1.创建特性 用于标注依赖注入

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic; namespace Util.Attributes
{
/// <summary>
/// 标注要运用DI的类 被此属性标注的类 要被注册到依赖注入容器中 并且可以指定类要映射的接口或者类
/// 此属性只能运用于类,并且此属性不能继承
/// </summary>
[AttributeUsage(AttributeTargets.Class,Inherited =false)]
public class UseDIAttribute:Attribute
{
//Targets用于指示 哪些接口或者类 要被 "被属性修饰了的类" 进行依赖注入
public List<Type> TargetTypes=new List<Type>();
public ServiceLifetime lifetime;
public UseDIAttribute(ServiceLifetime argLifetime,params Type[] argTargets)
{
lifetime = argLifetime;
foreach (var argTarget in argTargets)
{
TargetTypes.Add(argTarget);
}
} public List<Type> GetTargetTypes()
{
return TargetTypes;
}
public ServiceLifetime Lifetime
{
get
{
return this.lifetime;
}
}
}
}

2.对程序集中要注入的类进行标记

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using System.Threading.Tasks;
using User.Domain;
using User.Domain.POCOModels;
using Util.Attributes; namespace DDD.Repositories.UserRepositories
{
[UseDI(ServiceLifetime.Scoped,typeof(ILoginRepository))]
public class LoginEFCoreRepository:ILoginRepository
{
private readonly DbContext dbContext;
public LoginEFCoreRepository(DbContext dbContext)
{
this.dbContext = dbContext;
}

3.为IserviceCollection扩展一个方法  可以实现对程序集进行操作

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Util.Attributes; namespace Util.DIPlugin
{
public static class NetCoreDIModuleRegister
{
/// <summary>
/// 自动注册服务
/// </summary>
/// <param name="services">注册服务的集合(向其中注册)</param>
/// <param name="ImplementationType">要注册的类型</param>
public static void AutoRegisterService(this IServiceCollection services, Type ImplementationType)
{
//获取类型的 UseDIAttribute 属性 对应的对象
UseDIAttribute attr = ImplementationType.GetCustomAttribute(typeof(UseDIAttribute)) as UseDIAttribute;
////获取类实现的所有接口
//Type[] types = ImplementationType.GetInterfaces();
List<Type> types = attr.GetTargetTypes();
var lifetime = attr.Lifetime;
//遍历类实现的每一个接口
foreach (var t in types)
{
//将类注册为接口的实现-----但是存在一个问题,就是担心 如果一个类实现了IDisposible接口 担心这个类变成了这个接口的实现
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(t, ImplementationType, lifetime);
services.Add(serviceDescriptor);
} }
/// <summary>
/// 根据程序集的名字获取程序集中所有的类型集合
/// </summary>
/// <param name="AssemblyName">程序集名字</param>
/// <returns>类型集合</returns>
public static Type[] GetTypesByAssemblyName(String AssemblyName)
{
Assembly assembly = Assembly.Load(AssemblyName);
return assembly.GetTypes();
} #region 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中 重载1
/// <summary>
/// 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="AassemblyName">程序集名字</param>
public static void AutoRegisterServicesFromAssembly(this IServiceCollection services,
string AassemblyName)
{
//根据程序集的名字 获取程序集中所有的类型
Type[] types = GetTypesByAssemblyName(AassemblyName);
//过滤上述程序集 首先按照传进来的条件进行过滤 接着要求Type必须是类,而且不能是抽象类
IEnumerable<Type> _types = types.Where(t => t.IsClass && !t.IsAbstract);
foreach (var t in _types)
{
IEnumerable<Attribute> attrs = t.GetCustomAttributes();
//遍历类的所有特性
foreach (var attr in attrs)
{
//如果在其特性中发现特性是 UseDIAttribute 特性 就将这个类注册到DI容器中去
//并跳出当前的循环 开始对下一个类进行循环
if (attr is UseDIAttribute)
{
services.AutoRegisterService(t);
break;
}
}
}
}
#endregion #region 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中 重载2
/// <summary>
/// 将程序集中的所有符合条件的类型全部注册到 IServiceCollection 中
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="AassemblyName">程序集名字</param>
/// <param name="wherelambda">过滤类型的表达式</param>
public static void AutoRegisterServicesFromAssembly(this IServiceCollection services,
string AassemblyName, Func<Type, bool> wherelambda)
{
//根据程序集的名字 获取程序集中所有的类型
Type[] types = GetTypesByAssemblyName(AassemblyName);
//过滤上述程序集 首先按照传进来的条件进行过滤 接着要求Type必须是类,而且不能是抽象类
IEnumerable<Type> _types = types.Where(wherelambda).Where(t => t.IsClass && !t.IsAbstract);
foreach (var t in _types)
{
IEnumerable<Attribute> attrs = t.GetCustomAttributes();
//遍历类的所有特性
foreach (var attr in attrs)
{
//如果在其特性中发现特性是 UseDIAttribute 特性 就将这个类注册到DI容器中去
//并跳出当前的循环 开始对下一个类进行循环
if (attr is UseDIAttribute)
{
services.AutoRegisterService(t);
break;
}
}
}
}
#endregion }
}

4.在webapi的startup.cs类中注册 需要处理的程序集:

利用.net Core 对程序集中的类 进行统一依赖注入的更多相关文章

  1. ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    ExpandoObject与DynamicObject的使用   using ImpromptuInterface; using System; using System.Dynamic; names ...

  2. NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions

    .NET Core 控制台程序没有 ASP.NET Core 的 IWebHostBuilder 与 Startup.cs ,那要读 appsettings.json.注依赖.配日志.设 IOptio ...

  3. ASP.NET Core 中间件的使用(二):依赖注入的使用

    写在前面 上一篇大家已经粗略接触了解到.NET Core中间件的使用:ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件, .NET Core框架中很多核心对象都是通过依 ...

  4. ASP.NET Core 6框架揭秘实例演示[05]:依赖注入基本编程模式

    毫不夸张地说,整个ASP.NET Core就是建立在依赖注入框架之上的.ASP.NET Core应用在启动时构建管道所需的服务,以及管道处理请求使用到的服务,均来源于依赖注入容器.依赖注入容器不仅为A ...

  5. ASP.NET Core 6框架揭秘实例演示[06]:依赖注入框架设计细节

    由于依赖注入具有举足轻重的作用,所以<ASP.NET Core 6框架揭秘>的绝大部分章节都会涉及这一主题.本书第3章对.NET原生的依赖注入框架的设计和实现进行了系统的介绍,其中设计一些 ...

  6. ASP.NET Core中使用自定义MVC过滤器属性的依赖注入

    除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...

  7. .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...

  8. 把旧系统迁移到.Net Core 2.0 日记(3) - 详解依赖注入 (转)

    关于DI 依赖注入, 转载这篇文章, 写得很好的. ----------------------------- DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关 ...

  9. DI容器Ninject在管理接口和实现、基类和派生类并实现依赖注入方面的实例

    当一个类依赖于另一个具体类的时候,这样很容易形成两者间的"强耦合"关系.我们通常根据具体类抽象出一个接口,然后让类来依赖这个接口,这样就形成了"松耦合"关系,有 ...

随机推荐

  1. CYPRESS USB芯片win10驱动

    The ZIP file attached with this knowledge base article contains the CyUSB3.inf and CyUSB3.sys files ...

  2. if..... if..... 和if..... else if.....

    曾经一度认为没有区别,,在有的时候是没有区别的,,但是有些时候则不可相互替换 这两个是有区别的 if..... if..... 是不相关的.只要各自判断两部分的条件即可,两个都会执行 if.... e ...

  3. Android Studio SVN使用和VisualSVN-Server配置(图解)

    转载请标明出处: http://blog.csdn.net/zq2114522/article/details/51078544: 本文出自:[梁大盛的博客] Android Studio SVN使用 ...

  4. [RxJS] Conclusion: when to use Subjects

    As a conclusion to this course about RxJS subjects, let's review when and why should you use them. F ...

  5. android 应用内部获取本应用或者相应包名的应用的SHA1签名的办法

    我这个人比較懒.每次做的都是心血来潮,所以打算改掉这个坏毛病.昨晚非常晚才睡,躺在床上一直在回忆.这两年来,我以前的目标是什么,我放弃了什么,我完毕了什么. 结果目标非常多,也放弃了一些. 完毕的差点 ...

  6. ZOJ FatMouse' Trade 贪心

    得之我幸,不得,我命.仅此而已. 学姐说呀,希望下次看到你的时候依然潇洒如故.(笑~) 我就是这么潇洒~哈哈. 感觉大家比我还紧张~ 我很好的.真的 ------------------------- ...

  7. Ubuntu12.04LTS SDK无法更新

    1.打开终端输入sudo gedit /etc/hosts 加入下面 2.加入下列文字到文件里:       203.208.46.146 dl.google.com       203.208.46 ...

  8. VS(Visual Studio)自动创建的文件格式

    .sln:solution,解决方案文件: .vsxproj:解决方案下的项目文件: .vssettings:环境设置文件, 菜单栏 ⇒ [工具]⇒ [导入和导出设置]⇒ 进行环境设置的导入和导出操作 ...

  9. kali 系统的源

    sources.list deb http://http.kali.org/kali kali-rolling main non-free contrib deb http://mirrors.ust ...

  10. [React Native] Writing Platform-Specific Components for iOS and Android in React Native

    Learn to write components that render differently on iOS and Android, but present the same API. Firs ...