基于特性的方式结合Autofac第三方容器来完成对类的依赖注入。在这里你只需要在你的代码里面进行最简单的配置,然后只需要使用一个特性,或者不使用任何特性就能够完成注入类的实例。你可以在c#相关项目中,也可以在c#的基于netcore的项目中完成这样的事情。由于本人是以netcore开发项目,这里就以最新的net6.0项目作为使用讲解。当然这里也会提到在非netcore项目中集成自动注入的代码段。 如果你看完后觉得这个还行还可以还比较好,你可以在Nuget上通过搜索OpenDeepSpace.Autofac.AutomaticInjection引用到你自己的项目中进行使用。 废话不多说,懂的都懂,直接开整,上代码!!!
集成Autofac自动注入
在非NetCore项目中集成
ContainerBuilder builder=new ContainerBuilder();
builder.UseAutomaticInjection(new List<OpenDeepSpace.Autofac.AutomaticInjection.Ioc.AutomaticInjectionSelector>() {
});
通过这样简单的两句话就完成了集成就可以通过特性自动注入开整了
在NetCore项目中集成
如果要在Controller中使用自动注入需要添加这样一句话即把Contoller作为Service,非常重要,这里我直接写到前面。
builder.Services.AddControllers().AddControllersAsServices();
集成方式一
这里我是以Net6.0为例子
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.UseAutomaticInjection(new List<OpenDeepSpace.Autofac.AutomaticInjection.Ioc.AutomaticInjectionSelector>() {
new OpenDeepSpace.Autofac.AutomaticInjection.Ioc.AutomaticInjectionSelector(t=>t.BaseType==typeof(ControllerBase))
});
builder.RegisterType<ServiceOne>().AsSelf().As<IServiceOne>().Keyed<IServiceOne>(typeof(ServiceOne).FullName);
builder.RegisterType<ServiceOneUpdate>().AsSelf().As<IServiceOne>().Keyed<IServiceOne>(typeof(ServiceOneUpdate).FullName);
}).UseServiceProviderFactory(new AutofacServiceProviderFactory());
集成方式二
使用这种方式 如果你使用NetCore原有的依赖注入AddTransient/AddScoped/AddSingleton,如果存在一个接口多个实现的情况,会自动将实现类FullName作为Keyed的键注入到Autofac中,直接达到单接口多实现。
builder.Host.UseAutofac(new List<AutomaticInjectionSelector>()
{
new OpenDeepSpace.Autofac.AutomaticInjection.Ioc.AutomaticInjectionSelector(t=>t.BaseType==typeof(ControllerBase))
});
使用特性完成自动注入
这里有两个特性一个是AutomaticInjectionAttribute表示自动注入 一个是NonAutomaticInjectionAttribute表示不自动注入。 首先我们说第一个特性自动注入: AutomaticInjectionAttribute可以使用在类上/属性上/字段上 当使用在类上时,该类下面的所有属性和字段都将被注入
属性 | 说明 |
---|
ImplementationType | 指定实现类将解析该类作为实例,用于单接口多实现的情况 |
然后再说第二个特性不自动注入: NonAutomaticInjectionAttribute该特性使用在类上/属性上/字段上 该特性一般结合自动注入筛选集以及当AutomaticInjectionAttribute使用在类上是,用来标注某些类/属性/字段不使用自动注入
使用特性完成自动注入例子
[ApiController]
[Route("[controller]/[action]")]
public class AutomaticInjectionController : ControllerBase
{
private readonly ILogger<AutomaticInjectionController> logger;
[NonAutomaticInjection]
private ILogger<AutomaticInjectionController> logger2 { get; set; }
[AutomaticInjection(ImplementationType = typeof(IOptions<MvcOptions>))]
private MvcOptions _mvcOptions;
private readonly ILogger<AutomaticInjectionController> originLogger;
[AutomaticInjection(ImplementationType = typeof(ServiceOneUpdate))]
private readonly IServiceOne serviceOne;
public AutomaticInjectionController(ILogger<AutomaticInjectionController> originLogger)
{
this.originLogger = originLogger;
}
[HttpGet]
public void TestAutomaticInjection()
{
serviceOne.Op();
}
}
[AutomaticInjection]
public class ServiceOne : IServiceOne
{
public readonly ILogger<ServiceOne> logger;
public void Op()
{
logger.LogInformation($"{typeof(ServiceOne)} Op");
}
}
public class ServiceOneUpdate : IServiceOne
{
[AutomaticInjection]
private readonly ILogger<ServiceOneUpdate> logger;
public void Op()
{
logger.LogInformation($"{typeof(ServiceOneUpdate)} Op");
}
}
在不能使用自动注入下获取实例
在NetCore项目中
IocManager.InitContainer(app.Services.GetAutofacRoot());
以NetCore的Filter为例
public class ActionCheckFilter : IAsyncActionFilter
{
private MvcOptions mvcOptions=>IocManager.Resolve<IOptions<MvcOptions>>().Value;
private IServiceProvider serviceProvider => IocManager.Resolve<IServiceProvider>();
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await next();
await Task.CompletedTask;
}
}
通过以上的一顿配置注入的操作接下来简单的看一下结果:
批量注入
暂未实现准备实现
Aop切面
暂未实现准备实现
在使用过程中欢迎给位提出宝贵的意见,我将进一步改进
|