.Net Core中依赖注入服务使用总结
一、依赖注入
引入依赖注入的目的是为了解耦和。说白了就是面向接口编程,通过调用接口的方法,而不直接实例化对象去调用。这样做的好处就是如果添加了另一个种实现类,不需要修改之前代码,只需要修改注入的地方将实现类替换。上面的说的通过接口调用方法,实际上还是需要去实例化接口的实现类,只不过不需要我们手动new 构造实现类,而是交给如微软的DI、Autofac这些工具去构建实现类。我们只需要告诉它们,某个类是某个接口的实现类,当用到的时候,工具会自动通过构造函数实例化类。
二、.Net Core中自带的DI
本来想写依赖注入源码的讲解的,看到网上有篇文章关于源码讲解的,很详细、清楚,就不再写了。地址:http://www.cnblogs.com/bill-shooting/p/5540665.html。我在这里就说说使用吧。
依赖注入有三种生命周期,每种生命周期的注入方式大同小异,下面我以作用域生命周期举例,其他两种跟这个不同,我会特别说明。
下面为用到的两个服务。
public class UserService : IUserService
{
public string GetName()
{
return "UserName";
}
} public interface IUserService
{
string GetName();
}
public class ConfigReader : IConfigReader
{
private string configFilePath;//需要传一个路径,去读取路径下文件的内容
public ConfigReader(string configFileName)
{
this.configFilePath = configFileName;
}
public string Reader()
{
return File.ReadAllText(configFilePath);
}
} public interface IConfigReader
{
string Reader();
}
1、最常用的注入方式,以接口形式暴露服务
services.AddScoped(typeof(IUserService), typeof(UserService));
services.AddScoped<IUserService, UserService>();
两种注入方式是一个意思,这种方式适合实现类为无参构造函数或者有参构造函数中参数已经被注入过了。
2、自己注入自己,以实现形式暴露服务
services.AddScoped<UserService>();
services.AddScoped(typeof(UserService));
这种注入方式适合只有实现类,没有借口类的注册。
3、需要传参的构造函数的类的注入
services.AddScoped<IConfigReader, ConfigReader>(x => { return new ConfigReader("c:/a.txt"); });
services.AddScoped<IConfigReader>(x => { return new ConfigReader("c:/a.txt"); });
services.AddScoped(typeof(IConfigReader), x => { return new ConfigReader("c:/a.txt"); });
前两个匿名方法参数是IServiceProvider,返回值为一个实例,第三个返回值是Object。上面举的例子没有用到IServiceProvider ,下面再举一个例子。修改上面的UserService类,将构造方法需要一个IConfigReader参数。
public class UserService : IUserService
{private IConfigReader configReader; public UserService(IConfigReader configReader)
{
this.configReader = configReader;
}
public string GetName()
{
return "UserName" + configReader.Reader();
}
}
注册的时候,如下:
services.AddScoped<IConfigReader, ConfigReader>(x => { return new ConfigReader("c:/a.txt"); });
//通过ServiceProvider获取已经注册的IConfigReader
services.AddScoped<IUserService, UserService>(x => { return new UserService(x.GetService<IConfigReader>()); });
//或者
services.AddScoped<IUserService, UserService>(x => { return new UserService(new ConfigReader("c:/a.txt")); });
单例类型的生命周期多了两种注入方式:
services.AddSingleton<IConfigReader>(new ConfigReader("c:/a.txt"));
services.AddSingleton(typeof(IConfigReader), new ConfigReader("C:/a.txt"));
自带的依赖注入工具也可以批量注入
var assembly = Assembly.GetExecutingAssembly()
.DefinedTypes
.Where(a => a.Name.EndsWith("Service") && !a.Name.StartsWith("I")); foreach (var item in assembly)
{
services.AddTransient(item.GetInterfaces().FirstOrDefault(), item);
}
注意:当一个服务有多个实现时,调用的时候通过 IEnumerable<IPayService> PayServices 获取所有的实现服务。
services.AddTransient<IPayService, AliPayService>();
services.AddTransient<IPayService, WeChatPayService>();
使用的时候:

