Asp.net MVC中如何实现依赖注入(DI)(一)

一,什么是依赖注入(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));
        }            
View Code

在应用程序的Globle.asax文件中注册全局事件

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //依赖注入
            AutoFacBoot.Register();
        }
View Code

如果类库中类较少可以将类声明属性放到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);
        }
    }
View Code

在新建一个类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);

        //}
    }
View Code

这样就可以啦

在全局文件Global.asax中注册一下

IWindsorContainer container = new WindsorContainer();
            //设置Controller指定工厂类
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
            ComponentRegistrar.AddComponentsTo(container);
View Code

使用同上,就不在重复啦

原文地址:https://www.cnblogs.com/MrLiu90/p/9877310.html