|
|
namespace SemanticKernelStudy.Test;
|
|
|
|
|
|
/// <summary>
|
|
|
/// xUnit:依赖注入框架(Xunit.DependencyInjection)的启动类
|
|
|
/// 1、执行顺序按照方法代码书写顺序执行(BuildHost有点特殊
|
|
|
/// 2、两种风格任选其一即可:同时存在,则HostApplicationBuilder风格优先,Startup风格的方法会被忽略
|
|
|
/// 3、两种风格都支持Configure方法:都会在最后执行
|
|
|
/// 4、一次测试中,只执行一次(无论一次测试执行了多少个单元测试)
|
|
|
/// </summary>
|
|
|
public class Startup
|
|
|
{
|
|
|
#region HostApplicationBuilder 风格
|
|
|
/*
|
|
|
/// <summary>
|
|
|
/// 必须:主配置方法
|
|
|
/// 1、用本方法区分两种风格:本方法优先,如果存在本方法,则忽略Startup风格的方法
|
|
|
/// </summary>
|
|
|
/// <param name="hostApplicationBuilder"></param>
|
|
|
public void ConfigureHostApplicationBuilder(IHostApplicationBuilder hostApplicationBuilder)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 可选:生成IHost主机,只在异常时需要此方法
|
|
|
/// 在程序因找不到此方法签名异常时,只需添加本方法,并调用 hostApplicationBuilder.Build() 即可构建主机。
|
|
|
/// </summary>
|
|
|
/// <param name="hostApplicationBuilder"></param>
|
|
|
/// <returns></returns>
|
|
|
public IHost BuildHostApplicationBuilder(HostApplicationBuilder hostApplicationBuilder)
|
|
|
{
|
|
|
return hostApplicationBuilder.Build();
|
|
|
}
|
|
|
*/
|
|
|
#endregion
|
|
|
|
|
|
#region Startup 风格
|
|
|
|
|
|
/// <summary>
|
|
|
/// 可选:创建HostBuilder
|
|
|
/// 主要用于Minimal API场景,需导入Xunit.DependencyInjection.AspNetCoreTesting包
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public IHostBuilder CreateHostBuilder(System.Reflection.AssemblyName assemblyName)
|
|
|
{
|
|
|
// minimal API testing, see details: https://github.com/pengweiqhca/Xunit.DependencyInjection#minimalapi
|
|
|
// return MinimalApiHostBuilderFactory.GetHostBuilder<Program>();
|
|
|
|
|
|
//通用方式:可以省略本方法
|
|
|
IHostBuilder hostBuilder = new HostBuilder();
|
|
|
//IHostBuilder hostBuilder = Host.CreateDefaultBuilder();
|
|
|
|
|
|
//注入(先执行):主机 IConfiguration
|
|
|
hostBuilder.ConfigureHostConfiguration(config =>
|
|
|
{
|
|
|
//config.AddJsonFile($"{assemblyName}.json");
|
|
|
});
|
|
|
|
|
|
//注入(后执行):应用 IConfiguration
|
|
|
hostBuilder.ConfigureAppConfiguration((context, builder) =>
|
|
|
{
|
|
|
//builder.AddEnvironmentVariables();
|
|
|
});
|
|
|
|
|
|
//设置日志
|
|
|
hostBuilder.ConfigureLogging((context, builder) =>
|
|
|
{
|
|
|
|
|
|
});
|
|
|
|
|
|
return hostBuilder;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 可选:配置Host主机
|
|
|
/// </summary>
|
|
|
/// <param name="hostBuilder"></param>
|
|
|
public void ConfigureHost(IHostBuilder hostBuilder)
|
|
|
{
|
|
|
hostBuilder.ConfigureLogging(config =>
|
|
|
{
|
|
|
//清除日志设置
|
|
|
//config.ClearProviders();
|
|
|
|
|
|
//集成 OpenTelemetry Logger
|
|
|
config.AddOpenTelemetry(config =>
|
|
|
{
|
|
|
config
|
|
|
.AddConsoleExporter()
|
|
|
.AddOtlpExporter(config =>
|
|
|
{
|
|
|
config.Endpoint = new Uri("http://localhost:4317/");
|
|
|
});
|
|
|
});
|
|
|
|
|
|
//将 Microsoft.Extensions.Logging 日志写入到 ITestOutputHelper
|
|
|
//需要导入 Microsoft.Extensions.Logging、Xunit.DependencyInjection.Logging包,设置后统一使用ILogger(不再单独使用 ITestOutputHelper)
|
|
|
config
|
|
|
.AddXunitOutput()
|
|
|
.SetMinimumLevel(LogLevel.Trace);
|
|
|
|
|
|
});
|
|
|
|
|
|
//集成 OpenTelemetry Tracer
|
|
|
TracerProviderBuilder builder = Sdk.CreateTracerProviderBuilder();
|
|
|
builder
|
|
|
.SetResourceBuilder
|
|
|
(
|
|
|
ResourceBuilder
|
|
|
.CreateDefault()
|
|
|
.AddService("Xunit.DependencyInjectionService=========================================")
|
|
|
)
|
|
|
.AddSource("Xunit.DependencyInjection")
|
|
|
.AddHttpClientInstrumentation()
|
|
|
.AddConsoleExporter()
|
|
|
.AddOtlpExporter(config =>
|
|
|
{
|
|
|
config.Endpoint = new Uri("http://localhost:4317");
|
|
|
})
|
|
|
.AddZipkinExporter(config =>
|
|
|
{
|
|
|
config.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
|
|
|
})
|
|
|
;
|
|
|
}
|
|
|
|
|
|
/* 异常时启用
|
|
|
/// <summary>
|
|
|
/// 可选:构建Host主机
|
|
|
/// 如果找不到此方法签名,使用此方法即可构建主机
|
|
|
/// 注意:没有异常时,不需要此方法
|
|
|
/// </summary>
|
|
|
/// <param name="hostBuilder"></param>
|
|
|
/// <returns></returns>
|
|
|
public IHost BuildHost(IHostBuilder hostBuilder)
|
|
|
{
|
|
|
//注意:执行Build 方法之前(此时还没有创建IHost对象),先执行 ConfigureServices 方法
|
|
|
|
|
|
IHost host = hostBuilder.Build();
|
|
|
|
|
|
//注意:ConfigureServices方法执行后,回返回此处继续执行
|
|
|
return host;
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
/// <summary>
|
|
|
/// 必须:配置IoC容器服务
|
|
|
/// 注意:如果有BuildHost方法,则执行本方法后,回返回 BuildHost 方法继续执行
|
|
|
/// </summary>
|
|
|
/// <param name="services">必须</param>
|
|
|
/// <param name="context">可选</param>
|
|
|
/// <param name=""></param>
|
|
|
public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
|
|
|
{
|
|
|
//将 Microsoft.Extensions.Logging 日志写入到 ITestOutputHelper
|
|
|
//需要导入 Microsoft.Extensions.Logging、Xunit.DependencyInjection.Logging包,设置后统一使用ILogger(不再单独使用 ITestOutputHelper)
|
|
|
//services.AddLogging(configLog =>
|
|
|
//{
|
|
|
// configLog
|
|
|
// .AddOpenTelemetry(options =>
|
|
|
// {
|
|
|
// options
|
|
|
// .AddConsoleExporter()
|
|
|
// .AddOtlpExporter(config =>
|
|
|
// {
|
|
|
// config.Endpoint = new Uri("http://localhost:4317/");
|
|
|
// });
|
|
|
// })
|
|
|
// .AddXunitOutput()
|
|
|
// .SetMinimumLevel(LogLevel.Trace);
|
|
|
//});
|
|
|
|
|
|
//也可以直接使用
|
|
|
//configLog.AddXunitOutput().SetMinimumLevel(LogLevel.Trace);
|
|
|
|
|
|
JsonSerializerOptions serializerOption = new JsonSerializerOptions()
|
|
|
{
|
|
|
// 设置编码器,允许非ASCII字符直接输出
|
|
|
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
|
// 可选:设置缩进,使输出更易读
|
|
|
WriteIndented = true
|
|
|
};
|
|
|
|
|
|
services.AddKeyedSingleton("NiceJsonOption", serializerOption);
|
|
|
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 可选:两种风格都支持的方法(最后执行)
|
|
|
/// 参数:已经注册过的对象都可以,默认情况下,IServiceCollection 未注册
|
|
|
/// 注意:默认的,从参数中不能获取 IServiceCollection,也就不能进行IoC注册;也就启动的末尾(全局启动的结尾,不是单元测试方法的结尾),做些收尾的事.
|
|
|
/// </summary>
|
|
|
/// <param name="applicationServices">可选的 IServiceProvider </param>
|
|
|
public void Configure
|
|
|
(
|
|
|
IHost host,
|
|
|
IServiceProvider applicationServices,
|
|
|
HostBuilderContext hostBuilderContext,
|
|
|
IHostEnvironment env,
|
|
|
IConfiguration configuration,
|
|
|
ITestOutputHelperAccessor helperAccessor
|
|
|
)
|
|
|
{
|
|
|
//启动后:业务逻辑
|
|
|
}
|
|
|
}
|