我已经创建了一个配置了Unity MVC和Unity Web API的C#ASP项目。
我不想在依赖于它们的对象中定义依赖项的名称 - 我试图将该配置与其他容器配置保持一致。
但是我很难确定如何使用控制器来做到这一点?我的控制器看起来像:
namespace MyService.Controllers
{
public class HomeController : Controller
{
private ITest test;
public HomeController(ITest test)
{
this.test = test;
}
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
}
}
我目前对容器配置的尝试如下:
container.RegisterType<ITest>("bar",
new InjectionFactory(c => new TestImpl1()));
container.RegisterType<ITest>("foo",
new InjectionFactory(c => new TestImpl2()));
container.RegisterType<HomeController>("Home",
new InjectionFactory(c => new HomeController(
c.Resolve<ITest>("foo")
)));
但我最终得到了这个例外:
The current type, MyService.App_Start.ITest, is an interface and cannot be constructed. Are you missing a type mapping?
这对我来说意味着它没有使用容器来获取已注册的HomeController。我不确定如何正确连线?
解决方案
根据接受的答案,对我有用的确切解决方案是注册该控制器工厂;
public class UnityControllerFactory : DefaultControllerFactory
{
private readonly IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, null);
}
return _container.Resolve(controllerType) as IController;
}
}
使用Start()实际注册它,当然:
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
答案 0 :(得分:2)
MVC中的控制器由控制器工厂创建。如果你想使用依赖注入,你必须挂钩到这个控制器工厂并使你的覆盖使用统一。
public class MgsMvcControllerFactory : DefaultControllerFactory {
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
// our controller instance will have dependency injection working
if (!ServiceLocator.IoC.IsServiceRegistered(controllerType, controllerType.FullName)) {
ServiceLocator.IoC.RegisterType(controllerType, controllerType.FullName, new ContainerControlledLifetimeManager())
}
return ServiceLocator.IoC.Resolve<IController>(controllerType.FullName);
}
}
在global.asax.cs中:
protected void Application_Start() {
// initialization of unity container
ServiceLocator.IoC = ...;
var factory = new MgsMvcControllerFactory()
ControllerBuilder.Current.SetControllerFactory(factory);
}
备选(不那么酷的恕我直言)是基础Controller
的创建 - 我们称之为DIController
,它将在构造函数中调用BuildUp()
并从此{{1}继承其余控制器}。毋庸置疑,您必须将基于构造函数的注入重写为基于方法或属性的注入。