Abhängigkeitsspritze
Vermeiden Sie Abhängigkeiten, indem Sie Objekte von außen an den Auftragnehmer weitergeben
Ich werde am Beispiel von Interactor schreiben Trockencontainer und dry-auto_inject Ich habe DI mit versucht
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
Sie können sehen, dass es von UserRepository abhängt
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
Initialisierte Argumente sind in der Regel sehr umfangreich und schwer zu lesen ich habe das
dry-di.rb
module Container
module FindUser
extend Dry::Container::Mixin
#Registrieren Sie das zu injizierende Objekt
#Sie können ein Standardobjekt mit block deklarieren
register "params"
register "user_repo" do
UserRepository.new
end
end
end
module Interactor
class FindUser
Import = Dry::AutoInject(Container::FindUser)
#Sie können aufrufen, was Sie mit method einschließen
include Import["params", "user_repo"]
def call
user_repo.by_pk(params[:id])
end
end
end
Der Kodex hat zugenommen, aber die Aussichten haben sich durch die Trennung der Verantwortlichkeiten verbessert.
Weil der Interactor vom Container abhängt und der Aufrufer (z. B. Controller) auch vom Container abhängt. Ich konnte die Abhängigkeit gut umkehren
before: controller -> interactor after: controller -> container <- interactor
Durch das Auslagern der Initialisierung in den Container wurde die Verantwortung des Interaktors reduziert. Ich möchte die Verantwortlichkeiten pro Klasse reduzieren
Der Interaktortest kann ohne Vorbereitung der DB durchgeführt werden Im obigen Beispiel können Sie ein Objekt übergeben, das auf "by_pk (id)" reagiert
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
Kann wie gemacht werden
Recommended Posts