在.net core中使用依赖注入是很常见的,最常见的我们会使用以下三种
services.AddScoped(); services.AddSingleton (); services.AddTransient (); 当我们的业务层内容不多的时候这样写没有什么问题,但是加入有100个BLL呢,那样一个一
个加会很麻烦,每加一个就要多写一次,而且容易忘记漏掉。
那么我们的需求是让希望能够实现批量注入,并且可以按照不同的生命周期去实现自动注入,以避免每加一个业务类,就要写一次services.AddScoped<>();
我将通过反射+特性来实现它。
1.首先新建一个类ServiceAttribute,该类要继承Attribute,定义一个属性LifeTime,用它来接收注入时需要的生命周期,默认等于ServiceLifetime.Scoped,使用ServiceLifetime.Scoped需要导入using Microsoft.Extensions.DependencyInjection命名空间。
////// 属性形式定义生命周期 /// 默认Scoped /// [AttributeUsage(AttributeTargets.Class)] public class ServiceAttribute:Attribute { public ServiceLifetime LifeTime { get; set; } public ServiceAttribute(ServiceLifetime serviceLifetime= ServiceLifetime.Scoped) { LifeTime = serviceLifetime; } }
2.在自己需要注入的业务类中加上ServiceAttribute特性,并给上生命周期,也可以不给,就默认是Scoped
[Service(ServiceLifetime.Scoped)]
public class TestBLL:TestIBLL
{
}
public interface TestIBLL
{
}
3.核心部分,新建一个IServiceCollection的扩展方法类,取名叫ServiceCollectionExpand,定义扩展方法AddBusiness
1.获取当前程序域中的所有程序集,然后获取每个程序集中的所有type,得到其中包含有我们写的ServiceAttribute特性的类。
2.遍历types,得到每一个type所继承的接口数组和它注入的生命周期的值,然后根据生命周期实现注入, service.AddSingleton(,)和service.AddSingleton<>()不同的是传入的参数不同,前者的两个值都是type类型,后者是两个泛型
////// IServiceCollection扩展类 /// public static class ServiceCollectionExpand { ////// 按特性中的生命周期注入业务组件 /// /// public static void AddBusiness(this IServiceCollection service) { //获取有ServiceAttribute特性的所有类 Listtypes = AppDomain.CurrentDomain .GetAssemblies() .SelectMany(x => x.GetTypes()) .Where(t => t.IsClass && !t.IsAbstract && t.GetCustomAttributes(typeof(ServiceAttribute), false).Length > 0 ) .ToList(); types.ForEach(impl=> { //获取该类所继承的所有接口 Type[] interfaces = impl.GetInterfaces(); //获取该类注入的生命周期 var lifetime = impl.GetCustomAttribute ().LifeTime; interfaces.ToList().ForEach(i => { switch (lifetime) { case ServiceLifetime.Singleton: service.AddSingleton(i,impl); break; case ServiceLifetime.Scoped: service.AddScoped(i, impl); break; case ServiceLifetime.Transient: service.AddTransient(i, impl); break; } }); }); } }
4.然后在startup类中的configureservices方法中调用扩展方法即可实现自动注入了
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
#region 注册业务组件
services.AddBusiness();
#endregion
}
使用的话,在控制器中和以前一样使用即可。有反射的基础知识再看的话会比较容易明白。
也有很多第三方组件可以实现批量依赖注入,比如autofac,Unity等。



