.net5 使用Autofac详解

Autofac与C#语言的结合非常紧密,并学习它非常的简单,也是.NET领域最为流行的IoC框架之一。

1. 初识Autofac

 public abstract class IAService
    {
    }
 public class AService:IAService
    {
        public AService()
        {
            Console.Write("AService被构造");
        }
    }

在startup中写入

  #region Autofac 测试
            ContainerBuilder builer = new ContainerBuilder();//实例化一个容器
            builer.RegisterType<AService>().As<IAService>();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve<IAService>();//获取服务
            #endregion

结果:他会构造出一个Aservice的实例,

2. Autofac多中注入

构造函数注入
下面来试一下构造函数的注入,再创建Bservice和Iservice

  public abstract class IBService
    {
    }
  public class BService:IBService
    {
     
      public BService()
        {
            Console.Write("BService被构造");
        }

    }

再A中注入B,这时候怎么玩呢?这里用构造函数注入

  public class AService:IAService
    {
        private IBService _bservice;

        public AService(IBService bservice)
        {
            Console.Write("AService被构造");
        }
       
    }

在startup中

#region Autofac 测试
            ContainerBuilder builer = new ContainerBuilder();//实例化一个容器
            builer.RegisterType<BService>().As<IBService>();
            builer.RegisterType<AService>().As<IAService>();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve<IAService>();//获取服务
            #endregion

执行顺序:先娶自动的实例化bservice,然后把bservice的对象再去实例化aserbice
所以先打印出这两句话
要把你最后得到的对象呢,写在最下面

  Console.Write("BService被构造");
  Console.Write("AService被构造");

属性注入
上面是用构造函数来实现,这里用属性来实现注入
关键词**PropertiesAutowired()**在哪个使用属性注入的就在后面加上这个

 public class AService:IAService
    {
        //private IBService _bservice;
        public  IBService _bservice { set; get; }
        public AService()
        {
            Console.Write("AService被构造");
        }
       
    }
 public class BService:IBService
    {
     
      public BService()
        {
            Console.Write("BService被构造");
        }

        public void Get()
        {
            Console.Write("Get被嗲用");
        }
    }

startup

 #region Autofac 测试
            ContainerBuilder builer = new ContainerBuilder();//实例化一个容器
            builer.RegisterType<BService>().As<IBService>();
            builer.RegisterType<AService>().As<IAService>().PropertiesAutowired();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve<IAService>();//获取服务
            #endregion

方法注入*

以方法的形式注入

 public class AService:IAService
    {
        //private IBService _bservice;
        public IBService _bservice;

        public void SetFun(IBService bservice)
        {
            _bservice = bservice;
        }
        /*public AService()
        {
            Console.Write("AService被构造");
        }*/
       
    }
#region Autofac 测试
            ContainerBuilder builer = new ContainerBuilder();//实例化一个容器
            builer.RegisterType<BService>().As<IBService>();
            builer.RegisterType<AService>().As<IAService>().OnActivated(item=>item.Instance.SetFun(item.Context.Resolve<IBService>())).As<IAService>();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve<IAService>();//获取服务
            #endregion

3. Autofac的生命周期

InstancePerDependency 瞬时生命周期(每次获取都不一样)
SingleInstance 单例生命周期(整个进程中只有一个)
InstancePerLifetimeScope 一个范围内都是相同的(下面是案例)

using(var scope1 = container.BeginLifetimeScope())
{
  for(var i = 0; i < 100; i++)
  {
    // 每次从这里解析它
    // 你会得到相同的实例。
    var w1 = scope1.Resolve<Worker>();
  }
}

InstancePerMatchingLifetimeScope(“1”) 也是范围生命周期(下面是案例)只不过可以自己自定义范围用名字来自定义

using(var scope1 = container.BeginLifetimeScope("1"))
{
  for(var i = 0; i < 100; i++)
  {
    // 每次从这里解析它
    // 你会得到相同的实例。
    var w1 = scope1.Resolve<Worker>();
  }
}

InstancePerRequest (必须请求来是实现实例)

4. Autofac支持配置文件(断开对细节的依赖)

引入程序集
autofac.extension.d…
autofac.configuration

5. Autofac单抽象多实现

AAService和AService同时实现IAService接口,在依赖注入的时候呢,系统无法获得你想要的具体实现类,会按照注册的顺序进行覆盖,这时候呢,就会有问题,autofac可以解决这个问题

 public class AAService:IAService
    {
    }
 public class AService:IAService
    {
        //private IBService _bservice;
        public IBService _bservice;

        public void SetFun(IBService bservice)
        {
            _bservice = bservice;
        }
        /*public AService()
        {
            Console.Write("AService被构造");
        }*/
       
    }

