(转)Asp.Net MVC 体验 4 Unity使用
原文地址:http://www.cnblogs.com/yuanhuaming/archive/2010/03/08/1680613.html
话说今天这篇文章才逐步开始涉及到mvc的功能。
暂时用代码的方式实现的,对比分析下2种IOC方式我觉得中大型项目还是使用配置文件比较好,
1.维护起来比代码方式方便。
2.不需要损耗额外编译时间。
3.不需要考虑项目之间的引用问题。
但不管使用哪种方法,配置文件尽可能的归类处理以提高可维护性。
我们来说一下,如何结合mvc使用吧
1.ioc在项目运行前期载入
在global.cs
protected void Application_Start()
{
IocBuilder.Build("");
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
Build()方法有个参数,传配置文件的路径的。现在没啥用。
看来下build()内部
public static void Build(string configPath)
{
string iKnowConnectionString = ConfigurationManager.ConnectionStrings["iKnow"].ConnectionString;
string northiwindConnectionString = ConfigurationManager.ConnectionStrings["northwind"].ConnectionString;
IUnityContainer container = new UnityContainer();
// 设置ControllerBuilder 默认controller工厂-> UnityControllerFactory
IControllerFactory controllerFactory =new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
container.RegisterType<IUnitOfWork, KnowDataContext>("iknow",
new UnityPerWebRequestLifetimeManager(),
new InjectionConstructor(new[] { iKnowConnectionString }))
.RegisterType<IUnitOfWork, NorthwindDataContext>("northwind",
new UnityPerWebRequestLifetimeManager(),
new InjectionConstructor(new[] { northiwindConnectionString }))
;
container.RegisterType<IRepository<Categories>, LinqRepository<Categories>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("northwind")));
container.RegisterType<CategoriesBiz>(new InjectionConstructor(new ResolvedParameter<IRepository<Categories>>()));
container.RegisterType<HomeController>(new InjectionConstructor(new ResolvedParameter<CatalogBiz>("catalogBiz")));
container.RegisterType<IRepository<Catalog>, LinqRepository<Catalog>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("iknow")));
container.RegisterType<CatalogBiz>(new InjectionConstructor(new ResolvedParameter<IRepository<Catalog>>()));
container.RegisterType<CatalogController>(new InjectionProperty("CatalogBiz"));
//about question
container.RegisterType<IRepository<Question>, LinqRepository<Question>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("iknow")));
container.RegisterType<QuestionBiz>(new InjectionConstructor(new ResolvedParameter<IRepository<Question>>()));
container.RegisterType<QuestionController>(new InjectionProperty("QuestionBiz"));
//about answer
container.RegisterType<IRepository<Answer>, LinqRepository<Answer>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("iknow")));
container.RegisterType<AnswerBiz>(new InjectionConstructor(new ResolvedParameter<IRepository<Answer>>()));
container.RegisterType<AnswerController>(new InjectionProperty("AnswerBiz"));
//
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
}
修改了controllerFactory的实现。就是说当系统要初始化controller的时候会去UnityControllerFactory.GetControllerInstance()中找配置在ioc容器里的controller。
UnityControllerFactory的实现:
public class UnityControllerFactory : DefaultControllerFactory
{
private readonly IUnityContainer container;
public UnityControllerFactory(IUnityContainer container)
{ //要做异常处理
this.container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
//这里把Controller实例注册到了unity容器
IController icontroller = container.Resolve(controllerType) as IController;
return icontroller;
}
}
我想说明一点为什么要使用ioc容器。为了解除具体依赖。那为什么要解除依赖呢?因为要面向接口开发。为什么要面向接口开发呢?其实就是为了应对修改程序对程序结构的破坏,所以要依赖于抽象,不依赖具体。
因此我们在面向接口开发的时候,请考虑编写的接口是否能够满足未来需求变更的时候保持相对得不变。(很难,但是很重要)。如果接口不断的变化,那抽象就变得没有意义了。那ioc更不重要了。