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);
            }
        }
    }
}



原文地址:https://www.cnblogs.com/zuochanzi/p/13704572.html