栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

.net5 使用Autofac详解

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

.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().As();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve();//获取服务
            #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().As();
            builer.RegisterType().As();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve();//获取服务
            #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().As();
            builer.RegisterType().As().PropertiesAutowired();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve();//获取服务
            #endregion

方法注入*

以方法的形式注入

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

        public void SetFun(IBService bservice)
        {
            _bservice = bservice;
        }
        
       
    }
#region Autofac 测试
            ContainerBuilder builer = new ContainerBuilder();//实例化一个容器
            builer.RegisterType().As();
            builer.RegisterType().As().OnActivated(item=>item.Instance.SetFun(item.Context.Resolve())).As();//注册服务
            IContainer container = builer.Build();//获取容器
            IAService aserice=container.Resolve();//获取服务
            #endregion
3. Autofac的生命周期

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

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

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

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

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

启用autofac

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

startup中的autofac的方法

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

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

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

        


    }

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

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

注入模块

  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().As().EnableInterfaceInterceptors();//支持接口AOP
            //builer.RegisterType().As();
        }
public class BillQueryController : ControllerBase
    {
        public ILogger _logger;
     
        //public AService _aservice;
        public IAService _iaservice;


        public BillQueryController(ILogger 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().As().EnableClassInterceptors() ;//支持类aop

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

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

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

 builer.RegisterType().Named("AService").EnableClassInterceptors();
            builer.RegisterType().Named("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("AService");//括号里面的名字要和startup里面括号里面的要一模一样,这就相当于一个标识
            IAService _iaaservice = _context.ResolveNamed("AAService");
            _iaservice.Show();
            _iaaservice.Show();
           
           
        }
        


    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/908095.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号