Netcore中实现字段和属性注入
https://www.cnblogs.com/loogn/p/10566510.html
简单来说,使用Ioc模式需要两个步骤,第一是把服务注册到容器中,第二是从容器中获取服务,我们一个一个讨论并演化。这里不会考虑使用如Autofac等第三方的容器来代替默认容器,只是提供一些简单实用的小方法用于简化应用层的开发。
将服务注入到容器
asp.netcore官方给出的在容器中注册服务方法是,要在Startup类的ConfigureServices方法中添加服务,如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton(typeof(UserService));
services.AddSingleton(typeof(MsgService));
services.AddSingleton(typeof(OrderService));
}
AddMvc方法添加了mvc模块内部用到的一些服务,这个是封装好的,一句话就行了,其他第三方组件也都提供了类似的Add方法,把自己内部需要的服务都封装好注册进去了。但是我们应用开发人员使用的类,还是需要一个一个写进去的,大家最常见的三层架构中的数据访问层和业务逻辑层便是此类服务,上面代码中我加入了三个业务服务类。这显然不是长久之计,我想大家在开发中也会针对此问题做一些处理,这里说下我的,仅供参考吧。
解决方法就是批量注册!说到批量,就需要一个东西来标识一批东西,然后用这一个东西来控制这一批东西。在.net程序的世界中,有两个可选的角色,一个是接口Interface,另一个是特性Attribute。
如果使用接口作为标识来使用,限制就太死板了,一个标识的信息不是绝对的单一,是不推荐使用接口的,因为可能需要引入多个接口才能共同完成,所以我选择特性作为标识。特性相较与接口有什么特点呢?特性在运行时是类的实例,所以可以存储更多的信息。
下面我们简单实现一个AppServiceAttribute:
/// <summary>
/// 标记服务
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AppServiceAttribute : Attribute
{
}
这个特性类取名AppService有两个理由,一是指定是应用层的服务类,二是避免使用Service这样的通用命名和其他类库冲突。
有了标识,就可以批量处理了,我们在一个新的类中给IServiceCollection提供一个扩展方法,用来批量添加标记有AppService特性的服务到容器中。
public static class AppServiceExtensions
{
/// <summary>
/// 注册应用程序域中所有有AppService特性的服务
/// </summary>
/// <param name="services"></param>
public static void AddAppServices(this IServiceCollection services)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
var serviceAttribute = type.GetCustomAttribute<AppServiceAttribute>();
if (serviceAttribute != null)
{
services.AddSingleton(type);
}
}
}
}
}
我们遍历应用程序中所有程序集,然后嵌套遍历每个程序集中的所有类型,判断类型是否有AppService特性,如果有的话就添加到容器中,这里有点不自信哦,为什么呢,因为我是使用AddSingleton方法以单例模式将服务添加到容器中的,虽然三层中的数据访问层和业务逻辑层绝大部分都可以使用单例,但是我们希望更通用一些,大家都知道netcore自带的Ioc容器支持三种生命周期,所以我们修改AppServiceAttribute,添加一个Lifetime属性:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AppServiceAttribute : Attribute
{
/// <summary>
/// 生命周期
/// </summary>
public ServiceLifetime Lifetime { get; set; } = ServiceLifetime.Singleton;
}
Lifetime的默认值我们设置成ServiceLifetime.Singleton是比较合适的,因为大部分服务我们都希望使用单例注册,一个合理的默认设置可以节省使用者很多代码,新手可能还会乐于复制粘贴,但老同志肯定都深有体会。
有了Lifetime这个信息,我们就可以改进AddAppServices方法了,在判断serviceAttribute不为null后,使用下面的代码替换services.AddSingleton(type):
switch (serviceAttribute.Lifetime)
{
case ServiceLifetime.Singleton:
services.AddSingleton(serviceType, type);
break;
case ServiceLifetime.Scoped:
services.AddScoped(serviceType, type);
break;
case ServiceLifetime.Transient:
services.AddTransient(serviceType, type);
break;
default:
break;
}
现在我们可以注册不同生命周期的服务了,只是该控制是在类的定义中,按理说,服务对象注册到容器中的生命周期,是不应该在类的定义中确定的,因为一个类的定义是独立的,定义好之后,使用者可以用任何一种容器支持的生命周期来注册实例。但是此时这样的设计是比较合理的,因为我们要解决的是应用层服务的批量注册,这类服务一般在定义的时候就已经确定了使用方式,而且很多时候服务的开发者就是该服务的使用者!所以我们可以把这个当成合理的反范式设计。
目前这样子,对于我来说,基本已经够用了,因为在应用层,我都是依赖实现编程的
Netcore中实现字段和属性注入的更多相关文章
- 在netcore中实现字段和属性注入
简单来说,使用Ioc模式需要两个步骤,第一是把服务注册到容器中,第二是从容器中获取服务,我们一个一个讨论并演化.这里不会考虑使用如Autofac等第三方的容器来代替默认容器,只是提供一些简单实用的小方 ...
- C#中的字段与属性的区别及属性的作用
C#中的字段与属性的区别及属性的作用 先上代码 public class Employee { //字段 private string name; //属性 public string Name { ...
- C#类中的字段、属性和方法
C#类中的字段.属性和方法 刚开始学C#,对于类中的字段.属性和方法很难分清,写下这份笔记,帮助理解 字段:与类相关的变量 声明方法与声明变量类似,可在前面添加访问修饰符.static关键字等: 属性 ...
- ASP.NET Core中使用Autofac进行属性注入
一些无关紧要的废话: 作为一名双修程序员(自封的),喜欢那种使用Spring的注解形式进行依赖注入或者Unity的特性形式进行依赖注入,当然,形式大同小异,但结果都是一样的,通过属性进行依赖注入. A ...
- C#反射类中所有字段,属性,方法
可能大家都知道在C#中如何创建一个类,但对于类的结构可能大家不一定了解的很清楚,对于我来说,我之前也搞的不是很明白,今天,当我没事研究反射的时候突然发现了着一点.我们来看类的结构到底是什么 publi ...
- Java中的字段和属性
Java中的属性,通常可以理解为get和set方法.而字段,通常叫做“类成员”. 属性只局限于类中方法的声明,并不与类中其他成员相关.例如:void setA(String s){}String ge ...
- django中model字段与属性
model field 类型1.AutoField 一个自增的IntegerField,一般不直接使用,Django会自动给每张表添加一个自增的primary key. 2.BigIntege ...
- SQLSERVER获取数据库中的所有表的名称、表中所有字段的属性
1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...
- ms sql 根据表名查询 表中所有字段的属性值 sql语句
SELECT表名=case when a.colorder=1 then d.name else '' end,--表说明=case when a.colorder=1 then isnull(f.v ...
随机推荐
- Java 访问 Kylin 总结
这次开发功能是OEM统计报表.统计报表的数据由大数据平台部的同事收集,数据的展示由我们部门开发. 大数据那边使用 Kylin 分布式分析引擎(kylin官方文档). Kylin 虽比较偏向大数据相关, ...
- IO流框架关系总结(关系图)
字节流和字符流关系图 打印流和序列化流关系图
- 10.model/view实例(2)
任务:显示一个2x3的表格,将表格中的数据显示如下: 思考: 1.如何显示数据和上个例子一样. 2.但是每个单元格的数据都是有角色划分的. Qt::ItemDataRole 3.View从Model中 ...
- format Code
setting中设置format code. 方便格式化代码.
- java后台对json格式数据的解析
Json 和 Jsonlib 的使用 什么是 Json JSON(JvaScript Object Notation)(官网网站:http://www.json.org/)是 一种轻量级的数据交换格式 ...
- Netty学习大纲
1.BIO.NIO和AIO2.Netty 的各大组件3.Netty的线程模型4.TCP 粘包/拆包的原因及解决方法5.了解哪几种序列化协议?包括使用场景和如何去选择6.Netty的零拷贝实现7.Net ...
- [raspberry pi3] zram设置
linux 3.15之后添加了个和mac一样的功能,内存压缩zram, 之前还有个zswap, zram通常是以模块的方式被放在系统里面的,以便在可以根据需求的不同,定制化加载. raspberry ...
- 添加节点至XML文档中去
不管是<怎样创建XML文档> http://www.cnblogs.com/insus/p/3276944.html还是<泛型List<T>转存为XML文档> ht ...
- poj1195(二维树状数组)
题目链接:https://vjudge.net/problem/POJ-1195 题意:有s*s的矩阵,初始化为全0,有两种操作,单点修改(x,y)的值,区间查询(x,y)的值(l<=x< ...
- PL/0语言词法分析器
前言:关于词法分析的基础知识的介绍可以看一下这篇博客,我再累述估计也不会有这篇讲的清楚QAQ. https://www.cnblogs.com/yanlingyin/archive/2012/04/1 ...