利用.net Core 对程序集中的类 进行统一依赖注入
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 对程序集中的类 进行统一依赖注入的更多相关文章
- 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 ...
- NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
.NET Core 控制台程序没有 ASP.NET Core 的 IWebHostBuilder 与 Startup.cs ,那要读 appsettings.json.注依赖.配日志.设 IOptio ...
- ASP.NET Core 中间件的使用(二):依赖注入的使用
写在前面 上一篇大家已经粗略接触了解到.NET Core中间件的使用:ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件, .NET Core框架中很多核心对象都是通过依 ...
- ASP.NET Core 6框架揭秘实例演示[05]:依赖注入基本编程模式
毫不夸张地说,整个ASP.NET Core就是建立在依赖注入框架之上的.ASP.NET Core应用在启动时构建管道所需的服务,以及管道处理请求使用到的服务,均来源于依赖注入容器.依赖注入容器不仅为A ...
- ASP.NET Core 6框架揭秘实例演示[06]:依赖注入框架设计细节
由于依赖注入具有举足轻重的作用,所以<ASP.NET Core 6框架揭秘>的绝大部分章节都会涉及这一主题.本书第3章对.NET原生的依赖注入框架的设计和实现进行了系统的介绍,其中设计一些 ...
- ASP.NET Core中使用自定义MVC过滤器属性的依赖注入
除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...
- .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...
- 把旧系统迁移到.Net Core 2.0 日记(3) - 详解依赖注入 (转)
关于DI 依赖注入, 转载这篇文章, 写得很好的. ----------------------------- DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关 ...
- DI容器Ninject在管理接口和实现、基类和派生类并实现依赖注入方面的实例
当一个类依赖于另一个具体类的时候,这样很容易形成两者间的"强耦合"关系.我们通常根据具体类抽象出一个接口,然后让类来依赖这个接口,这样就形成了"松耦合"关系,有 ...
随机推荐
- [WASM] Read WebAssembly Memory from JavaScript
We use an offset exporting function to get the address of a string in WebAssembly memory. We then cr ...
- [WASM] Call a JavaScript Function from WebAssembly
Using WASM Fiddle, we show how to write a simple number logger function that calls a consoleLog func ...
- svn 清理失败 (clean up 失败) 的解决方法
解决方法: step1: 到 sqlite官网 (http://www.sqlite.org/download.html) 下载 sqlite3.exe 找到 Precompiled Binaries ...
- sublime课程3 emmet插件中的常用符号有哪些
sublime课程3 emmet插件中的常用符号有哪些 一.总结 一句话总结:emmet插件中的符号和css选择器里面哪些符号的意思很像. 1.+是干嘛的? 组合 2.{}是干嘛的? 标签里面的inn ...
- CSS Sprite的相关概念
原文 简书原文:https://www.jianshu.com/p/8ae3be23a642 大纲 1.什么是CSS Sprite 2.CSS Sprite的优点 3.CSS Sprite的缺点 4. ...
- 实现拖拽上传文件的一款小控件——dropzone
由于专注所以专业.非常多小巧的东西乍一看非常不起眼,却在特定的领域表现不俗,就是由于集中了热情. dropzone就是这样一款小控件,实现拖拽上传.它不依赖于其他像jquery等JS库.并且支持多方面 ...
- ios开发之Quartz2D 四:画饼图
#import "PieView.h" @implementation PieView - (void)drawRect:(CGRect)rect { // Drawing cod ...
- ios开发之手势处理 之手势识别一
#import "ViewController.h" @interface ViewController ()<UIGestureRecognizerDelegate> ...
- 200行代码,7个对象——让你了解ASP.NET Core框架的本质
原文:200行代码,7个对象--让你了解ASP.NET Core框架的本质 2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘&g ...
- web项目开启日志打印
原文链接:http://blog.csdn.net/qq_37936542/article/details/79045188 参考文章地址:点击打开链接,写的很清晰 一:导入log4j包或依赖 ...