4.6 .net core依赖注入的封装
现在流行的系统一般都采用依赖注入的实现方式,利用DI容器来直接获取所用到的类/接口的实例。.net core也一样采用DI的方式,提供了DI容器的接口IServiceCollection,并提供了基于该接口的缺省实现ServiceCollection。
这样我们就可以不再像以前一样,需要引入第三方的Untiy、Autofac、Castle等DI组件了。
在.net core源码的ServiceCollectionExtensions的实现中,有三个注册的方法AddScoped、AddSingleton、AddTransient。这其中的三个选项(Singleton、Scoped和Transient)体现三种对服务对象生命周期的控制形式。
- Singleton:ServiceProvider创建的服务实例保存在作为根节点的ServiceProvider上,所有具有同一根节点的所有ServiceProvider提供的服务实例均是同一个对象。适合于单例模式。
- Scoped:ServiceProvider创建的服务实例由自己保存,所以同一个ServiceProvider对象提供的服务实例均是同一个对象。 可以简单的认为是每请求(Request)一个实例。
- Transient:针对每一次服务提供请求,ServiceProvider总是创建一个新的服务实例。 每次访问时被创建,适合轻量级的,无状态的服务。
这个具体说起来就太多了,还是查阅相关材料吧J
有了DI容器,我们在使用时,可以简单的在Startup.cs程序中编写上注册语句,下面以操作日志的仓储类为例:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IOperLogRepository, OperLogRepository>();
}
第一个泛型类型表示将要从容器中请求的类型(通常是一个接口)。第二个泛型类型表示将由容器实例化并且用于完成这些请求的具体类型。
我们在操作日志的逻辑服务类使用操作日志的仓储时,就这样写:
public partial class OperLogAppService : IOperLogAppService
{
private IOperLogRepository service; public OperLogAppService(IOperLogRepository service)
{
this.service = service;
} public void Write(OperLogDto operLogDto)
{
this.service.Insert(operLogDto.AsInfo());
}
}
系统会在创建OperLogAppService的实例时,会自动创建IOperLogRepository在DI容器中注册OperLogRepository类的实例。
然而这种方式在框架中是有些不方便的。我们知道,框架要求的是可扩展,可配置,在新增系统功能模块时,还需要手工修改程序,在Startup.cs的ConfiguraeService中增加注册(就算把所有注册移到一个独立的方法中也是一样),就如同第一个代码写的一样,包括注册仓储类、注册逻辑服务类等等。然后编译,再发布运行。每增加、修改一个模块,都需要整个系统编译、发布,对运行中的系统影响还是挺大的。
我们的做法是,功能模块都有一个自注册的类。这个自注册的类会将功能模块中所有的仓储类、逻辑服务类等都注册进DI容器中。Startup.cs会自动查找所有功能模块中的自注册类,然后将相关内容注册进DI容器中。这样就可以做到,每增加一个模块,只需要将该模块的应用程序集Dll复制到系统的运行目录就行了,其他的系统帮你搞定。
按照上述思路,首先是建一个自注册的类。这个类都抽象出一个接口IServiceRegister
public interface IServiceRegister
{
/// <summary>
/// 注册
/// </summary>
void Register(IServiceCollection services);
}
我们以通用模块为例子,自注册的类应该是这样的。
public class CommonServiceRegister : IServiceRegister
{
public void Register(IServiceCollection services)
{
services.AddDbContext<CommonDbContext>(option => option.UseDb<CommonDbContext>(services.BuildServiceProvider()), ServiceLifetime.Scoped); services.AddScoped<IParaReferRepository, ParaReferRepository>();
services.AddScoped<IParaReferAppService, ParaReferAppService>();
services.AddScoped<ISystemParameterRepository, SystemParameterRepository>();
services.AddScoped<ISystemParameterAppService, SystemParameterAppService>();
…
}
}
这个类中service.AppScoped注册的是仓储层和逻辑层接口对应的实现类,我们这里只是列出了系统参数和引用参数的注册。对于第一句AddDbContext,请参见:4.4 异构、多数据库的存取组件
为了在Startup.cs中自己查找并调用这些注册类,还是比较简单的,程序如下:调用ReflectionHelper的GetSubTypes方法,获取所有继承IServiceRegister的实现类,对于每个实现类,创建实例并将模块的仓储和逻辑服务注册到DI容器中。ReflectionHelper的GetSubTypes方法,请参见:4.1 反射工具
IEnumerable<Type> serviceList = ReflectionHelper.GetSubTypes<IServiceRegister>();
foreach (Type type in serviceList)
{
IServiceRegister register = ReflectionHelper.CreateInstance(type) as IServiceRegister; register.Register(services);
}
.net framework也可以按照上述思路进行,不同的就是.net framework没有startup.cs,只需要将上面的内容写进global.asax即可,还有一点不同是IServiceCollection,可以使用Unity等DI组件提供的DI容器。
面向云的.net core开发框架
4.6 .net core依赖注入的封装的更多相关文章
- 实现BUG自动检测 - ASP.NET Core依赖注入
我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...
- [译]ASP.NET Core依赖注入深入讨论
原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...
- 自动化CodeReview - ASP.NET Core依赖注入
自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 我个人比较懒,能自动做的事绝 ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- .NET Core依赖注入集成Dynamic Proxy
在<Castle DynamicProxy基本用法>中介绍了如何将DP与Autofac集成使用,而 .NET Core有自己的依赖注入容器,在不依赖第三方容器的基础上,如何实现动态代理就成 ...
- ASP.NET Core依赖注入系统学习教程:关于服务注册使用到的方法
在.NET Core的依赖注入框架中,服务注册的信息将会被封装成ServiceDescriptor对象,而这些对象都会存储在IServiceCollection接口类型表示的集合中,另外,IServi ...
- # ASP.NET Core依赖注入解读&使用Autofac替代实现
标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...
- net core 依赖注入问题
net core 依赖注入问题 最近.net core可以跨平台了,这是一个伟大的事情,为了可以赶上两年以后的跨平台部署大潮,我也加入到了学习之列.今天研究的是依赖注入,但是我发现一个问题,困扰我很久 ...
- NET Core依赖注入解读&使用Autofac替代实现
NET Core依赖注入解读&使用Autofac替代实现 标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. ...
随机推荐
- (转载) RESTful API 设计指南
作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...
- Centos 7 vsftpd ldap 配置
#ldap 安裝配置 环境Centos7#安装 yum install -y openldap openldap-clients openldap-servers migrationtools pam ...
- JavaScript中的this
本文尽量避免概念性的讲解,那样太抽象 所以下面以一些简单的例子,从易到难对this的用法总结 1.方法中的this会指向当前执行该方法的对象 如: var name = "window&qu ...
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
- win7,Mindmanager2012使用模板时弹出Runtime error R6025解决方法
Mindjet.MindManager2012.v10.0在应用个别模板时提示"参数错误",然后自动关闭. 解决办法: 如果是win7系统,可以进入C:\Users\(用户名)\A ...
- 关于VS2015支持编译Linux程序的问题
现状 目前已经发布的VS2015中包括VS2015 Preview 以及 VS2015 CTP6,这两个版本均不支持直接编译C++代码为Linux程序,具体情况可以参考 Visual Studio 2 ...
- P/Invoke:C#调用C++
P/Invoke的全称是Platform Invoke (平台调用) 它实际上是一种函数调用机制通 过P/Invoke我们就可以调用非托管DLL中的函数. P/Invoke依次执行以下操作: 1. 查 ...
- ABP源码分析四十六:ABP ZERO中的Ldap模块
通过AD作为用户认证的数据源.整个管理用户认证逻辑就在LdapAuthenticationSource类中实现. LdapSettingProvider:定义LDAP的setting和提供Defaut ...
- node入门学习1
一个普通网站访问过程(1)浏览器向服务器发出一个HTTP请求(2)域名解析为IP地址(3)建立TCP连接(4)浏览器发起HTTP请求(5)服务器接收到HTTP请求,解析请求的路径和参数 出现乱码的原因 ...
- 在thinkPHP3.2.3框架下实现手机和PC端浏览器的切换
查看thinkphp版本号方法 打开文件“根目录\ThinkPHP\ThinkPHP.php”下的文件ThinkPHP.php,在22--23行可以看到版本信息THINK_VERSION,如下图: 说 ...