[英]MVC Controller Generic injection with AutoFac
我对使用Autofac的DI相当新,并想知道以下是否可行
我想创建一个接收注入类型的通用控制器和动作。 我不想要一个注入类型的实例,但只需要它的类型,这将是一个预期接口的实现。
我也想把这个泛型类型传递给ViewModel,但这完全是另一个主题,但是如果有一些天才可以解决这两个问题,那将是非常好的。
public ContractorController<T> : Controller
where T : IContractor{
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
应通过http://mysite.com/Contractor/New
调用此控制器
我一直在寻找使用AutoFac注册泛型,但似乎问题是AutofacControllerFactory只实现了GetControllerInstance(),期望从GetController()或CreateController()传递给它的控制器类型,不确定哪个或哪个不同在他们之间。 这些方法从RoutData接收控制器的名称作为字符串,并返回相应的.NET类型,给出URL, http://mysite.com/Contractor/New
://mysite.com/Contractor/New是controller = Contractor,因此ContractorController不能与GetController()匹配或CreateController()和therfore将null传递给GetControllerInstance(),这意味着AutofacControllerFactory不会尝试解析该类型。
我想我必须创建一个派生自AutofacControllerFactory的自定义Controller Factory,重写GetController()或CreateController()并执行我自己的映射,从控制器名称到泛型类型。 就像是
if(controllerName ==“Contractor”)返回System.Type.GetType(“UI.Controllers。”+ controllerName +“Controller`1”);
当我调试这个时,我可以看到这个代码正在找到通用控制器并返回它。
我想我可以只注册类似的类型
builder.RegisterType<FakeContractor>().As<IContractor>();
builder.RegisterGeneric(typeof(ContractorController<>));
但是我收到以下错误
The Autofac service
'UI.Controllers.ContractorController`1'
representing controller
'ContractorManagement.UI.Controllers.ContractorController`1'
in path '/Contractor/New' has not been registered.
所以我想我可能正在咆哮错误的树。 任何人都可以在没有拔牙的情况下阐明如何做到这一点
谢谢
我不完全确定你为什么要使用通用的控制器。 在Mvc中实际上不支持在Controller上使用通用 - 或者至少涉及支持路由路径。 也许您可以提供有关该方法背后原因的更多信息?
它看起来像是你想要一个支持不同类型的模型绑定的控制器。 接下来的问题是这些类型是否在公共接口或基类之间有所不同。
如果是这种情况,对于Mvc2,请查看IocModelBinder信息 。 这将非常适合Autofac。 这将允许类型在post或get上进行模型绑定,允许您使用autofac注入服务。
如果您想通过一个共同的基础来改变类型 - 支持各种具体的视图模型 - 那么请查看MvcContrib中的DerivedTypeModelBinder 。 有一个版本适用于Mvc 1,2,现在MvcContrib for Mvc3有一个很好的示例应用程序。 Mvc3实现也更快 - 速度以前不是问题,它只是一个更有效的识别过程。
也许这不是你问题的直接答案,但这是使用我见过和使用的通用控制器的唯一可行方法:
public abstract class ContractorControllerBase<T> : Controller where T : IContractor {
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
public class FakeContractorController : ContractorControllerBase<FakeContractor> {
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.