.Net core ---Autofac2

Autofac整合.NET5 Mvc
1.指定Autofac工厂替换默认工厂,Program指定

 public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
2.在Startup类增加Configurecontainer方法,注册关系

       /// <summary>
        /// 整个方法被Autofa自动调用
        /// 负责注册各种服务。尽管Autofac有专门的地方来注册服务
        ///之前ServiceColleetion注册的服务其实也会生效;
        /// </summary>
        /// <param name="containerBuilder"></param>
        public void ConfigureContainer(ContainerBuilder containerBuilder)
        {
            containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>();
            containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>();
            containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>().PropertiesAutowired();
        }

第二种方式

#region ServiceCollection注册的服务可以让Autofac使用,因为Autofac在自己注册服务之前;会先把ScrviceCollection中注册的服务全部接管过来;
            services.AddTransient<ITestServiceA, TestServiceA>();
            services.AddTransient<ITestServiceB, TestServiceB>();
            services.AddTransient<ITestServiceC, TestServiceC>();
            #endregion


2.通过控制器构造的数注入,获取实例

 public class TestServiceCController : Controller
    {
        private readonly ITestServiceA _testServiceA;
        private readonly ITestServiceC _testServiceC;
        private readonly ITestServiceB _testServiceB;
        public TestServiceCController(
            ITestServiceA testServiceA,
            ITestServiceC testServiceC,
            ITestServiceB testServiceB
            )
        {
            _testServiceA=testServiceA;
            _testServiceC=testServiceC;
            _testServiceB= testServiceB;
        }
        public IActionResult Index()
        {
            _testServiceC.show();
            return View();
        }
    }

Autofac支持控制器属性注入
控制器是一个类,控制器的实例其实是IControllerActivator来创建的;

1. 得让控制器使用容器来获取实例(Startup.cs);

  public void ConfigureServices(IServiceCollection services)
        {

     #region 指定控制器实例让容器来创建
 services.Replace(ServiceDescriptor.Transient<IControllerActivator,ServiceBasedControllerActivator>());
            #endregion

  }
2. 注册控制器抽象和具休的关系(Startup.cs)

 /// <summary>
        /// 整个方法被Autofa自动调用
        /// 负责注册各种服务
        /// </summary>
        /// <param name="containerBuilder"></param>
        public void ConfigureContainer(ContainerBuilder containerBuilder)
        {
        

            // 这样注册不够; 控制器的创建还需要依赖于其他的任何内容; 既然要注册就需要把所有依赖的内容都注册进来;
            //containerBuilder.RegisterType<TestServiceCController>().As<ControllerBase>();

            #region 注册所有控制器的关系 控制器实例化需要的所有组件
            Type[] controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
                .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();

            containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(new CustomPropertySelector());
           #endregion

 

3. 在控制器内定义属性

public class TestServiceCController : Controller
    {
     
  [CustomPropertyAttribute]
        private ITestServiceA TestServiceA { get; set; }
        private ITestServiceA TestServiceB { get; set; }
        private ITestServiceA TestServiceC { get; set; }

        private readonly ITestServiceA _testServiceA;
        private readonly ITestServiceC _testServiceC;
        private readonly ITestServiceB _testServiceB;
        public TestServiceCController(
            ITestServiceA testServiceA,
            ITestServiceC testServiceC,
            ITestServiceB testServiceB
            )
        {
            _testServiceA=testServiceA;
            _testServiceC=testServiceC;
            _testServiceB= testServiceB;
        }
        public IActionResult Index()
        {
            _testServiceC.show();
            return View();
        }
    }

4. 扩展,自己控制究竟哪些属性需要做依赖注入

CustomPropertyAttribute.cs

    [AttributeUsage(AttributeTargets.Property)]
    public class CustomPropertyAttribute:Attribute
    {
    } 

CustomPropertySelector

 public class CustomPropertySelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            //需要一个判断的范围
            return propertyInfo.CustomAttributes.Any(it => it.AttributeType== typeof(CustomPropertyAttribute));
        }
    }

Autofac抽象多实现的问题
1.一个抽象多个实例,都注册了,通过构造函数用抽象类型来获取实例,哪个后面注册就获取到哪一个;覆盖型;

2.一个抽象多个实例,都注册了,可以通过一个IEnumerables<抽象>,当做构造函数参数,可以获取到所有注册的具体的实例;

3.注朋一个抽象的多个实例资源

startup.cs

 public void ConfigureContainer(ContainerBuilder containerBuilder)
        {

            #region 注册所有控制器的关系 控制器实例化需要的所有组件
            Type[] controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
                .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();

            containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(new CustomPropertySelector());

            #endregion

            #region 注册单抽象多实例
            containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>();
            containerBuilder.RegisterType<TestServiceUpdate>().As<ITestServiceA>();
            #endregion

            #region 单抽像多实现
            containerBuilder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(t =>
            t.IsAssignableTo<ITestServiceA>()));
            #endregion

        }

TestServiceCController

private readonly ITestServiceA _testServiceA;

        private readonly IEnumerable<ITestServiceA> _testServiceAList;

        private readonly TestServiceA _testServiceA1112;

        private readonly TestServiceUpdate _testServiceUpdate;

        public TestServiceCController(
            ITestServiceA testServiceA, 
            IEnumerable<ITestServiceA> testServiceAList,
            TestServiceA testServiceA1112,//接受具体的
            TestServiceUpdate testServiceUpdate//接受具体的
            )
        {
            _testServiceA = testServiceA;
            testServiceAList = _testServiceAList;
            testServiceA1112 = _testServiceA1112;
            testServiceUpdate = _testServiceUpdate;

        }

Autofac支持AOP
AOP面向切面编程;不用修改之前代码的基础上,可以动态的在某个动作之前加一些操作,动态在在某一个动作之后做点什么事儿。

1.Nuget引入Castle.Core程序集+Autofac.Extras.DynamicProxy程序集合

2.在服务的抽象上标记[Intercept(typeof(CustomAutofacAop))]

  [Intercept(typeof(CustomAutofacAop))] //AOP能够在当前接口生效
   public interface ITestServiceA
    {
        void show();
    }

3.注册支持AOP扩展的类

containerBuilder.RegisterType(typeof(CustomAutofacAop));

4.注册服务的时候,需要调用EnableInterfaceInterceptors, 标记说明当前服务获取实例后可以支持AOP

         #region Autofac支持AOP
            containerBuilder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(t =>
            t.IsAssignableTo<ITestServiceA>()));

            containerBuilder.RegisterType(typeof(CustomAutofacAop));
            containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>()
                .EnableInterfaceInterceptors();//接口
            containerBuilder.RegisterType<TestServiceUpdate>().As<ITestServiceA>()
                .EnableInterfaceInterceptors();// 接口
            #endregion

 public class CustomAutofacAop : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            {
                Console.WriteLine("方法执行前");
            }
            invocation.Proceed();//执行这句话就是去执行具体的实例的这个方法
            {
                Console.WriteLine("方法执行后");
            }
        }
    } 

Autofac支持AOP-2

EnableInterfaceInterceptors+抽象标记特性[Interceptypeof(CustomAutofacAop),只要是实现了这个抽象就可以支持AOP
EnableClassInterceptors +实现类标记特性(Interceptitypeof(CustomAutofacop)] ,只有标记了这个特性的,才能够支持AOP
如果使用EnableClassInterceptors来支持AOP,实现类中支持AOP的方法必须为虚方法;

   containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>()
                .EnableClassInterceptors(); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值