启用autofac

 public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).ConfigureLogging(options =>
                {
                    options.AddLog4Net("cigfile/log4net.Config");
                }).UseServiceProviderFactory(new AutofacServiceProviderFactory());

startup中的autofac的方法

        public void ConfigureContainer(ContainerBuilder builer)
        {
           //可以用具体来注入
            builer.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(item => item.IsAssignableTo<IAService>()));
        }
  public class BillQueryController : ControllerBase
    {
        public ILogger<BillQueryController> _logger;
     
        public AService _aservice;
        public AAService _aaservice;

        public BillQueryController(ILogger<BillQueryController> logger, AService aservice, AAService aaservice)
        {
            _logger = logger;
            _aservice = aservice;
            _aaservice = aaservice;

        }
        [HttpGet]
        public void Get()
        {
            _logger.LogWarning("222");
           
        }
        /*  public BillQueryController(IBillQueryService ibillqueryservice)
           {
               _ibillqueryservice = ibillqueryservice;
           }*/

        /*   public  async Task<IEnumerable<QVL_BILL>> GetBill()
           {
               return await _ibillqueryservice.GetBill();
           }*/


    }

Autofac模块化注册
就是说,当注册内容很多的时候,不能把内容都写在startup当中,这里可用模块来搞,还可以分类

public class AModule: Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(item => item.IsAssignableTo<IAService>()));
        }
    }

注入模块

  builer.RegisterModule(new AModule());

6. Autofac支持Aop

接口实现AOP

[Intercept(typeof(CustomAutofacAop))]//生效Aop
    public interface  IAService
    {
        public  void Show();
    }
}
  public class AService : IAService
    {
        
        public void Show()
        {
            throw new NotImplementedException();
        }
    }

新建aop类实现IInterceptor
在执行show方法之前会先进来这里

public class CustomAutofacAop : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            //之前
            invocation.Proceed();
            //之后
        }
    }
 public void ConfigureContainer(ContainerBuilder builer)
        {

            //builer.RegisterModule(new AModule());

            //支持aop
            builer.RegisterType(typeof(CustomAutofacAop));//注册aop
            builer.RegisterType<AService>().As<IAService>().EnableInterfaceInterceptors();//支持接口AOP
            //builer.RegisterType<AService>().As<IAService>();
        }
public class BillQueryController : ControllerBase
    {
        public ILogger<BillQueryController> _logger;
     
        //public AService _aservice;
        public IAService _iaservice;


        public BillQueryController(ILogger<BillQueryController> logger, IAService iaservice)
        {
            _logger = logger;
           // _aservice = aservice;
            1_iaservice = iaservice;


    }
        [HttpGet]
        public void Get()
        {
            _iaservice.Show();
            _logger.LogWarning("222");
           
        }

抽象的的实现不是Aservice,而是以profx结尾
只要是实现了标记了AOP特性的,都会实现aop

类实现AOP(解决多个实现,有些需要aop,有些不要)

第一步
标记在具体实现类上

 [Intercept(typeof(CustomAutofacAop))]//生效Aop

方法为虚方法

 
        public virtual void Show()
        {
            throw new NotImplementedException();
        }

第三步 EnableClassInterceptors() //支持类aop

builer.RegisterType<AService>().As<IAService>().EnableClassInterceptors() ;//支持类aop

解决多个实现,有些需要aop,有些不要
因为杀呢?一个接口多个实现,在注册的时候呢,只会实现最下面的那一个,如果想要获取上面的呢,做不到

builer.RegisterType<AService>().As<IAService>().EnableClassInterceptors() ;//合格其实获取不到
            builer.RegisterType<AAService>().As<IAService>().EnableClassInterceptors();//支持类aop

这里就来解决
新的注册方式

 builer.RegisterType<AService>().Named<IAService>("AService").EnableClassInterceptors();
            builer.RegisterType<AAService>().Named<IAService>("AAService").EnableClassInterceptors(); ;

控制器注入方式也变了,现注入autofac的上下文

  public class BillQueryController : ControllerBase
    {
       
        private IComponentContext _context;//autofac上下文


        public BillQueryController( IComponentContext context)
        {
            _context = context;
        }
        [HttpGet]
        public void Get()
        {
            IAService _iaservice = _context.ResolveNamed<IAService>("AService");//括号里面的名字要和startup里面括号里面的要一模一样,这就相当于一个标识
            IAService _iaaservice = _context.ResolveNamed<IAService>("AAService");
            _iaservice.Show();
            _iaaservice.Show();
           
           
        }
        


    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小盆友你是否很有多问号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值