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)
}
}
  1. 移除 TestFramework assembly attribute
  2. 不再需要继承于 DependencyInjectionTestFramework
  3. 也因为上面的不需要继承,所以原本要 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 部分定义 XunitStartupAssemblyXunitStartupFullName,具体规则如下

<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

更优雅的在 Xunit 中使用依赖注入的更多相关文章

  1. 在 XUnit 中使用依赖注入

    在 XUnit 中使用依赖注入 Intro 之前写过一篇 xunit 的依赖注入相关的文章,但是实际使用起来不是那么方便 今天介绍一个基于xunit和微软依赖注入框架的"真正"的依 ...

  2. 在 xunit 测试项目中使用依赖注入

    在 xunit 测试项目中使用依赖注入 Intro 之前写过几篇 xunit 依赖注入的文章,今天这篇文章将结合我在 .NET Conf 上的分享,更加系统的分享一下在测试中的应用案例. 之所以想分享 ...

  3. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  4. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  5. Spring学习(一)——Spring中的依赖注入简介【转】

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  6. 转: 理解AngularJS中的依赖注入

    理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS依赖注入系统是如何运行的. Prov ...

  7. 理解AngularJS中的依赖注入

    点击查看AngularJS系列目录 理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS ...

  8. ABP中的依赖注入思想

    在充分理解整个ABP系统架构之前首先必须充分了解ABP中最重要的依赖注入思想,在后面会具体举出一些实例来帮助你充分了解ABP中的依赖注入思想,在了解这个之前我们首先来看看什么是依赖注入?来看看维基百科 ...

  9. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)

    相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...

随机推荐

  1. ca70a_c++_重载函数_实参类型转换

    /*ca70a_c++_重载函数_实参类型转换转换等级,详见P290 编译选择哪个函数版本呢?1.精确匹配2.通过类型提升3.通过标准转换4.通过类类型转换参数匹配和枚举类型重载和const形参 vo ...

  2. 资料共享-源代码-视频教程-PLC-OpenCV-C++-MFC

    资料共享-源代码-视频教程-PLC-OpenCV-C++-MFC 资料共享-源代码-视频教程 资料共享-源代码-视频教程-PLC-OpenCV-C++-MFC

  3. MFC套接字连接不成功-记得在app的cpp文件里面初始化套接字

    MFC套接字连接不成功-记得在app的cpp文件里面初始化套接字 stdafx.h文件中添加:#include "afxsock.h" BOOL CMFC_TCP_Client_c ...

  4. vs.net/vscode中使用Beetlex创建vue应用

    平时在开发Vue应用则需要安装nodejs,vue cli等相关东西相对来说麻烦一些:如果你喜欢像vs.net/vscode创建普通项目一样就能开发Vue项目的话那可以尝试一下BeetleX针对Vue ...

  5. 1.WebPack概念

    一.什么是WebPack 官方解释:本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构 ...

  6. 12.DRF-节流

    Django rest framework源码分析(3)----节流 添加节流 自定义节流的方法 限制60s内只能访问3次 (1)API文件夹下面新建throttle.py,代码如下: # utils ...

  7. 【解读】Https协议

    一.为什么需要https 1.HTTP是明文传输的,也就意味着,介于发送端.接收端中间的任意节点都可以知道你们传输的内容是什么.这些节点可能是路由器.代理等. 举个最常见的例子,用户登陆.用户输入账号 ...

  8. Spring IoC bean 的创建(上)

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 本篇文章主要介绍 Spring IoC 容 ...

  9. 【floyd+矩阵乘法】POJ 3613 Cow Relays

    Description For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a rel ...

  10. Oracle 11g各种服务作用以及哪些需要开启

    Windwos server 2012 R2上成功安装Oracle 11g后共有7个服务,如果全局数据库名为orcl,则Oracle服务分别为 Oracle ORCL VSSWriter Servic ...