依存関係は、コンストラクターで静的コンテナーまたはシングルトン コンテナーを使用するのではなく、最上位層のクラスから順にカスケードで解決する必要があります。
このリンクを確認してください。
アプリが依存関係を解決するためのパイプラインへのフックを (コントローラーの場合と同様に) 提供しない場合Unity.Mvc3
、最良のアプローチは、Manager
Unity を介して (トップ レイヤー クラス) クラスを解決し (最初に登録する必要があります)、DI コンテナーにIRepository
. これにより、静的/シングルトン コンテナーを 1 か所に保持し、制御下に置くことができます。アプリ内の他のレイヤーは、DI コンテナーについて何も認識してはなりません。
完全な依存関係グラフを解決する例は、次のコードです。
Public Class ClasificationManagement //application layer service, top layer class
Implements IClasificationManagement
Private _servicio As IClasificacionesService //inject domain serice for bussines
Private _repositorio As IClasificationRepository //inject repository for perisitence
Public Sub New(ByVal servicio As IClasificacionesService, ByVal repositorio As IClasificationRepository)
_servicio = servicio
_repositorio = repositorio
End Sub
Public sub SwapDescrition(ByVal clasificationOrigenID As String, ByVal clasificationDestinoID As String) Implements IClasificationManagement. SwapDescrition
//code using domain services and repositories
End sub
Public class ClasificacionesService
implements IClasificacionesService
private _tracer as ITracer //inject tracer to service domain
public sub new(tracer as ITracer)
_tracer = tracer
end sub
//not relevant code using ITracer
End Class
XML またはランタイムでの Unity の適切な構成により、ClasificationManagement を解決するだけで済み、Unity はすべての依存チェーンを解決するという汚い作業を行います。
//resolve manager
manager = ServiceLocator.Current.GetInstance(Of IClasificationManager)()
//use manager, all dependencies (bussines service, repositories, tracers) were injected by Unity
manager.SwapDescrition("123-ABC", "456-DEF")
Unity 構成の場合、依存関係を変更でき、コンパイルが不要なため、xml 構成が好きです。アプリの初期化ロジックのどこかにこの関数を含めるだけです。
Imports Microsoft.Practices.Unity
Imports Microsoft.Practices.Unity.Configuration
Imports Microsoft.Practices.ServiceLocation
Private Sub InitServiceLocator()
Dim container As IUnityContainer = New UnityContainer()
container.LoadConfiguration() //read xml config
//container.RegisterType<Of ...>(...) //config in runtime
Dim provider = New UnityServiceLocator(container)
ServiceLocator.SetLocatorProvider(Function() provider)
End Sub
XML 構成は次のようになります。
<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IClasificationManagement" type="AppPrincipal.IClasificationManagement, AppPrincipal" />
<alias alias="IClasificationRepository" type="X509ValDAL.IClasificationRepository, X509ValDAL" />
<alias alias="IClasificacionesService" type="Entidades.IClasificacionesService, Entidades" />
<alias alias="IUnitOfWork" type="X509ValDAL.IUnitOfWork, X509ValDAL" />
<alias alias="ObjectContext" type="System.Data.Objects.ObjectContext, System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<alias alias="ClasificationManagement" type="AppPrincipal.ClasificationManagement, AppPrincipal" />
<alias alias="ClasificationRepository" type="X509ValDAL.ClasificationRepository, X509ValDAL" />
<alias alias="ClasificacionesService" type="Entidades.ClasificacionesService, Entidades" />
<alias alias="UnitOfWork" type="X509ValDAL.UnitOfWork, X509ValDAL" />
<alias alias="X509VALEntities" type="Entidades.X509VALEntities, Entidades" />
<assembly name="AppPrincipal" />
<assembly name="X509ValDAL" />
<assembly name="Entidades" />
<assembly name="System.Data.Entity" />
<namespace name="AppPrincipal" />
<namespace name="X509ValDAL" />
<namespace name="Entidades" />
<namespace name="System.Data.Objects" />
<container>
<register type="IClasificationManagement" mapTo="ClasificationManagement">
<constructor>
<param name="servicio">
<dependency/>
</param>
<param name="repositorio">
<dependency/>
</param>
</constructor>
</register>
<register type="IClasificationRepository" mapTo="ClasificationRepository">
<constructor>
<param name="uow">
<dependency/>
</param>
</constructor>
</register>
<register type="IClasificacionesService" mapTo="ClasificacionesService" />
TODO: Inject ITracer
<register type="ObjectContext" mapTo="X509VALEntities" />
<register type="IUnitOfWork" mapTo="UnitOfWork" >
<constructor>
<param name="context">
<dependency />
</param>
</constructor>
</register>
</container>
</unity>
この例が、DI の哲学を理解するのに役立つことを願っています。静的コンテナー (ServiceLocator) を使用する場合でも。コンテナーは、サービスロケーターのアンチパターンを回避するために最上位のレイヤー クラスをロードするためだけに使用されます。