0

私はStevenSandersonとAdamFreemanによる「ASP.NetMVC3」をフォローしていますが、ある時点で彼らはを定義していますControllerFactory。公開されたインターフェースはコントローラーを作成するためのものであり、コントローラーに注入されるもの(データを提供するクラスなど)はブラックボックス(外界用)です。

私は、実際にはコントローラーを取得したくないのですが、コントローラーのバインディングセット、つまりデータを提供するクラスを取得したいと思っています。

コントローラファクトリに別のメソッドを追加することもできますが(のようにGetBinding)、それは機能しますが、それは正しい方法でしょうか?


何かに集中するためだけに。私にはIDataProvider2つのクラスがあります-MockupProviderProviderForReal。一度設定したいのですが、今のところ必要なときにいつでもIDataProvider取得できMockupProviderます。これは(私が)コントローラーファクトリーで設定します。

そして、私が設定したものを最もエレガントな方法で取得したいので、インターフェイスクラスを再度バインドすることはありません。そのようなメソッドを追加することはGetBinding、コントローラーファクターに良いパターンですか?

私はコントローラーを構築していません。バインディングコントローラーを使用する必要があります。


言い換えると...

コントローラ工場があります。内部にはいくつかのバインディングが定義されています。それらを取得する必要があります(コントローラーではなくバインディング)。技術的には、これをいくつかの方法で行うことができます。

  • コードを見て、特定のバインディングを見て、バインドされたタイプを別の場所で使用(ハードコーディング)します

  • コントローラファクトリにパブリックメソッドを追加しますGetBinding

  • ...?

正しい方法は何ですか?


アップデート

私のコントローラーファクトリー:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninject_kernel;

    public NinjectControllerFactory()
    {
        ninject_kernel = new StandardKernel();
        AddBindings();
    }

    private void AddBindings()
    {
        ninject_kernel.Bind<IBookRepository>().To<DataManagement.Concrete.EFBookRepository>();
        // ninject_kernel.Bind<IBookRepository>().ToConstant(DataManagement.Mocks.Mocks.BookRepository);
    }

    public T GetBinding<T>()
    {
        return ninject_kernel.Get<T>();
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;
        else
            return (IController)ninject_kernel.Get(controllerType);
    }
}
4

1 に答える 1

1

コメントに続いて、あなたの質問に答えようとしています。あなたにふさわしくない場合は、削除する用意があります。

したがって、私の ASP.NET MVC アプリケーションでは、ninject とその mvc 拡張機能を使用して、コントローラー (および基になるサービスとリポジトリ) に依存関係を注入しています。

Global.asax

public class MvcApplication : Ninject.Web.Mvc.NinjectHttpApplication
{
        /// this is here only to see that NinjectHttpApplication uses its own ControllerFactory, which is supposed to create your controllers with dependencies injected
        protected override Ninject.Web.Mvc.NinjectControllerFactory CreateControllerFactory()
        {
            return base.CreateControllerFactory();
        }

        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            // here you can configure your bindings according to actual requirements 
            kernel.Bind<IDataProvider>().To<ProviderForReal>().InRequestScope(); 
            kernel.Bind<IDataService>().To<RealDataService().InRequestScope();                
            return kernel;
        }
}

コントローラ

public class MyController : Controller
{
    private readonly IDataProvider dataService;
    // i will get injected an IDataProvider according to my actual configuration
    public MyController(IDataService dataService)
    {
          this.dataService = dataService;
    }
}

IDataService

public class RealDataService: IDataService{
     private readonly IDataProvider dataProvider;
     public RealDataService(IDataProvider dataProvider){
         this.dataProvider = dataProvider;
     } 
}

アップデート

独自のコントローラー ファクトリを作成する必要はありません。上記のコードでは、このメソッドを暗黙的にオーバーライドし、依存関係を解決する独自の実装を使用するCreateControllerFactoryことを示すためだけにメソッドのオーバーライドを入れています (たとえその依存関係が間接的であっても - 私の更新されたコードでわかるように => Ninject はそれを解決する必要があることを確認し、バインディングを調べて、 へのバインディングがあることを確認しますが、に依存するコンストラクターしかありません。createに注入し、RealDataService よりも)。 Ninject.Web.Mvc.NinjectHttpApplicationNinjectControllerFactoryMyControllerIDataServiceRealDataServiceIDataProviderIDataProviderProviderForRealProviderForRealReadDataServiceMyController

于 2012-11-16T23:55:41.143 に答える