在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们但凡需求在Controller激活系统中引进IoC,用于处置用户请求的 Controller,让Controller依托于ModelRepository的笼统而不是它的完成。
我们能够在三个阶段应用IoC完成下面所说的解耦支配,起首需求俭朴先容一下默许环境下Controller的激活进程:
1、用户发送请求黑ASP.NET,路由系统对请求中止解析,依照注册的路由规律对请求中止婚配,解析出Controller和Action的称号等信息。
2、将解析出的信息交给一个MvcRouteHandler对象中止处置,MvcHttpHandler中存在以个ControllerFactory成员,若是机关函数中没有供应一个完成IControllerFactory接口的对象,则默许机关函数经由过程挪用ControllerBuilder.Current.GetControllerFactory()取得一个多么的对象。
3、系统挪用上文对象中德GetHttpHandler获得了一个完成了IHttpHandler接口的MvcHandler对象究竟处置请求。
4、在 MvcHandler中挪用BeginProcessRequest方式连续处置请求,方式中从1中解析的信息中获得Controller和Action 的信息,此后支配2种的IControllerFactory对象激活Controller对象,并究竟实行响应的Action。
第一种方式
由上文2种可知,我们能够树立自身的IControllerFactory对象完成依托注进,但是我们能够经由过程直接担当 DefaultControllerFactory侧重写GetControllerInstance方式来完成,多么能够防止往从头完成其他一些功用的任务。
以下是应用Unity树立的担当自DefaultControllerFactory的UnityControllerFactory的俭朴示例:
namespace UnitySample
{
public class UnityControllerFactory:DefaultControllerFactory
{
private IUnityContainer container;
public UnityControllerFactory(IUnityContainer container)
{
this.container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return null == controllerType ? null : (IController)this.container.Resolve(controllerType);
//return base.GetControllerInstance(requestContext, controllerType);
}
}
}
我们能够在App_Start中应用ControllerBuilder设置系统应用这个ControllerFactory
IUnityContainer container = new UnityContainer();
container.RegisterType();
UnityControllerFactory factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);
第二种方式
上文中担当的DefaultControllerFactory中,应用一个ControllerActivator的成员来完成对 Controller的激活,若是树立对象中没有供应一个IControllerActivator对象,则供应一个默许完成了 IControllerActivator的DefaultControllerActivator对象这个类型,这个接口中存在用于树立 Controller对象的Create方式,在DefaultControllerFactory中有存在一个 IControllerActivator类型的机关方式来拟定它。所以我们可运用一个自界说的完成自IControllerActivator捏词的对象来中止依托注进。
namespace UnitySample
{
public class UnityControllerActivator:IControllerActivator
{
private IUnityContainer container;
public UnityControllerActivator(IUnityContainer container)
{
this.container = container;
}
public IController Create(RequestContext requestContext, Type controllerType)
{
return controllerType == null ? null : (IController)container.RegisterType(controllerType);
}
}
}
点窜方式1中在App_Start中的代码,应用这个ControllerActivator:
IUnityContainer container = new UnityContainer();
container.RegisterType();
//UnityControllerFactory factory = new UnityControllerFactory(container);
IControllerActivator controllerActivator = new UnityControllerActivator(container);
DefaultControllerFactory defaultFactory = new DefaultControllerFactory(controllerActivator);
ControllerBuilder.Current.SetControllerFactory(defaultFactory);
第三种方式
犹如DefaultControllerFactory类中一样,在DefaultControllerActivator中也存在一个包括一个参数(类型为IDependencyResolver)的机关方式和一个没有参数的机关方式,默许环境下DefaultControlerFactory应用无参机关函数实例化一个DefaultControllerActivator对象,这类环境下供应一个默许的IDependencyResolver 对象。所以我们就一样可运用一个自界说的IDependencyResolver类完成依托注进。在IDependencyResolver接口中存在方式GetService和GetServices来对细致的类型中止解析
namespace UnitySample
{
public class UnityDependencyResolver:IDependencyResolver
{
private IUnityContainer container;
public UnityDependencyResolver(IUnityContainer container)
{
this.container = container;
}
public object GetService(Type serviceType)
{
return container.Resolve(serviceType);
}
public IEnumerable object GetServices(Type serviceType)
{
return container.ResolveAll(serviceType);
}
}
}
点窜App_Strat中的方式,应用这个自界说的DependencyResolver:
IUnityContainer container=new UnityContainer();
container.Register Type IXXXRepository,XXXRepository
UnityDependencyResolver resolver=new UnityDependencyResolver(container);
DependencyResolver.SetResolver(resolver)