Reputation: 18600
In my .NET Web APIv2 project, I've found myself marking the scope of all my injected services as Singleton
.
I'm using the Simple Injector DI framework (not that this matters for my specific question).
Here's a simplified example:
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();
}
}
}
Some of my other services include some cryptography classes, which contain no state whatsoever, and could easily be static classes.
Here's the Simple Inject code, just for completion:
var container = new Container();
container.Register<IDbConnectionFactory, SqlConnectionFactory>(Lifestyle.Singleton);
container.Register<IUserService, UserService>(Lifestyle.Singleton);
Based on how I'm creating the database connection, it would appear to me that a Singleton is fine for my SqlConnectionFactory
class, as well as my UserService
class, but please correct me if I'm wrong.
This leads me to ask, when would you (or wouldn't you) use a Singleton scope for an injected service? And if you can use a Singleton, why wouldn't you? Isn't there a performance benefit of not having to instantiate a new instance for every web request thread, or entry (Transient) to a method?
Upvotes: 5
Views: 1621
Reputation: 233150
As a general rule, use Singleton lifetime for thread-safe classes. There's no reason to create new instances all the time if a single instance can do the job as well. You do, however, also need to avoid Captive Dependencies.
In case of the OP, it looks to me as though all classes are stateless (and thereby thread-safe), so Singleton lifetimes look good to me.
Lifetime mismatches can be difficult to spot when using a DI Container, but become much easier to detect when using Pure DI. That's one of many reasons I prefer Pure DI.
Upvotes: 1