0

我正在关注 Steven Sanderson 和 Adam Freeman 的“ASP.Net MVC 3”,他们曾一度定义ControllerFactory. 暴露的接口用于创建控制器,注入其中的(如提供数据的类)是黑盒(用于外部世界)。

我在这一点上,我真的不想获得任何控制器,而是控制器的绑定集——即提供数据的类。

我可以为控制器工厂添加另一种方法(如GetBinding),它会起作用,但这是正确的方法吗?


只是为了专注于某事。我有IDataProvider两个课程——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 扩展将依赖项注入到我的控制器(以及底层服务和存储库)。

全球.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;
    }
}

数据服务

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

更新

您不需要编写自己的控制器工厂。在上面的代码中,我将我的CreateControllerFactory方法覆盖只是为了显示Ninject.Web.Mvc.NinjectHttpApplication隐式覆盖此方法并使用它自己的NinjectControllerFactory实现来为您解决依赖关系(即使该依赖关系是间接的 - 正如您在我更新的代码中看到的那样 => Ninject 将为您解决它,因为它会看到MyController需要IDataService并会查看绑定并将看到绑定到RealDataService,但它只有依赖于的构造函数IDataProvider。所以它会再次查看绑定并且会看到IDataProvider绑定到ProviderForReal而不是创建ProviderForReal将其注入到ReadDataServiceRealDataService 到MyController)。

于 2012-11-16T23:55:41.143 回答