更优雅的在 Xunit 中使用依赖注入
Xunit.DependencyInjection 7.0 发布了
Intro
上次我们已经介绍过一次大师的 Xunit.DependencyInjection https://www.cnblogs.com/weihanli/p/xuint-dependency-injection.html ,最近大师完成了 7.0 的重构并且已经正式发布,已经可以直接安装使用了
7.0 为我们带来了更好的编程体验,在 6.x 的版本中,我们的 Startup 需要继承于 DependencyInjectionTestFramework 而且需要设置一个 assembly attribute,这在 7.0 中都不需要了,下面我们来看看有了哪些变化
Startup 的变化
首先来看大师给出的 diff
-[assembly: TestFramework("Your.Test.Project.Startup", "Your.Test.Project")]
namespace Your.Test.Project
{
- public class Startup : DependencyInjectionTestFramework
+ public class Startup
{
- public Startup(IMessageSink messageSink) : base(messageSink) { }
- protected void ConfigureServices(IServiceCollection services)
+ public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IDependency, DependencyClass>();
}
- protected override IHostBuilder CreateHostBuilder() =>
- base.CreateHostBuilder(assemblyName)
- .ConfigureServices(ConfigureServices);
- protected override void Configure(IServiceProvider provider)
+ public void Configure(IServiceProvider provider)
}
}
- 移除
TestFrameworkassembly attribute - 不再需要继承于
DependencyInjectionTestFramework - 也因为上面的不需要继承,所以原本要
override的方法可以不override了,原来是protected的方法现在需要改成public
新的 Startup 解析
我把上一篇文章写的示例用升级到了新的版本
需要实现自己的一个 Startup ,在 Startup 里进行服务注册和初始化
namespace XUnitDependencyInjectionSample
{
public class Startup
{
// 自定义 HostBuilder ,可以没有这个方法,没有这个方法会使用默认的 hostBuilder,通常直接使用 `ConfigureHost` 应该就够用了
// public IHostBuilder CreateHostBuilder()
// {
// return new HostBuilder()
// .ConfigureAppConfiguration(builder =>
// {
// // 注册配置
// builder
// .AddInMemoryCollection(new Dictionary<string, string>()
// {
// {"UserName", "Alice"}
// })
// .AddJsonFile("appsettings.json")
// ;
// })
// .ConfigureServices((context, services) =>
// {
// // 注册自定义服务
// services.AddSingleton<IIdGenerator, GuidIdGenerator>();
// if (context.Configuration.GetAppSetting<bool>("XxxEnabled"))
// {
// services.AddSingleton<IUserIdProvider, EnvironmentUserIdProvider>();
// }
// })
// ;
// }
// 自定义 host 构建
public void ConfigureHost(IHostBuilder hostBuilder)
{
hostBuilder
.ConfigureAppConfiguration(builder =>
{
// 注册配置
builder
.AddInMemoryCollection(new Dictionary<string, string>()
{
{"UserName", "Alice"}
})
.AddJsonFile("appsettings.json")
;
})
.ConfigureServices((context, services) =>
{
// 注册自定义服务
services.AddSingleton<IIdGenerator, GuidIdGenerator>();
if (context.Configuration.GetAppSetting<bool>("XxxEnabled"))
{
services.AddSingleton<IUserIdProvider, EnvironmentUserIdProvider>();
}
})
;
}
// 支持的形式:
// ConfigureServices(IServiceCollection services)
// ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
{
services.TryAddSingleton<CustomService>();
}
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
public void Configure(IServiceProvider applicationServices, IIdGenerator idGenerator)
{
// 有一些测试数据要初始化可以放在这里
// InitData();
}
}
}
在新的版本中 Startup 和 asp.net core 里的 Startup 更加相像了,
会多一个 CreateHostBuilder/ConfigureHost(IHostBuilder) 的方法,允许用户自定义 Host 的构建,也可以没有这个方法
ConfigureServices 方法允许用户增加 HostBuilderContext 作为参数,可以通过 hostBuilderContext 来获取配置信息,也可以在 CreateHostBuilder/ConfigureHost(IHostBuilder) 里注册也是一样的
注册配置/服务和 asp.net core 里一模一样,有数据或配置需要在项目启动时初始化的,可以放在 Configure 方法做,有点类似于 asp.net core 里 Startup 中的 Configure 方法,可以将需要的服务作为方法参数,执行时会自动从注册的服务中获取
Startup 的寻找方法
默认的 Startup 通常是 ProjectName.Startup,通常在项目根目录下创建一个 Startup 是不需要配置的,如果不是或不起作用,可以参考下面 Startup 的寻找规则
如果要使用一个特别的 Startup, 你可以通过在项目文件的 PropertyGroup 部分定义 XunitStartupAssembly 和 XunitStartupFullName,具体规则如下
<Project>
<PropertyGroup>
<XunitStartupAssembly>Abc</XunitStartupAssembly>
<XunitStartupFullName>Xyz</XunitStartupFullName>
</PropertyGroup>
</Project>
| XunitStartupAssembly | XunitStartupFullName | Startup |
|---|---|---|
| Your.Test.Project.Startup, Your.Test.Project | ||
| Abc | Abc.Startup, Abc | |
| Xyz | Xyz, Your.Test.Project | |
| Abc | Xyz | Xyz, Abc |
More
除了上面的 Startup 的改动之外,新版本还支持了 xunit 中 fixture 的依赖注入,这是由一个外国小哥提的 PR, 详见:https://github.com/pengweiqhca/Xunit.DependencyInjection/pull/21
有了这个神器,在测试代码中使用依赖注入要方便很多了,还没有用起来的可以准备上手了~~
Reference
- https://github.com/pengweiqhca/Xunit.DependencyInjection
- https://github.com/WeihanLi/SamplesInPractice/tree/master/XUnitDependencyInjectionSample
更优雅的在 Xunit 中使用依赖注入的更多相关文章
- 在 XUnit 中使用依赖注入
在 XUnit 中使用依赖注入 Intro 之前写过一篇 xunit 的依赖注入相关的文章,但是实际使用起来不是那么方便 今天介绍一个基于xunit和微软依赖注入框架的"真正"的依 ...
- 在 xunit 测试项目中使用依赖注入
在 xunit 测试项目中使用依赖注入 Intro 之前写过几篇 xunit 依赖注入的文章,今天这篇文章将结合我在 .NET Conf 上的分享,更加系统的分享一下在测试中的应用案例. 之所以想分享 ...
- 在WPF中使用依赖注入的方式创建视图
在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...
- Spring学习(一)——Spring中的依赖注入简介【转】
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- 转: 理解AngularJS中的依赖注入
理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS依赖注入系统是如何运行的. Prov ...
- 理解AngularJS中的依赖注入
点击查看AngularJS系列目录 理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS ...
- ABP中的依赖注入思想
在充分理解整个ABP系统架构之前首先必须充分了解ABP中最重要的依赖注入思想,在后面会具体举出一些实例来帮助你充分了解ABP中的依赖注入思想,在了解这个之前我们首先来看看什么是依赖注入?来看看维基百科 ...
- 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)
相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...
随机推荐
- 【JMeter_12】JMeter逻辑控制器__包括控制器<Include Controller>
包括控制器<Include Controller> 业务逻辑: 通过Filename的路径和文件名引用外部的jmx文件,然后对齐执行,若外部文件中没有可执行范围内的脚本内容,则跳过该逻辑控 ...
- Centos7 composer安装时 Warning: This development build of composer is over 60 days old. It is recommended to update it by running "/usr/bin/composer self-update" to get the latest version.
emmm,其实就是想让你运行一下/usr/bin/composer self-update这个命令更新一下
- Andrew Ng - 深度学习工程师 - Part 1. 神经网络和深度学习(Week 3. 浅层神经网络)
=================第3周 浅层神经网络=============== ===3..1 神经网络概览=== ===3.2 神经网络表示=== ===3.3 计算神经网络的输出== ...
- Shiro简单加密服务
编码/加密 在涉及到密码存储问题上,应该加密 / 生成密码摘要存储,而不是存储明文密码.比如之前的 600w csdn 账号泄露对用户可能造成很大损失,因此应加密 / 生成不可逆的摘要方式存储. Sh ...
- skywalking中表字段的信息
https://skyapm.github.io/document-cn-translation-of-skywalking/zh/6.2.0/concepts-and-designs/scope-d ...
- 02【熟悉】springboot和微服务的介绍
1,springboot简介 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程. 该框架使用了特定的方式来进行配置,从 ...
- C#/VB.NET 在PDF中添加文件包(Portfolio)
PDF文件包(Portfolio)允许用户将多种不同类型的文件如Word.Excel.PDF.PowerPoint和图片等集合到一个PDF文件中,用户可以打开.更改PDF文件包中的单个文件.添加文件包 ...
- 【Xamarin.Forms 3】页面类型
系列目录 微信 1.[Xamarin.Forms 1]App的创建与运行 2.[Xamarin.Forms 2]App基础知识与App启动 知乎 1.[Xamarin.Forms 1]App的创建与运 ...
- python数据类型的72变
输入数据的类型 input函数接收的数据默认为字符串类型 转换函数 通过转换函数实现接收其他类型的数据 1.接收整数:字符串→整型数据: int("整数格式的字符串") 2.接收小 ...
- Alink漫谈(十) :特征工程 之 特征哈希/标准化缩放
Alink漫谈(十) :特征工程之特征哈希/标准化缩放 目录 Alink漫谈(十) :特征工程之特征哈希/标准化缩放 0x00 摘要 0x01 相关概念 1.1 特征工程 1.2 特征缩放(Scali ...