1

私は CQRS を実装している MVC アプリケーションを使用しており、データの保存と別のインターフェイスへのデータの読み取りを分離しています。これらのインターフェイスの具体的なインスタンスをコントローラーに注入するために、コンストラクター注入を使用しています。コンストラクター インジェクションには、Unity コンテナーを使用しています。以下の例を参照してください

//The Employee controller 
public class EmployeeController : Controller
{
    IEmployeeRepository _Writer;

    IEmployeeQuery _Reader;

    //constructor injection
    public EmployeeController(IEmployeeRepository writer, IEmployeeQuery reader)
    {
        this._Writer = writer;
   this._Reader = reader;   

    }


    //To Do: constructor injection for write operations only
    public EmployeeController(IEmployeeRepository writer)
    {
        this._Writer = writer;

    }

    //To Do: constructor injection for read operations only
    public EmployeeController(IEmployeeQuery reader)
    {
        this._Reader = reader;

    }
}


//Registration of the concrete types in the unity container.
public static class Bootstrapper
{
    public static void ConfigureUnityContainer()
    {
        IUnityContainer container = new UnityContainer();

        container.RegisterType<IEmployeeRepository, EmployeeRepository>(new HttpContextLifetimeManager<IEmployeeRepository>());
        container.RegisterType<IEmployeeQuery, EmployeeQueries>(new HttpContextLifetimeManager<IEmployeeQuery>());
        ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
    }
}

//The derived Controller Factory for injection dependencies in the Controller constructor
public class UnityControllerFactory : DefaultControllerFactory
{
    IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container)
    {
        this.container = container;
    }
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {


        try
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException("controllerType");
            }

            if (!typeof(IController).IsAssignableFrom(controllerType))
            {
                throw new ArgumentException(String.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
            }

            return container.Resolve(controllerType) as IController;





        }
        catch (Exception)
        {

            return null;
        }
    }
}

どのアクションでも、データをフェッチするか、データを書き込むかのいずれかであり、両方ではないことがわかりました。その場合、「_Writer」または「_Reader」のどちらを初期化する必要があるかに応じて、コントローラー コンストラクターを条件付きで呼び出す必要があります。

これはどのように行うことができますか?

4

2 に答える 2

1

2 つを使用する必要があるコントローラーが 1 つあるように見えますか? 読み取りと書き込みの両方を行う必要がない場合は、そのコンポーネントを単一の責任にリファクタリングすることを検討します。

それをしたくない場合は、その依存関係をまったく注入しないのではなく、NullObject を注入することを検討します。このスレッドを参照してください。

TecXプロジェクトには、NInject のコンテキスト バインディングを模倣する拡張機能が含まれています。これにより、いつどの依存関係を注入するかを指定できます。このコードは、TecX.Unityプロジェクト (フォルダーContextualBinding ) 内にあります。その使用方法を示すテストは、TecX.Unity.ContextualBinding.Testプロジェクト内にあります)。

于 2012-07-16T11:54:05.793 に答える
1

遅延読み込みコンポーネントについてはどうですか? 両方の依存関係を解決しますが、実際に使用される 1 つだけが初期化されます。

サンプルはこちら: http://pwlodek.blogspot.com/2010/05/lazy-and-ienumerable-support-comes-to.html

于 2012-07-25T10:29:19.570 に答える