当我调试以下代码时,我发现我注册的单例生命周期在执行到之后SqliteConnection
从内部解析时并不是单例。AddDbContext
GetAsync("")
我添加了以下内容来验证单例是否失败。
if (!ReferenceEquals(_sharedConnection, connection))
throw new ApplicationException("SqliteConnection should be singleton.");
罪魁祸首是什么?解决方法是什么?完整代码如下。
正在测试的 Web API
public class AppDbContext(DbContextOptions<AppDbContext> o) : DbContext(o);
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", (AppDbContext db) => "Hello");
app.Run();
}
}
测试
public class CustomWebAppFactory : WebApplicationFactory<Program>
{
private static SqliteConnection _sharedConnection = null!;
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.ConfigureTestServices(services =>
{
services.RemoveAll(typeof(SqliteConnection));
services.RemoveAll(typeof(DbContextOptions<AppDbContext>));
services.AddSingleton(provider =>
{
var connection = new SqliteConnection("DataSource=:memory:");
return connection;
});
services.AddDbContext<AppDbContext>((provider, options) =>
{
var connection = provider.GetRequiredService<SqliteConnection>();
if (!ReferenceEquals(_sharedConnection, connection))
throw new ApplicationException("SqliteConnection should be singleton.");
options.UseSqlite(connection);
});
var provider = services.BuildServiceProvider();
if (_sharedConnection != null)
throw new ApplicationException("_sharedConnection should be null before reaching the following line.");
_sharedConnection = provider.GetRequiredService<SqliteConnection>();
});
}
}
public class TrivialTest
{
[Fact]
public async Task Should_return_OK()
{
using var factory = new CustomWebAppFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
}
我认为问题出在这一行:
每次访问单例时,都会创建一个新的 SqliteConnection 实例。像这样,您只需创建一次实例: