Injection de dépendance
Éviter les dépendances en permettant aux objets d'être transmis à l'entrepreneur de l'extérieur
J'écrirai en utilisant Interactor comme exemple dry-container et dry-auto_inject J'ai essayé DI en utilisant
not_di.rb
module Interactor
class FindUser
def initialize(params)
@params = params
end
def call
user_repo = UserRepository.new
user_repo.by_pk(@params[:id])
end
end
end
Vous pouvez voir que cela dépend de UserRepository
pure-di.rb
module Interactor
class FindUser
def initialize(params: {}, user_repo: UserRepository.new)
@params = params
@user_repo = user_repo
end
def call
@user_repo.by_pk(@params[:id])
end
end
end
Les arguments Initializd ont tendance à être énormes et difficiles à lire J'ai ceci
dry-di.rb
module Container
module FindUser
extend Dry::Container::Mixin
#Enregistrer l'objet à injecter
#Vous pouvez déclarer un objet par défaut avec block
register "params"
register "user_repo" do
UserRepository.new
end
end
end
module Interactor
class FindUser
Import = Dry::AutoInject(Container::FindUser)
#Vous pourrez appeler ce que vous incluez avec méthode
include Import["params", "user_repo"]
def call
user_repo.by_pk(params[:id])
end
end
end
Le code a augmenté, mais les perspectives se sont améliorées en séparant les responsabilités.
Parce que l'Interactor dépend du Container et que l'appelant (tel que Controller) dépend également du Container. J'ai pu bien inverser la dépendance
before: controller -> interactor after: controller -> container <- interactor
--Le code est rafraîchissant
En externalisant l'initialisation vers le conteneur, la responsabilité de l'interacteur a été réduite. Je veux réduire les responsabilités par classe
Le test d'interacteurs peut être effectué sans préparer la base de données
Dans l'exemple ci-dessus, vous pouvez passer un objet qui réagit à by_pk (id)
test.rb
User = Struct.new(:id, :name, :age)
class TestUserRepo
def by_pk(id)
User.new(id, "tarou", 20)
end
end
params = { id: 1 }
user_repo = TestUserRepo.new
input = { params: params, user_repo: user_repo }
Interactor::FindUser.new(input).call
Peut être fait comme
Recommended Posts