我正在关注史蒂文桑德森和亚当弗里曼的“ASP.Net MVC 3”,他们一度定义ControllerFactory
。暴露的接口用于创建控制器,注入它们的内容(如提供数据的类)是黑盒子(用于外部世界)。
我就是这样,我真的不想得到任何控制器,而是控制器的绑定集 - 即提供数据的类。
我可以为控制器工厂添加另一种方法(例如GetBinding
)并且它可以工作,但它是正确的方式吗?
专注于某事。我有IDataProvider
和两个班级 - MockupProvider
和ProviderForReal
。我想设置一次,现在只要我需要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);
}
}
答案 0 :(得分: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.Web.Mvc.NinjectHttpApplication
隐式覆盖此方法并使用其自己的NinjectControllerFactory
implmentation,它将为您解析依赖项(即使该依赖项是间接的 - 你可以在我更新的代码中看到=&gt; Ninject会为你解决它,因为它会看到MyController
需要IDataService
并且会查看绑定并且会看到绑定到{ {1}},但它只有依赖于RealDataService
的构造函数。所以它会再次查看绑定,并且会看到IDataProvider
绑定到IDataProvider
而不是创建ProviderForReal
将它注入ProviderForReal
而不是RealDataService注入ReadDataService
)。