依赖注入——何时在 Web 应用程序中使用单例范围

Dependency Injection - When to use a Singleton scope in a Web Application

在我的 .NET Web APIv2 项目中,我发现自己将所有注入服务的范围标记为 Singleton

我正在使用 Simple Injector DI 框架(这对我的具体问题并不重要)。

这是一个简化的例子:

public class SqlConnectionFactory : IDbConnectionFactory
{
    public async Task<SqlConnection> GetOpenSqlConnectionAsync()
    {
        var connection = new SqlConnection("connstring");

        await connection.OpenAsync();

        return connection;
    }
}


public class UserService : IUserService
{
    private IDbConnectionFactory DbConnectionFactory { get; set; }

    public UserService(IDbConnectionFactory dbConnectionFactory)
    {
        DbConnectionFactory = dbConnectionFactory;
    }

    public async Task AddAsync(AddUserDto data)
    {
        using (SqlConnection connection = await DbConnectionFactory.GetOpenSqlConnectionAsync())
        {
            // Create a glorious SqlCommand...
            await cmd.ExecuteNonQueryAsync();
        }
    }
}

我的一些其他服务包括一些加密 classes,其中不包含任何状态,并且很容易是静态的 classes。

这是简单注入代码,仅用于完成:

        var container = new Container();

        container.Register<IDbConnectionFactory, SqlConnectionFactory>(Lifestyle.Singleton);
        container.Register<IUserService, UserService>(Lifestyle.Singleton);

根据我创建数据库连接的方式,在我看来,单例适用于我的 SqlConnectionFactory class 以及我的 UserService class,如有错误请指正

这让我想问,您什么时候(或不会)为注入的服务使用 Singleton 作用域?如果您可以使用 Singleton,为什么不呢?不必为每个 Web 请求线程或方法的入口(瞬态)实例化新实例是否有性能优势?

作为一般规则,为线程安全使用单例生存期 类。如果单个实例也可以完成这项工作,则没有理由一直创建新实例。但是,您还需要避免 Captive Dependencies.

在 OP 的情况下,在我看来,好像所有 类 都是无状态的(因此是线程安全的),所以单例生命周期对我来说很好。

使用 DI 容器时很难发现生命周期不匹配,但会变得很多 easier to detect when using Pure DI. That's one of many reasons I prefer Pure DI