• asp.net mvc Autofac 配置使用纪要


     在此使用扫描的方式RegisterAssemblyTypes

    注入注册有多种,在此只做常用的 控制器  服务  和Global.asax 

    项目例子可以参考:https://github.com/nicholaspei/MvcApplication5

    如果服务 和控制器是在一个项目中Global.asax.cs是这么配置的

      public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                //   DependencyResolverConfig.Register();
    
                var builder = RegisterService();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);   
            }
    
            private ContainerBuilder RegisterService()
            {
                var builder = new ContainerBuilder();
    
                var baseType = typeof(IService);
                var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
                var AllServices = assemblys
                    .SelectMany(s => s.GetTypes())
                    .Where(p => baseType.IsAssignableFrom(p) && p != baseType);
    
                builder.RegisterControllers(assemblys.ToArray());
    
                builder.RegisterAssemblyTypes(assemblys.ToArray())
                       .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                       .AsImplementedInterfaces().InstancePerLifetimeScope();
                return builder;
            }

    IService

      public interface IService
        {
        }

    ITestService

     public interface ITestService : IService
        {
             string Show();
           /* {
                return "你好啊";
            }*/
        }

    实现

     public class TestService : ITestService
        {
            public string Show()
            {
                return "你好啊";
            }
        }
     public class HomeController : Controller
        {
            private readonly ITestService TestService;
           
    
          public HomeController(ITestService carmodel)
            {
                TestService = carmodel;
              
            }
    
    
        //    ITestService TestService { get; set; } 
            public ActionResult Index()
            {
            System.Diagnostics.Trace.WriteLine(TestService.Show());
                return View();
            }

    以上就是service 和controller 在一个项目中的配置方式  controller中必须 在构造函数中注册注入

    而还有一种简单的写法跟java 一样

    ITestService TestService { get; set; }
    就这么一句话
    使用场景是iserver 和serverce 接口和实现 和控制器不在一个项目中, 我因为这一句话无法使用,提示了良久才发现这种写法存在问题
    下边说说这种方式的配置

     Global.asax.cs

      protected void Application_Start()
            {
                RemoveWebFormEngines();
    
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                //创建autofac管理注册类的容器实例
                var builder = new ContainerBuilder();
                SetupResolveRules(builder);
                //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册 支持属性注入
                builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
    
                // 把容器装入到微软默认的依赖注入容器中
                var container = builder.Build();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            }
    
            private static void SetupResolveRules(ContainerBuilder builder)
            {
                //WebAPI只用引用services和repository的接口,不用引用实现的dll。
                //如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll
                var iServices = Assembly.Load("FineAdmin.IService");
                var services = Assembly.Load("FineAdmin.Service");
                var iRepository = Assembly.Load("FineAdmin.IRepository");
                var repository = Assembly.Load("FineAdmin.Repository");
    
                //根据名称约定(服务层的接口和实现均以Services结尾),实现服务接口和服务实现的依赖
                builder.RegisterAssemblyTypes(iServices, services)
                  .Where(t => t.Name.EndsWith("Service"))
                  .AsImplementedInterfaces().PropertiesAutowired();
    
                //根据名称约定(数据访问层的接口和实现均以Repository结尾),实现数据访问接口和数据访问实现的依赖
                builder.RegisterAssemblyTypes(iRepository, repository)
                  .Where(t => t.Name.EndsWith("Repository"))
                  .AsImplementedInterfaces().PropertiesAutowired();
            }

    服务 和接口服务  iservice  都一样

    控制器端 举例

    public IUserService UserService { get; set; }
            public ILogonLogService LogonLogService { get; set; }

    一下有各种的注册写法

      // Register services 1
                /*            var result = builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
                                   .Where(x =>typeof(IService).IsAssignableFrom(x))
                                   .AsImplementedInterfaces()
                                   .InstancePerRequest();
                */
    
    
                /* 2 var result = builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                   .Where(x => typeof(IService).IsAssignableFrom(x))
                   .AsImplementedInterfaces()
                   .InstancePerRequest();*/
             /*   3 */var result = builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                   .Where(t => t.Name.EndsWith("IService"))
                   .AsImplementedInterfaces()
                   .InstancePerRequest();
    
                //  var builder = new ContainerBuilder();
    
                /* 4  var baseType = typeof(IService);
                   var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
                   var AllServices = assemblys
                       .SelectMany(s => s.GetTypes())
                       .Where(p => baseType.IsAssignableFrom(p) && p != baseType);
    
                   builder.RegisterControllers(assemblys.ToArray());
    
                   builder.RegisterAssemblyTypes(assemblys.ToArray())
                          .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                          .AsImplementedInterfaces().InstancePerLifetimeScope();
                //   return builder;
                   DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));*/

     了解了这些似乎配置复杂一点的还是出现各种问题,比如泛型接口

    通过一步步的抓包加深了解

     这是那个测试项目

     

     这条代码应该是获取当前项目使用的所有程序集转list

    在此是只为当前项目名的程序集,下边可以看到红框内当前项目名在里边

    接下来查找程序集里边IService类

     

     这句在此没有什么实际用处

    而此句

     是注册控制器内的构造函数的相关的, 注册所有控制类还有一种写法 省一行代码

    // 注册所有的Controller
    // builder.RegisterControllers(Assembly.GetExecutingAssembly());

     如果没有那句,

    isAssignableFrom()方法是判断是否为某个类的父类

     限于没深入研究更为复杂的 接口加抽象类 类似以下 的结构的注入配置,决定放弃 service 和 controller Repositories 在同一项目的情况, 如果想用注入最好是三者分开项目,真是方便配置autofac

     总结就是autofac 如果小项目就不要用了, new 来new去也不错啊, 一旦用了这那玩意 ,还要配置总接口,有些还有接口下再加具体接口,接口 加上后,显得代码也够臃肿,改了一个地方,考虑接口里也得加上,

    再说有些人说省new 省资源, 这一点从线程角度,个人理解, 每次请求iis会生成一个线程的,关于线程大家都知道,会把对象,函数之类的组到一个单独的堆里.从这一点理解上来看,并没有省新建对象的啊..

    个人理解,有机会再深入了解一下请求线程是如何使用资源的.

    留下调试过程中的配置方法各种

    using Autofac;
    using Autofac.Integration.Mvc;
    using RegisterAssemblyDemo.Services;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    using System.Web.Compilation;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    
    namespace RegisterAssemblyDemo
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            /*  protected void Application_Start()
              {
                  AreaRegistration.RegisterAllAreas();
                  //   DependencyResolverConfig.Register();
    
                  var builder = RegisterService3();//RegisterService();
                  var container = builder.Build();
                  using (var scope = container.BeginLifetimeScope())
                  {
                      var service = scope.Resolve<IService>();
    
                      // If IService is registered, it will be resolved; if
                      // it isn't registered, the return value will be null.
                      var servic = scope.ResolveOptional<IService>();
                      ITestService provider;
                      if (scope.TryResolve<ITestService>(out provider))
                      {
                          provider.Show();
                          // Do something with the resolved provider value.
                      }
                  }
                  DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
                  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                  RouteConfig.RegisterRoutes(RouteTable.Routes);
                  BundleConfig.RegisterBundles(BundleTable.Bundles);
              }
            */
            protected void Application_Start()
            {
                RemoveWebFormEngines();
    
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                //创建autofac管理注册类的容器实例
                var builder = new ContainerBuilder();
                SetupResolveRules(builder);
                //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册 支持属性注入
                builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
    
                // 把容器装入到微软默认的依赖注入容器中
                var container = builder.Build();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            }
    
            private static void SetupResolveRules(ContainerBuilder builder)
            {
                //WebAPI只用引用services和repository的接口,不用引用实现的dll。
                //如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll
                var iServices = Assembly.Load("FineAdmin.IService");
                var services = Assembly.Load("FineAdmin.Service");
                var iRepository = Assembly.Load("FineAdmin.IRepository");
                var repository = Assembly.Load("FineAdmin.Repository");
    
                //根据名称约定(服务层的接口和实现均以Services结尾),实现服务接口和服务实现的依赖
                builder.RegisterAssemblyTypes(iServices, services)
                  .Where(t => t.Name.EndsWith("Service"))
                  .AsImplementedInterfaces().PropertiesAutowired();
    
                //根据名称约定(数据访问层的接口和实现均以Repository结尾),实现数据访问接口和数据访问实现的依赖
                builder.RegisterAssemblyTypes(iRepository, repository)
                  .Where(t => t.Name.EndsWith("Repository"))
                  .AsImplementedInterfaces().PropertiesAutowired();
            }
    
    
            private void RegisterService2()
            {
                var builder = new ContainerBuilder();
                // Register 方式指定具体类
         /*       builder.Register(c => new InjectionTestService()).As<IService>().InstancePerDependency();
    
            // RegisterType 方式指定具体类
            builder.RegisterType<InjectionTestService>().As<IService>().InstancePerDependency();*/
    
            // 自动注册的方式
    
            // 获取包含继承了IService接口类的程序集
            var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>()
                .Where(
                    assembly =>
                        assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=
                        null
                );
    
            // RegisterAssemblyTypes 注册程序集
            var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();
                if (enumerable.Any())
                {
                    builder.RegisterAssemblyTypes(enumerable)
                        .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency();
                 }
      
          }
            private ContainerBuilder RegisterService3()
            {
                var builder = new ContainerBuilder();
                builder.RegisterControllers(typeof(MvcApplication).Assembly);
    
                // 自动注册的方式
    
                // 获取包含继承了IService接口类的程序集
                var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>()
                    .Where(
                        assembly =>
                            assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=
                            null
                    );
    
                // RegisterAssemblyTypes 注册程序集
                var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();
                if (enumerable.Any())
                {
                    builder.RegisterAssemblyTypes(enumerable)
                        .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency();
                }
                // 获取包含继承了IService接口类的程序集
                var assemblies2 = BuildManager.GetReferencedAssemblies().Cast<Assembly>()
                    .Where(
                        assembly =>
                            assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IBaseService<>))) !=
                            null
                    );
    
                // RegisterAssemblyTypes 注册程序集
                var enumerable2 = assemblies2 as Assembly[] ?? assemblies2.ToArray();
                if (enumerable2.Any())
                {
                    builder.RegisterAssemblyTypes(enumerable2)
                        .Where(type => type.GetInterfaces().Contains(typeof(IBaseService<>))).AsImplementedInterfaces().InstancePerDependency();
                }
    
    
    
    
    
    
                return builder;
            }
            private ContainerBuilder RegisterService4()
            {
                var builder = new ContainerBuilder();
                builder.RegisterControllers(typeof(MvcApplication).Assembly);
                var res = builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
                               .Where(x => x.IsClass && !x.IsAbstract && typeof(IService).IsAssignableFrom(x))
                               .AsImplementedInterfaces()
                               .InstancePerRequest();
    
                return builder;
            }
    
    
            private ContainerBuilder RegisterService()
            {
                var builder = new ContainerBuilder();
    
                // 注册所有的Controller
            //    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    
                var baseType = typeof(IService);
                var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
                /*     var AllServices = assemblys
                         .SelectMany(s => s.GetTypes())
                         .Where(p => baseType.IsAssignableFrom(p) && p != baseType); */
    
                 builder.RegisterControllers(assemblys.ToArray());
    
                builder.RegisterAssemblyTypes(assemblys.ToArray())
                       .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                       .AsImplementedInterfaces().InstancePerLifetimeScope();
                return builder;
            }
            /// <summary>
            /// 移除webform试图引擎
            /// </summary>
            void RemoveWebFormEngines()
            {
                var viewEngines = ViewEngines.Engines;
                var webFormEngines = viewEngines.OfType<WebFormViewEngine>().FirstOrDefault();
                if (webFormEngines != null)
                {
                    viewEngines.Remove(webFormEngines);
                }
            }
        }
    }



  • 相关阅读:
    【ASP.NET 进阶】根据IP地址返回对应位置信息
    【网络文摘】编程的智慧
    【ASP.NET 类库】当你懒得用 Json+Ajax 时,可以试试 AjaxPro
    【iOS 初见】第一个简单的 iOS 应用
    【C#】C# 实现发送手机短信
    【网络文摘】一家公司要了你后,凭什么给你开高工资?
    深入理解Java虚拟机01--概述
    Java虚拟机(五)Java的四种引用级别
    OkHttp3源码详解(六) Okhttp任务队列工作原理
    OkHttp3源码详解(五) okhttp连接池复用机制
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/13704572.html
Copyright © 2020-2023  润新知