1. 程式人生 > 實用技巧 >HTML5中修改表單驗證預設提示語句

HTML5中修改表單驗證預設提示語句

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