【问题标题】:MVC Controller Generic injection with AutoFac使用 AutoFac 的 MVC 控制器通用注入
【发布时间】:2011-06-10 23:42:52
【问题描述】:

我对使用 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 是 controller=Contractor,因此 GetController() 或 CreateController() 无法匹配 ContractorController,因此将 null 传递给GetControllerInstance() 表示 AutofacControllerFactory 不会尝试解析类型。

我认为我必须创建一个自定义控制器工厂 从 AutofacControllerFactory 派生,覆盖 GetController() 或 CreateController() 和 执行我自己的从控制器名称到泛型类型的映射。 像

if (controllerName == "Contractor") 返回 System.Type.GetType( “UI.Controllers。” +控制器名称+“控制器`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. 

所以我想我可能找错了树。 谁能告诉我如何在不拉动的情况下做到这一点 我的牙齿

谢谢

【问题讨论】:

    标签: c# generics model-view-controller controller autofac


    【解决方案1】:

    我不完全确定您为什么要使用泛型的控制器。 Mvc 并不真正支持在 Controller 上使用泛型 - 或者至少会涉及支持的路由路径。也许您可以提供有关该方法背后的推理的更多信息?

    看起来你想要一个支持对不同类型进行模型绑定的控制器。下一个问题是这些类型是否会因公共接口或基类而异。

    如果是这样,对于 Mvc2,请查看 the IocModelBinder information。这将与 Autofac 很好地配合使用。这将允许类型在 post 或 get 上绑定模型,从而允许您使用 autofac 注入服务。

    如果您想通过一个共同的基础来改变类型 - 支持各种具体的视图模型 - 然后查看the DerivedTypeModelBinder in MvcContrib。有一个适用于 Mvc 1、2 的版本,现在 MvcContrib for Mvc3 有一个很好的示例应用程序来配合它。 Mvc3 实现也更快 - 以前速度不是问题,它只是一个更有效的识别过程。

    【讨论】:

      【解决方案2】:

      也许这不是您问题的直接答案,但这是我见过和使用过的使用通用控制器的唯一可能方法:

      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> {
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多