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