更优雅的在 Xunit 中使用依赖注入
Xunit.DependencyInjection 7.0 發(fā)布了
Intro
上次我們已經(jīng)介紹過一次大師的 Xunit.DependencyInjection??在 Xunit 中使用依賴注入?,最近大師完成了 7.0 的重構(gòu)并且已經(jīng)正式發(fā)布,已經(jīng)可以直接安裝使用了
7.0 為我們帶來了更好的編程體驗(yàn),在 6.x 的版本中,我們的 Startup 需要繼承于 DependencyInjectionTestFramework 而且需要設(shè)置一個(gè) 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)} }移除了?TestFramework assembly attribute
不再需要繼承于 DependencyInjectionTestFramework
也因?yàn)樯厦娴牟恍枰^承,所以原本要 override 的方法可以不 override 了,原來是 protected 的方法現(xiàn)在需要改成 public
新的 Startup 解析
我把上一篇文章寫的示例用升級到了新的版本,下面是更新后的示例代碼
namespace?XUnitDependencyInjectionSample {public?class?Startup{//?自定義?HostBuilder?,可以沒有這個(gè)方法,沒有這個(gè)方法會使用默認(rèn)的?hostBuilder,通常直接使用?`ConfigureHost`?應(yīng)該就夠用了//?public?IHostBuilder?CreateHostBuilder()//?{//?????return?new?HostBuilder()//?????????.ConfigureAppConfiguration(builder?=>//?????????{//?????????????//?注冊配置//?????????????builder//?????????????????.AddInMemoryCollection(new?Dictionary<string,?string>()//?????????????????{//?????????????????????{"UserName",?"Alice"}//?????????????????})//?????????????????.AddJsonFile("appsettings.json")//?????????????????;//?????????})//?????????.ConfigureServices((context,?services)?=>//?????????{//?????????????//?注冊自定義服務(wù)//?????????????services.AddSingleton<IIdGenerator,?GuidIdGenerator>();//?????????????if?(context.Configuration.GetAppSetting<bool>("XxxEnabled"))//?????????????{//?????????????????services.AddSingleton<IUserIdProvider,?EnvironmentUserIdProvider>();//?????????????}//?????????})//?????????;//?}//?自定義?host?構(gòu)建public?void?ConfigureHost(IHostBuilder?hostBuilder){hostBuilder.ConfigureAppConfiguration(builder?=>{//?注冊配置builder.AddInMemoryCollection(new?Dictionary<string,?string>(){{"UserName",?"Alice"}}).AddJsonFile("appsettings.json");}).ConfigureServices((context,?services)?=>{//?注冊自定義服務(wù)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>();}//?可以添加要用到的方法參數(shù),會自動從注冊的服務(wù)中獲取服務(wù)實(shí)例,類似于?asp.net?core?里?Configure?方法public?void?Configure(IServiceProvider?applicationServices,?IIdGenerator?idGenerator){//?有一些測試數(shù)據(jù)要初始化可以放在這里//?InitData();}} }在新的版本中 Startup 和 asp.net core 里的 Startup 更加相像了,
會多一個(gè) CreateHostBuilder/ConfigureHost(IHostBuilder) 的方法,允許用戶自定義 Host 的構(gòu)建,也可以沒有這個(gè)方法
ConfigureServices 方法允許用戶增加 HostBuilderContext 作為參數(shù),可以通過 hostBuilderContext 來獲取配置信息,也可以在 CreateHostBuilder/ConfigureHost(IHostBuilder) 里注冊也是一樣的
注冊配置/服務(wù)和 asp.net core 里一模一樣,有數(shù)據(jù)或配置需要在項(xiàng)目啟動時(shí)初始化的,可以放在 Configure ?方法做,有點(diǎn)類似于 asp.net core 里 Startup 中的 Configure 方法,可以將需要的服務(wù)作為方法參數(shù),執(zhí)行時(shí)會自動從注冊的服務(wù)中獲取
Startup 的尋找方法
默認(rèn)的 Startup 通常是 ProjectName.Startup,通常在項(xiàng)目根目錄下創(chuàng)建一個(gè) Startup 是不需要配置的,如果不是或不起作用,可以參考下面 Startup 的尋找規(guī)則
如果要使用一個(gè)特別的 Startup, 你可以通過在項(xiàng)目文件的 PropertyGroup 部分定義 XunitStartupAssembly 和 XunitStartupFullName,具體規(guī)則如下
<Project><PropertyGroup><XunitStartupAssembly>Abc</XunitStartupAssembly><XunitStartupFullName>Xyz</XunitStartupFullName></PropertyGroup> </Project>| Your.Test.Project.Startup, Your.Test.Project | ||
| Abc | Abc.Startup, Abc | |
| Xyz | Xyz, Your.Test.Project | |
| Abc | Xyz | Xyz, Abc |
More
除了上面的 Startup 的改動之外,新版本還支持了 xunit 中 fixture 的依賴注入,似乎是由一個(gè)外國小哥提的 PR, 詳見:https://github.com/pengweiqhca/Xunit.DependencyInjection/pull/21
有了這個(gè)神器,在測試代碼中使用依賴注入要方便很多了,還沒有用起來的可以準(zhǔn)備上手了~~
Reference
https://github.com/pengweiqhca/Xunit.DependencyInjection
https://github.com/WeihanLi/SamplesInPractice/tree/master/XUnitDependencyInjectionSample
總結(jié)
以上是生活随笔為你收集整理的更优雅的在 Xunit 中使用依赖注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core Blazor
- 下一篇: 三分钟Docker-环境搭建篇