繁体   English   中英

MVC控制器使用AutoFac进行通用注入

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM