AutoRegistDependency 1.0.32
See the version list below for details.
dotnet add package AutoRegistDependency --version 1.0.32
NuGet\Install-Package AutoRegistDependency -Version 1.0.32
<PackageReference Include="AutoRegistDependency" Version="1.0.32" />
paket add AutoRegistDependency --version 1.0.32
#r "nuget: AutoRegistDependency, 1.0.32"
// Install AutoRegistDependency as a Cake Addin #addin nuget:?package=AutoRegistDependency&version=1.0.32 // Install AutoRegistDependency as a Cake Tool #tool nuget:?package=AutoRegistDependency&version=1.0.32
AutoRegistDependency
介绍
AutoFac二次封装,实现根据特性自动注入功能
使用说明
nuget 搜索 AutoRegistDependency 进行安装
- 注册服务 program.cs文件中 (.net6以上)
builder.Host.ConfigureContainer<ContainerBuilder>((hostBuilderContext, containerBuilder) =>
{
//以下两种方式都可以
containerBuilder.RegisterModule(new Register(hostBuilderContext));
new Register(hostBuilderContext).RegisterType(containerBuilder);
//启用Quartz module!!
containerBuilder.RegisterModule(new QuartzAutofacFactoryModule());
});
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
**如果控制器需要使用autofac原生属性注入,需要使autofac接管controller,需添加以下代码**
builder.Services.AddControllers().AddControllersAsServices();//控制器生成作为服务
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
WebApplication? app = builder.Build();
//这句为启用quartz注册的任务,没有这句代码定时任务不启动!!
app.Services.QuartzRegist();
.net core 3.x program.cs文件中
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureContainer<ContainerBuilder>((hostBuilderContext, containerBuilder)=>
{
new Register(hostBuilderContext).RegisterType(containerBuilder);
//启用Quartz module!!
containerBuilder.RegisterModule(new QuartzAutofacFactoryModule());
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
startup.cs 文件中
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.ApplicationServices.QuartzRegist();
}
.net core 2.x (暂时先请用1.0.9之前的版本 ) startup文件中,改写ConfigureServices方法
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var builder = new ContainerBuilder();//实例化 AutoFac 容器
builder.Populate(services);//管道寄居
new Register()
//.SetDefaultLifeTime() //设置所有实例的默认生命周期,默认scope
.RegisterType(builder);
ApplicationContainer = builder.Build();
return new AutofacServiceProvider(ApplicationContainer);//将autofac反馈到管道中
}
特别说明:此组件默认读取系统的IConfignature服务获取配置文件数据,默认支持nacos读取json文件(如果nacos注册成功的话)
- 特性说明
ComponentAttribute 只能标记在类上,代表此类型需要被自动注入
/// constructor
/// </summary>
/// <param name="lifetime">生命周期</param>
/// <param name="autoActivate">是否自动激活实例</param>
/// <param name="interceptorType">拦截器代理类型</param>
/// <param name="name">服务名(默认类名简称)</param>
/// <param name="key">服务key</param>
/// <param name="registType">注册类型(注册自己本身还是作为接口实现类)</param>
/// <param name="propertyInjectType">autofac属性注入方式,是否通过特性标记需要注入的属性</param>
public ComponentAttribute(LifeTimeType lifetime = LifeTimeType.Default, bool autoActivate = false,
string name = "",object key=null,RegistType registType= RegistType.Default,
PropertyInjectType propertyInjectType = PropertyInjectType.Default)
{
Lifetime = lifetime;
AutoActivate = autoActivate;
Name = name;
PropertyInjectType = propertyInjectType;
Key = key;
RegistType= registType;
}
ConfigurationPropertiesAttribute 只能标记在类上,代表此类型是通过配置文件读取并进行实例绑定
/// <summary>
/// constructor
/// </summary>
public ConfigurationPropertiesAttribute(string path)
{
Path = path;//path为使用IConfiguration读取数据的key,和.net core原生读取规则一致
}
ConfigurationAttribute 只能标记在类上,代表此类被容器单例管理,通常配合bean使用
public sealed class ConfigurationAttribute:Attribute
{
}
注意 以上三种特性在同一个类中只能拥有一个,也就是说一个类只能作为一种服务类型注册到容器中!
BeanAttribute 只能标记在方法上,代表此方法返回的实例需要被管理 (此方法的类上未标记ConfigurationAttribute无效!!)
/// <summary>
/// constructor
/// </summary>
public BeanAttribute(string name = "",object key=null,LifeTimeType lifeTimeType = LifeTimeType.Default)
{
Name = name;
Key= key;
LifeTimeType = lifeTimeType;
}
AutowiredAttribute 可以标记在属性、字段上以及方法上 代表此属性(字段)将注入到实例中
/// <summary>
/// constructor
/// </summary>
/// <param name="name">需要获取的服务名(根据参数的类型和name去取)</param>
public AutowiredAttribute(string name = "")
{
Name = name;
}
ValueAttribute 可标记在属性,字段和参数上。代表被标记的对象需要从配置文件中自动读取数据
//path为读取配置文件的字符串,和使用IConfiguration原生读取规则相同。
public ValueAttribute(string path)
{
Path = path;
}
OrderAttribute 标记在类上,代表服务注册的顺序 越小越先注册
/// <summary>
/// constructor
/// </summary>
public OrderAttribute(int order)
{
this.Order = order;
}
RegistAsAttribute 标记在类上,代表此服务以何种类型注册(如果不是注册类型的父类或者注册类型所实现的接口,在注册初始化时将会报错)
/// <summary>
/// constructor
/// </summary>
public RegistAsAttribute(params Type[] types)
{
Types = types;
}
ConditionalAttribute 标记在类上或者方法上(支持多个特性打在同一目标),代表注册此服务是有条件的,conditionTypes为实现接口ICondition的实现类。如果hostBuilderContext为空的话,不会执行conditional特性所指定的类
public ConditionalAttribute(params Type[] conditionTypes)
{
ConditionTypes = conditionTypes;
}
public interface ICondition
{
bool Matches(HostBuilderContext hostBuilderContext, IComponentRegistryBuilder componentRegistry, object attributeMeta);
参数说明:
hostBuilderContext:包含程序整体的上下文信息,包括IHostEnvironment,IConfiguration等。
componentRegistry:注册上下文
attributeMeta:标记特性的原数据,Component为Type,Bean为MethodInfo
}
ConditionalOnPropertyAttribute 标记在类上或者方法上(支持多个特性打在同一目标),代表此服务的注册依赖于读取配置文件的值
/// <summary>
/// ctor
/// </summary>
/// <param name="name">配置文件名</param>
/// <param name="havingValue">配置文件值</param>
/// <param name="prefix">前缀</param>
public ConditionalOnPropertyAttribute(string name,string havingValue,string prefix="")
{
//例如根据配置文件Logging:LogLevel:Default的值来进行注册。
//Prefix="Logging:LogLevel" name="Default" 或者
//name="Logging:LogLevel:Default"
Prefix= prefix;
Name= name;
HavingValue= havingValue;//配置文件写的值 如果匹配就代表注册
}
JobAttribute 仅能标记在类上,代表此类为Quartz的任务类(此类必须实现Quartz的Ijob接口,否则会报错!)
/// <summary>
/// ctor
/// </summary>
/// <param name="cron">cron表达式</param>
/// <param name="priority">执行优先级 0-5</param>
public JobAttribute(string cron,int priority = 0)
{
Cron = cron;
Priority = priority;
}
- 动态代理注册方法 继承抽象类 AbstractInterceptor 实现抽象类的抽象方法(非泛型类的代理方法一定要是virtual,泛型类无法代理,只能代理泛型接口)
public abstract class AbstractInterceptor : IInterceptor, IAsyncInterceptor
{
protected readonly IEnumerable<Assembly> dlls;//为实例化Register时所扫描的程序集
public AbstractInterceptor(IEnumerable<Assembly> dlls)
{
this.dlls = dlls;
}
public abstract IEnumerable<Type> GetInterceptorTypes();//此方法返回需要被代理的所有类型
public abstract void Intercept(IInvocation invocation);//固定写法 this.ToInterceptor().Intercept(invocation);
public abstract void InterceptAsynchronous(IInvocation invocation);//Task返回类型的拦截方法
public abstract void InterceptAsynchronous<TResult>(IInvocation invocation);//Task<TResult>返回类型的拦截方法
public abstract void InterceptSynchronous(IInvocation invocation);//同步方法的拦截
}
4.事件总线功能 在需要使用事件总线的代码处注入EventBus或IEventBus:
[ApiController]
[Component]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly LogModel logModel;
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
[Autowired]
private IEventBus eventPublisher;
public WeatherForecastController(LogModel logModel,ILogger<WeatherForecastController> logger)
{
_logger = logger;
this.logModel = logModel;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
List<int> list=eventPublisher.PublishAsync<LogModel, int>(testValue).GetAwaiter().GetResult();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
在需要消费事件的代码处实现接口 IEventAsyncHandler<T,TResult> 需注意:EventBus发布的eventData和IEventAsyncHandler接口的泛型T完全匹配时,才能触发
[Component]
public class WorkListener: IEventAsyncHandler<LogModel, int>
{
public async Task<int> Handle(LogModel eventData)
{
await Task.Run(() =>
{
Console.WriteLine("123");
Task.Delay(500);
}) ;
return 0;
}
}
IEventBus调用方法对应触发的接口如下:
public interface IEventBus
{
/// <summary>
/// 同步发布消息
/// </summary>
/// <typeparam name="T">eventData类型</typeparam>
/// <param name="eventData">消息数据</param>
void Publish<T>(T eventData);//ps:此方法触发实现了IEventHandler<T>的类,eventData类型和接口泛型必须相同,且消费者必须受到Autofac的管理!!
/// <summary>
/// 异步发布消息
/// </summary>
/// <typeparam name="T">eventData类型</typeparam>
/// <param name="eventData">消息数据</param>
/// <returns></returns>
Task PublishAsync<T>(T eventData);//ps:此方法触发实现了IEventAsyncHandler<T>的类,eventData类型和接口泛型必须相同,且消费者必须受到Autofac的管理!!
/// <summary>
/// 发布消息(有返回值)
/// </summary>
/// <typeparam name="T">eventData类型</typeparam>
/// <typeparam name="TResult">返回结果类</typeparam>
/// <param name="eventData">消息数据</param>
/// <returns></returns>
List<TResult> Publish<T,TResult>(T eventData);//ps:此方法触发实现了IEventHandler<T,TResult>的类,eventData类型和返回值和接口泛型必须相同,且消费者必须受到Autofac的管理!!
/// <summary>
/// 异步发布消息(有返回值)
/// </summary>
/// <typeparam name="T">eventData类型</typeparam>
/// <typeparam name="TResult">返回结果类</typeparam>
/// <param name="eventData">消息数据</param>
/// <returns></returns>
Task<List<TResult>> PublishAsync<T,TResult>(T eventData);//ps:此方法触发实现了IEventAsyncHandler<T,TResult>的类,eventData类型和返回值和接口泛型必须相同,且消费者必须受到Autofac的管理!!
}
5.IBeanPostProcessor bean增强器。如果需要对注册的实例进行增强,可以实现IBeanPostProcessor,并注册到Autofac中( 注意:如果实现了IBeanPostProcessor 在注册时仅将其作为IBeanPostProcessor服务注册,不会注册自身及其他实现的接口!! )
/// <summary>
/// bean增强器
/// </summary>
public interface IBeanPostProcessor
{
/// <summary>
/// 构造函数构造对象成功之后对bean进行增强
/// </summary>
/// <param name="bean">bean实例</param>
/// <returns>增强后的bean实例</returns>
object PostProcessBeforeInitialization(object bean);
/// <summary>
/// 字段、方法、属性注入等成功之后对bean进行增强
/// </summary>
/// <param name="bean">bean实例</param>
/// <returns>增强后的bean实例</returns>
object PostProcessAfterInitialization(object bean);
}
6.聚合服务。如果需要将多个服务聚合到某一个接口组成满足业务逻辑,可以新建一个接口 如下:
[AggregateService]//聚合服务特性
public interface IMyAggregateService
{
[Autowired(name: "Test1")]
ITest test1();//支持使用Autowied特性筛选方法返回值
[Autowired(name: "Test")]
ITest test { get; }//支持使用Autowied特性筛选属性
}
注意:聚合服务不会被任何其他的代理类代理,同时也不受到IBeanPostProcessor的增强!!聚合服务定义接口一定要是同步方法,异步方法暂不支持!!
7.简单代码示例 新建web项目 新建接口和实现
public interface ITest
{
string Say();
}
**[Component(name:"Test")]**
public class Test : ITest
{
public Test() { }
public string Say()
{
return nameof(Test);
}
}
**[Component(key: "Test1")]**
public class Test1 : ITest
{
public virtual string Say()
{
return nameof(Test1);
}
}
//新建配置文件自动绑定实体
[ConfigurationPropertiesAttribute(path: "Logging:LogLevel")]
public class LogModel
{
public string Default { get; set; }
}
bean类型注册
**[Configuration]**
public class ConfigurationTest
{
**[Bean]**
public LogModel GetBeanObject([ComponentFilter(name: "Test")] ITest test)
{
test.Say();
return new LogModel()
{
Default = "12345"
};
}
//拦截器
**[Component]**
public class TestInterceptor : AbstractInterceptor
{
public TestInterceptor(IEnumerable<Assembly> dlls) : base(dlls)
{
}
public override IEnumerable<Type> GetInterceptorTypes()
{
// this.dlls 为程序运行时所扫描到的所有程序集,批量拦截操作可以通过这个变量进行筛选返回相应的Types!!如下:
//return this.dlls.Where(t => t.GetName().Name.StartsWith("Adks.WxMini.Repository") || t.GetName().Name.StartsWith("Adks.WxMini.Services")).SelectMany(t => t.GetTypes().Where(a => a.Name.EndsWith("Repository") || a.Name.EndsWith("Services")));
//从基类继承的dll变量是扫描到的所有程序集,可以通过程序集获取对应的被代理类型 这里只是个示例
return new Type[] { typeof(Test),typeof(Test1) };
}
public override void Intercept(IInvocation invocation)
{
this.ToInterceptor().Intercept(invocation);
}
public override void InterceptAsynchronous(IInvocation invocation)
{
Console.WriteLine($"before:{nameof(InterceptAsynchronous)}");
invocation.Proceed();//执行被拦截的返回值为Task的方法
Console.WriteLine($"after:{nameof(InterceptAsynchronous)}");
}
public override void InterceptAsynchronous<TResult>(IInvocation invocation)
{
Console.WriteLine($"before:{nameof(InterceptAsynchronous)}");
invocation.Proceed();
Console.WriteLine($"after:{nameof(InterceptAsynchronous)}");
}
public override void InterceptSynchronous(IInvocation invocation)
{
Console.WriteLine($"before:{nameof(InterceptSynchronous)}");
invocation.Proceed();
Console.WriteLine($"after:{nameof(InterceptSynchronous)}");
}
}
//Quartz任务注册
[Job(cron: "0/5 * * * * ? ")]
public class TestJob : IJob
{
//所有的注入方式都支持
//[Value("Logging:LogLevel")]
private LogModel testValue;
public TestJob(LogModel testValue)
{
this.testValue = testValue;
}
public Task Execute(IJobExecutionContext context)
{
return Task.Run(() =>
{
Console.WriteLine(testValue.Default);
});
}
}
//注入调用
[ApiController]
**[Component]**
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly LogModel logModel;
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
[Autowired(key: "Test1")]
private Test1 test1;//属性注入,指定服务key名
private ITest test;
[Value("Logging:LogLevel")]
private LogModel testValue;//配置文件注入
[Autowired]
private IGenercTest<LogModel> genercTest;
[Autowired]
private void GetTest([ComponentFilter(name: "Test")] ITest test)//方法注入,支持参数特性筛选指定服务
{
this.test = test;
}
public WeatherForecastController(LogModel logModel,ILogger<WeatherForecastController> logger)
{
_logger = logger;
//this.test= test;
this.logModel = logModel;
//this.genercTest = genercTest;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
Console.WriteLine($"test:{test1.Say()}");
Console.WriteLine($"genercTest:{genercTest.Say()}");
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
所有服务注册时必须加入响应的特性,否则无法注入成功(包括控制器)
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Autofac (>= 6.5.0)
- Autofac.Extensions.DependencyInjection (>= 8.0.0)
- Autofac.Extras.DynamicProxy (>= 6.0.1)
- Autofac.Extras.Quartz (>= 8.2.0)
- Castle.Core.AsyncInterceptor (>= 2.1.0)
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Extensions.Configuration (>= 7.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 7.0.3)
- Microsoft.Extensions.DependencyModel (>= 7.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 7.0.0)
- System.Runtime.Loader (>= 4.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.55 | 109 | 9/6/2024 |
1.0.54 | 132 | 6/5/2024 |
1.0.53 | 109 | 6/5/2024 |
1.0.52 | 99 | 5/21/2024 |
1.0.50 | 154 | 4/24/2024 |
1.0.49 | 115 | 4/23/2024 |
1.0.48 | 125 | 2/28/2024 |
1.0.47 | 140 | 1/23/2024 |
1.0.46 | 194 | 12/5/2023 |
1.0.45 | 215 | 9/8/2023 |
1.0.44 | 187 | 8/23/2023 |
1.0.43 | 151 | 8/10/2023 |
1.0.42 | 155 | 6/26/2023 |
1.0.41 | 151 | 5/23/2023 |
1.0.40 | 196 | 4/18/2023 |
1.0.39 | 197 | 4/14/2023 |
1.0.38 | 186 | 4/11/2023 |
1.0.37 | 201 | 4/11/2023 |
1.0.36 | 217 | 4/3/2023 |
1.0.35 | 240 | 3/16/2023 |
1.0.34 | 270 | 3/6/2023 |
1.0.32 | 243 | 3/3/2023 |
1.0.31 | 256 | 3/2/2023 |
1.0.30 | 253 | 3/2/2023 |
1.0.29 | 252 | 3/1/2023 |
1.0.28 | 273 | 2/25/2023 |
1.0.27 | 266 | 2/22/2023 |
1.0.26 | 259 | 2/22/2023 |
1.0.25 | 253 | 2/21/2023 |
1.0.24 | 257 | 2/20/2023 |
1.0.23 | 248 | 2/17/2023 |
1.0.22 | 319 | 2/15/2023 |
1.0.21 | 283 | 2/13/2023 |
1.0.20 | 271 | 2/9/2023 |
1.0.19 | 274 | 2/9/2023 |
1.0.18 | 282 | 2/7/2023 |
1.0.17 | 264 | 2/7/2023 |
1.0.16 | 258 | 2/7/2023 |
1.0.15 | 277 | 2/4/2023 |
1.0.14 | 287 | 2/2/2023 |
1.0.13 | 309 | 1/31/2023 |
1.0.12 | 296 | 1/31/2023 |
1.0.11 | 283 | 1/31/2023 |
1.0.10 | 311 | 1/30/2023 |
1.0.9 | 306 | 1/30/2023 |
1.0.8 | 302 | 1/30/2023 |
1.0.5 | 296 | 1/28/2023 |
1.0.4 | 321 | 1/28/2023 |
1.0.3 | 316 | 1/23/2023 |
1.0.2 | 317 | 1/21/2023 |
1.0.1 | 311 | 1/17/2023 |
1.0.0 | 318 | 1/17/2023 |