三、Autofac
1、以接口形式暴露服务
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var builder = new ContainerBuilder();
builder.Populate(services); builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope(); var container = builder.Build();
return new AutofacServiceProvider(container);
}
2、通过实现类暴露服务
builder.RegisterType<UserService>();
3、需要传参的构造函数的类的注入
builder.Register(c => new ConfigReader("c:/a.txt")).As<IConfigReader>();
4、通过程序集注入
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(c => c.Name.EndsWith("Service"))
.AsImplementedInterfaces();
总结:
不论是微软的依赖注入组件还是Autofac 原理都是先将接口和对应的实现类注入到容器中,当要使用的时候,组件会自动通过构造函数创建实例。这里有个问题如果有个实现类有多个构造函数,组件会找满足参数最多的那个构造函数。
.Net Core中依赖注入服务使用总结的更多相关文章
- .NET Core 中依赖注入框架详解 Autofac
本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的 Autofac相比.NET Core原生的注入方式提供了强大的功能, ...
- 用工厂模式解决ASP.NET Core中依赖注入的一个烦恼
这是最近在实际开发中遇到的一个问题,用 asp.net core 开发一个后端 web api ,根据指定的 key 清除 2 台 memcached 服务器上的缓存.背景是我们在进行 .net co ...
- .NET Core 中依赖注入 AutoMapper 小记
最近在 review 代码时发现同事没有像其他项目那样使用 AutoMapper.Mapper.Initialize() 静态方法配置映射,而是使用了依赖注入 IMapper 接口的方式 servic ...
- asp.net core 系列 3 依赖注入服务
一. 依赖注入概述 在软件设计的通用原则中,SOLID是非常流行的缩略语,它由5个设计原则的首字母构成:单一原则(S).开放封闭原则(O).里氏替换原则(L).接口分离原则(I).依赖反转原则(D). ...
- 在 ASP.NET Core 中执行租户服务
在 ASP.NET Core 中执行租户服务 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunna ...
- ASP.NET Core之依赖注入
本文翻译自:http://www.tutorialsteacher.com/core/dependency-injection-in-aspnet-core ASP.NET Core支持依赖注入,依赖 ...
- 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入
系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...
- 几十行代码实现ASP.NET Core自动依赖注入
在开发.NET Core web服务的时候,我们习惯使用自带的依赖注入容器来进行注入. 于是就会经常进行一个很频繁的的重复动作:定义一个接口->写实现类->注入 有时候会忘了写Add这一步 ...
- 重新整理 .net core 实践篇————依赖注入应用[二]
前言 这里介绍一下.net core的依赖注入框架,其中其代码原理在我的另一个整理<<重新整理 1400篇>>中已经写了,故而专门整理应用这一块. 以下只是个人整理,如有问题, ...
随机推荐
- 大话设计模式--原型模式 Prototype -- C++实现
1. 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象... 注意: 拷贝的时候是浅拷贝 还是 深拷贝, 来考虑是否需要重写拷贝构造函数. 关键在于: virtual Pro ...
- hdu 5475 线段树
An easy problem Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- jQuery ztree 自制一套 灰蓝皮肤
jQuery ztree 自制一套 灰蓝皮肤 PNG图片替换官方ztree下img文件中的png图片即可
- DIV+CSS专题:第一天 XHTML CSS基础知识
欢迎大家学习<十天学会web标准>,也就是我们常说的DIV+CSS.不过这里的DIV+CSS是一种错误的叫法,建议大家还是称之为web标准. 学习本系列教程需有一定html和css基础 ...
- Codeforces 366C Dima and Salad:背包dp
题目链接:http://codeforces.com/problemset/problem/366/C 题意: 有n个物品,每个物品有两个属性a[i]和b[i]. 给定k,让你选出一些物品,使得 ∑ ...
- NET 平台下的WebService 简单使用
一句话理解:提供可供外部访问的方法,实现跨平台访问 注意: 在客户端是添加“服务引用”,而不是引用 当服务端更新了服务之后,在客户端,一定也要“更新服务” 当要执行异常调用时,要在前台.aspx的头部 ...
- Java 时间和日期类型的 Hibernate 映射
以下情况下必须显式指定 Hibernate 映射类型 一个 Java 类型可能对应多个 Hibernate 映射类型. 例如: 如果持久化类的属性为 java.util.Date 类型, 对应的 Hi ...
- 2017-2018-1 20179203 《Linux内核原理与分析》第五周作业
攥写人:李鹏举 学号:20179203 ( 原创作品转载请注明出处) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...
- [HDU5290]Bombing plan
vjudge sol 树DP. 首先把模型转换成:每个点可以控制与它距离不超过\(w_i\)的点,先要求选出数量最少的点控制所有点. 设\(f[i][-100...100]\)表示\(i\)号点向上还 ...
- vue 常见的新增、编辑、查看公用同一个页面
用vue开发经常会碰到,一个功能的新增.编辑.查看公用同一个页面,如果是页面暂且不提. 但是弹框,很多人会发现,如果是点击编辑,取消,再点新增,弹框上面是会有残留数据的,为什么会这样呢,因为在点编辑的 ...