依赖注入——何时在 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。
在我的 .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。