一,什么是依赖注入(DI)
个人理解依赖注入(DI)就是控制反转(IOC)思想的一种实现方式,降低了代码之间的耦合,在应用程序运行中动态的向某个对象提供它所需要的对象。
二,依赖注入常用容器
常用的Spring.Net、Castle、Autofac等,下面主要说一下Castle、Autofac如何使用。
1.Autofac在MVC中的使用
Autofac在依赖注入框架中说是轻量级性能上非常高的,官网:https://autofac.org/.
首先我们要在项目中引用Autofac类库,我们需要两个类库,通过Nuget搜索autofac并安装,搜索autofac.MVC5并安装。安装好后就可以直接使用啦
少废话,直接贴代码:
在App_Start文件夹中创建AutoFacBoot类
public static void Register() { //创建容器 var builder = new ContainerBuilder(); //注册主控制器(所有控制器继承自BaseController) builder.RegisterControllers(typeof(BaseController).Assembly).PropertiesAutowired(); //注册Service 取类库中以Service结尾的类注册到容器中 var service = Assembly.Load("Lyr.CommonWebSit.Service"); builder.RegisterAssemblyTypes(service).Where(s => s.Name.EndsWith("Service")); //构建容器 var container = builder.Build(); //MVC注入 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }
在应用程序的Globle.asax文件中注册全局事件
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //依赖注入 AutoFacBoot.Register(); }
如果类库中类较少可以将类声明属性放到BaseController中,如较多建议放到子Controller中
这样就可以通过声明的对象直接使用类库中的方法啦,是不是很简单
2.Castle在MVC中的使用
Castle.Windsor也是可以试想依赖注入的框架,当然他还有实现其他功能的组件,这里只说一下他如何实现依赖注入。官网:http://www.castleproject.org/
同样,我们也需要在项目中安装他的两个类库,用Nuget如下图:
下载安装完成后,我们将逻辑单独放到一个CastleWindsor文件夹中,创建类WindsorControllerFactory并继承自DefaultControllerFactory默认MVC的Controller工厂类(可以看一下MVC声明周期与执行过程),并试想他的虚方法:
public class WindsorControllerFactory : DefaultControllerFactory { // Fields private readonly IWindsorContainer _container; // Methods public WindsorControllerFactory(IWindsorContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this._container = container; } protected override IController GetControllerInstance(RequestContext context, Type controllerType) { if (controllerType == null) { throw new HttpException(0x194, string.Format("The controller for path '{0}' could not be found or it does not implement IController.", context.HttpContext.Request.Path)); } return (IController)_container.Resolve(controllerType); } public override void ReleaseController(IController controller) { var disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } this._container.Release(controller); } }
在新建一个类ComponentRegistrar,用于实现依赖注入:
public class ComponentRegistrar { public static void AddComponentsTo(IWindsorContainer container) { AddCustomRepositoriesTo(container); AddAllControllerTo(container); //AddSessionHelperTo(container); } //注册类库 private static void AddCustomRepositoriesTo(IWindsorContainer container) { container.Register( Classes.FromAssemblyNamed("CommonWebSit.Service") .Where(type => type.Name.EndsWith("Service")) .WithService.DefaultInterfaces()); } //注册Controller private static void AddAllControllerTo(IWindsorContainer container) { container.Register(Classes.FromAssemblyNamed("Lyr.CommonWebSit.UI") .Where(typeof(IController).IsAssignableFrom) .If(c => c.Name.EndsWith("Controller")) .LifestyleTransient()); } //private static void AddSessionHelperTo(IWindsorContainer container) //{ // container.Register( // Component.For<SessionHelper>().LifeStyle.Transient); //} }
这样就可以啦
在全局文件Global.asax中注册一下
IWindsorContainer container = new WindsorContainer(); //设置Controller指定工厂类 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container)); ComponentRegistrar.AddComponentsTo(container);
使用同上,就不在重复啦