AutoRegistDependency 1.0.40
See the version list below for details.
dotnet add package AutoRegistDependency --version 1.0.40
NuGet\Install-Package AutoRegistDependency -Version 1.0.40
<PackageReference Include="AutoRegistDependency" Version="1.0.40" />
paket add AutoRegistDependency --version 1.0.40
#r "nuget: AutoRegistDependency, 1.0.40"
// Install AutoRegistDependency as a Cake Addin #addin nuget:?package=AutoRegistDependency&version=1.0.40 // Install AutoRegistDependency as a Cake Tool #tool nuget:?package=AutoRegistDependency&version=1.0.40
AutoRegistDependency
介绍
AutoFac二次封装,实现根据特性自动注入功能。 Based on AutoFac development, achieve automatic injection function according to characteristics.
使用说明
nuget 搜索 AutoRegistDependency 进行安装
- 注册服务 Registration Services program.cs文件中 (.net6以上)
builder.Host.ConfigureContainer<ContainerBuilder>((hostBuilderContext, containerBuilder) =>
{
//以下两种方式都可以 Both of the following methods are possible
containerBuilder.RegisterModule(new Register(hostBuilderContext));
new Register(hostBuilderContext).RegisterType(containerBuilder);
});
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 只能标记在类上,代表此类型需要被自动注入
/// <summary>
/// 组件注入特性。可以标记在类上。Component、Confignature、Job以及ConfigurationProperties特性在同一个类上只能有一个。
/// Component injection attribute. Can be marked on a class.
/// The Component, Configure,Job,ConfigurationProperties attributes can only have one on the same class.
/// </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>
/// 配置文件实体模型特性。标记在类上。将会把配置文件内读取到的json文件转为对应类的实例。读取的规则和.net core原生读取规则相同。
/// Component、Confignature、Job以及ConfigurationProperties特性在同一个类上只能有一个。
/// Configure the physical model properties of the file. Mark on class.
/// The JSON file read from the configuration file will be converted into an instance of the corresponding class.
/// The reading rules are the same as the native reading rules for. net core.
/// The Component, Configure, Job, and ConfigurationProperties attributes can only have one on the same class.
/// </summary>
public ConfigurationPropertiesAttribute(string path)
{
Path = path;//path为使用IConfiguration读取数据的key,和.net core原生读取规则一致
}
ConfigurationAttribute 只能标记在类上,代表此类被容器单例管理,通常配合bean使用
/// <summary>
/// 标记此特性代表容器管理此类型的一个单例,通常作为配置类管理需要注册的服务需要和BeanAttribte配合使用。Component、Confignature以及Job特性在同一个类上只能有一个。
/// Marking this Attribute represents a singleton of container management for this type, typically used in conjunction with BeanAttribute as a configuration class to manage registered services.
/// The Component, Configure, and Job attributes can only have one on the same class.
/// </summary>
public sealed class ConfigurationAttribute:Attribute
{
}
JobAttribute 仅能标记在类上,代表此类为Quartz的任务类(此类必须实现Quartz的Ijob接口,否则会报错!)
/// <summary>
/// 定时任务注册特性。仅能标记在类上。
/// Component、Confignature、Job以及ConfigurationProperties特性在同一个类上只能有一个。
/// 注册之后还需调用RegisterExtension.QuartzRegist方法才能成功启动任务。
/// 如果定时任务类需要使用动态代理,一定要将Execute方法声明为virtual!因为定时任务启动时调用的是IJob的实现类而非IJob接口!
/// Timer task registration feature. Can only be marked on a class.
/// The Component, Configure, Job, and ConfigurationProperties attributes can only have one on the same class.
/// After registration, the RegisterExtension.QuartzRegister method needs to be called to successfully start the task.
/// If the scheduled task class requires the use of dynamic proxies, be sure to declare the Execute method as virtual!
/// Because the implementation class of IJob is called when the scheduled task starts, not the IJob interface!
/// <param name="cron">cron表达式</param>
/// <param name="priority">执行优先级 0-5</param>
public JobAttribute(string cron,int priority = 0)
{
Cron = cron;
Priority = priority;
}
BeanAttribute 只能标记在方法上,代表此方法返回的实例需要被管理 (此方法的类上未标记ConfigurationAttribute无效!!)
/// <summary>
/// 方法上进行标记。将返回的实例注册到容器中(返回值为Task或者void的方法不会注册)。Bean所在的类上无ConfigurationAttribute特性将不会注册。
/// 如果注册的方法是个泛型方法,那么泛型方法的返回值也必须是个泛型,且返回值的泛型的数量和顺序必须和方法一致。
/// 例如:public BeanTest1 <T> TestBean1 <T>() where T: class=>new BeanTest1 <T>();BeanTest1 为泛型类,在注册时会当成开放泛型进行注册。否则泛型方法返回的实例不会被注册。
/// Mark the method. Register the returned instance into the container (methods with a return value of Task or void will not be registered).
/// If there is no ConfigurationAttribute attribute on the class where the bean is located, it will not be registered.
/// If the registered method is a generic method, the return value of the generic method must also be a generic, and the number and order of generics for the return value must be consistent with the method.
/// For example: public BeanTest1 <T> TestBean1 <T>() where T: class=>new BeanTest1 <T>(); BeanTest1 is a generic class that will be registered as an open generic during registration.
/// Otherwise, the instance returned by the generic method will not be registered.
/// </summary>
public BeanAttribute(string name = "",object key=null,LifeTimeType lifeTimeType = LifeTimeType.Default)
{
Name = name;
Key= key;
LifeTimeType = lifeTimeType;
}
AutowiredAttribute 可以标记在属性、字段上以及方法上 代表此属性(字段)将注入到实例中
/// <summary>
/// 自动装配特性,可以标记在属性、字段以及方法上。可以根据特性的属性筛选不同的实现类。
/// Automatic assembly features can be marked on attributes, fields, and methods.
/// You can filter different implementation classes based on the properties of the feature.
/// </summary>
/// <param name="name">需要获取的服务名(根据参数的类型和name去取)</param>
public AutowiredAttribute(string name = "")
{
Name = name;
}
ValueAttribute 可标记在属性,字段和参数上。代表被标记的对象需要从配置文件中自动读取数据
/// <summary>
/// 配置文件值读取特性。可标记在类、属性、字段以及构造函数参数上。读取配置文件对应key的值,读取规则和原生.net core一致。
/// Configuration file value reading feature. Can be marked on classes, properties, fields, and constructor parameters.
/// Read the value of the key corresponding to the configuration file, and the reading rules are consistent with the native. net core.
/// </summary>
/// <param name="path">配置文件key</param>
public ValueAttribute(string path)
{
Path = path;
}
OrderAttribute 标记在类上,代表服务注册的顺序 越小越先注册
/// <summary>
/// 组件注册顺序特性。值越小越先注册(对bean无效)
/// Component registration order feature. Register first with smaller values (invalid for bean)
/// </summary>
public OrderAttribute(int order)
{
this.Order = order;
}
RegistAsAttribute 标记在类上,代表此服务以何种类型注册(如果不是注册类型的父类或者注册类型所实现的接口,在注册初始化时将会报错)
/// <summary>
/// 注册目标类型特性,可标记在类上和方法上。目标类型必须为此类实现的接口或父类。
/// Register target type attributes that can be marked on classes and methods.
/// The target type must be an interface or parent class implemented by this class.
public RegistAsAttribute(params Type[] types)
{
Types = types;
}
ConditionalAttribute 标记在类上或者方法上(支持多个特性打在同一目标),代表注册此服务是有条件的,conditionTypes为实现接口ICondition的实现类。如果hostBuilderContext为空的话,不会执行conditional特性所指定的类
/// <summary>
/// 条件注册特性。可以标记在类以及方法上。根据不同的条件实现类判断是否注册标记的服务。
/// Conditional registration attribute. Can be marked on classes and methods.
/// Implement classes based on different conditions to determine whether to register marked services.
/// </summary>
/// <param name="conditionTypes">必须为实现了ICondition接口的类。Must be a class that implements the ICondition interface</param>
public ConditionalAttribute(params Type[] conditionTypes)
{
ConditionTypes = conditionTypes;
}
/// <summary>
/// 注册条件判断接口。
/// Registration condition judgment interface
/// </summary>
public interface ICondition
{
bool Matches(HostBuilderContext hostBuilderContext, IComponentRegistryBuilder componentRegistry, object attributeMeta);
参数说明:
hostBuilderContext:包含程序整体的上下文信息,包括IHostEnvironment,IConfiguration等。
componentRegistry:注册上下文
attributeMeta:标记特性的原数据,Component为Type,Bean为MethodInfo
}
ConditionalOnPropertyAttribute 标记在类上或者方法上(支持多个特性打在同一目标),代表此服务的注册依赖于读取配置文件的值
/// <summary>
/// 根据配置文件项决定组件是否注册特性。可以标记在方法以及类上。
/// Determine whether the component registers features based on the configuration file items. Can be marked on methods and classes.
/// </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;//配置文件写的值 如果匹配就代表注册
}
- 动态代理注册方法 继承抽象类 AbstractInterceptor 实现抽象类的抽象方法(非泛型类的代理方法一定要是virtual,泛型类无法代理,只能代理泛型接口)
/// <summary>
/// 代理抽象类,动态代理需继承此类并重写他的方法。
/// Proxy abstract class.Dynamic proxy needs to inherit this class and override its methods
/// </summary>
public abstract class AbstractInterceptor : IInterceptor, IAsyncInterceptor
{
/// <summary>
/// 初始化Register扫描到的所有程序集。
/// Initialize all assemblies scanned by Register class.
/// </summary>
protected readonly IEnumerable<Assembly> dlls;
/// <summary>
/// ctor
/// </summary>
/// <param name="dlls"></param>
public AbstractInterceptor(IEnumerable<Assembly> dlls)
{
this.dlls = dlls;
}
/// <summary>
/// 此方法获取此拦截器所有需要代理的类。
/// This method obtains all classes that require proxies for this interceptor.
/// </summary>
/// <returns></returns>
public abstract IEnumerable<Type> GetInterceptorTypes();
/// <summary>
/// 将同步代理转为异步代理。如有特殊需求可以重写此方法。
/// Convert synchronous proxy to asynchronous proxy.Override if needed.
/// </summary>
/// <param name="invocation">代理方法的调用。Encapsulates an invocation of a proxied method.</param>
public virtual void Intercept(IInvocation invocation)
{
this.ToInterceptor().Intercept(invocation);
}
/// <summary>
/// 返回值为Task的异步方法都会走这个方法。
/// Asynchronous methods with a return value of Task will use this method
/// </summary>
/// <param name="invocation">代理方法的调用。Encapsulates an invocation of a proxied method.</param>
public abstract void InterceptAsynchronous(IInvocation invocation);
/// <summary>
/// 返回值为泛型Task的异步方法都会走这个方法。
/// Asynchronous methods that return a generic Task will use this method.
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="invocation">代理方法的调用。Encapsulates an invocation of a proxied method.</param>
public abstract void InterceptAsynchronous<TResult>(IInvocation invocation);
/// <summary>
/// 同步方法都会走这里。
/// All synchronization methods will will use this method.
/// </summary>
/// <param name="invocation">代理方法的调用。Encapsulates an invocation of a proxied method.</param>
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增强器。可对组件初始化前后对组件功能进行增强。
/// Bean enhancer. It is possible to enhance the functionality of components before and after initialization.
/// </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.聚合服务。如果需要将多个服务聚合到某一个接口组成满足业务逻辑,可以新建一个接口 如下: Aggregation services. If multiple services need to be aggregated into a single interface to meet business logic, a new interface can be created as follows
/// <summary>
/// 聚合服务特性。只能标记在接口上,不需要实现类。聚合服务不会被任何其他的代理类代理,同时也不受到IBeanPostProcessor的增强。
/// 聚合服务定义接口一定要是同步方法,异步方法暂不支持。
/// Aggregation service characteristics. It can only be marked on an interface and does not require an implementation class.
/// The aggregation service will not be proxied by any other proxy class, nor will it be enhanced by IBeanPostProcessor.
/// The aggregation service definition interface must be a synchronous method, and asynchronous methods are currently not supported.
/// </summary>
public AggregateServiceAttribute(LifeTimeType lifetime = LifeTimeType.Default)
{
Lifetime = lifetime;
}
[AggregateService]//聚合服务特性
public interface IMyAggregateService
{
[Autowired(name: "Test1")]
ITest test1();//支持使用Autowied特性筛选方法返回值
[Autowired(name: "Test")]
ITest test { get; }//支持使用Autowied特性筛选属性
}
注意:聚合服务不会被任何其他的代理类代理,同时也不受到IBeanPostProcessor的增强!!聚合服务定义接口一定要是同步方法,异步方法暂不支持!!
7.指定类的构造方法。 请注意:如果指定构造函数,则此类的类代理不会生效!则此类的类代理不会生效!则此类的类代理不会生效!
/// <summary>
/// Autofac注入时默认使用参数最多的构造函数,使用此特性指定所使用的构造函数。
/// 请注意:如果使用此特性指定构造函数,即便在拦截器内的GetInterceptorTypes()方法内声明代理此类,此类的类代理也不会生效。
/// 无参构造函数上标记此特性无效。
/// 此特性在同一个类中只能有一个。
/// 非构造函数指明此特性无效。
/// By default, the constructor with the most parameters is used during Autofac injection, and this attribute is used to specify the constructor to be used.
/// Please note that if this attribute is used to specify a constructor, even if a proxy class is declared within the GetInterceptorTypes() method within the interceptor, the class proxy for this class will not take effect.
/// This attribute is not valid when marked on an unarmed constructor.
/// This attribute can only have one in the same class.
/// Non constructor indicates that this attribute is invalid.
/// </summary>
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
public class ConstructorAttribute:Attribute
{
}
8.简单代码示例 新建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) };
}
//最新版已经在基类加入了默认实现,不再需要写一次了。如果有特殊需求,可以override此方法。
//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类型的服务需要使用动态代理,那么必须将Execute方法声明为virtual,否则无法实现代理)
[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();
}
所有服务注册时必须加入相应特性,否则无法注入成功(包括控制器)。All services must incorporate corresponding features when registering, otherwise injection cannot be successful (including controllers)
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 (>= 7.0.0)
- Autofac.Extensions.DependencyInjection (>= 8.0.0)
- Autofac.Extras.DynamicProxy (>= 6.0.1)
- Castle.Core.AsyncInterceptor (>= 2.1.0)
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Extensions.Configuration (>= 7.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 7.0.4)
- Microsoft.Extensions.DependencyModel (>= 7.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 7.0.0)
- Quartz (>= 3.6.2)
- 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 | 110 | 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 |
支持注册时指定构造函数