HomeContact

Using the Factory Method with `AddSingleton` in .NET

By Shady Nagy
Published in dotnet
October 23, 2023
2 min read
Using the Factory Method with `AddSingleton` in .NET

Table Of Contents

01
Introduction:
02
Basic Dependency Injection in .NET:
03
The Power of the Factory Method:
04
Use Cases:
05
Considerations:
06
Conclusion:
07
References and Further Reading:
08
Feedback and Questions

Introduction:

Dependency Injection (DI) is a powerful pattern for implementing inversion of control, making our applications more modular, testable, and maintainable. .NET offers a built-in DI system that allows us to register and resolve dependencies. However, sometimes, we need more dynamic behavior than straightforward registrations.

In this tutorial, we’ll dive deep into a specialized technique: Using the factory method with AddSingleton to achieve dynamic service registration.

Basic Dependency Injection in .NET:

- What are AddSingleton, AddScoped, and AddTransient?

These are extension methods provided by .NET to register services with different lifetimes:

  • Singleton: Creates a single instance for the entire application’s lifetime.
  • Scoped: Creates an instance for the scope’s lifetime (e.g., an HTTP request).
  • Transient: Creates a new instance every time the service is requested.

- Use-cases:

  • Use Singleton for services that maintain state across requests or don’t maintain state at all.
  • Use Scoped for services that maintain state per request or transaction.
  • Use Transient for lightweight, stateless services.

The Power of the Factory Method:

Instead of just providing a type to the AddSingleton method, we can provide a factory method – a delegate that produces the instance of the service. This factory method can use other registered services and even runtime data.

builder.Services.AddSingleton<IService>(provider =>
{
var dependency = provider.GetRequiredService<IDependency>();
return new MyService(dependency);
});

Use Cases:

- Configuration from Database:

Imagine a scenario where our application’s configuration is stored in a database. Instead of reading it during startup, we want to fetch it dynamically and inject it into our services.

builder.Services.AddSingleton<ISomeService>(provider =>
{
var getDbSettingsService = provider.GetRequiredService<IGetDbSettingsService>();
var dbSettings = getDbSettingsService.ExecuteAsync().Result;
return new SomeService(dbSettings);
});

- Conditional Service Registration:

Depending on the environment or a certain condition, we might want to return different implementations of an interface.

builder.Services.AddSingleton<IRepository>(provider =>
{
if (Environment.IsDevelopment())
{
return new MockRepository();
}
return new SqlRepository();
});

- Complex Initialization:

Creating a service might require multiple steps, configurations, or even conditional logic.

Considerations:

- Asynchronous Challenges:

Using asynchronous operations within a factory method, like ExecuteAsync().Result, can lead to deadlocks. It’s often safer to preload such data before setting up the DI container or use synchronous methods if available.

- Service Lifetimes:

Be cautious about the lifetime of services you resolve in the factory method. Resolving a scoped service inside the factory method of a singleton can lead to unexpected behavior.

Conclusion:

The factory method in AddSingleton (and its siblings AddScoped and AddTransient) grants developers the power to dynamically construct services. With this power comes the responsibility to ensure the right lifetimes and handle asynchronous operations properly.

References and Further Reading:

  • Official Microsoft Dependency Injection in ASP.NET Core
  • More about Service Lifetimes

Feedback and Questions

Your insights drive us! For any questions, feedback, or thoughts, feel free to connect:

  1. Email: shady@shadynagy.com
  2. Twitter: @ShadyNagy_
  3. LinkedIn: Shady Nagy
  4. GitHub: ShadyNagy

If you found this guide beneficial, don’t hesitate to share it with your network and help others discover these useful features in DI.

Until the next guide, happy coding!


Tags

#.NETCore#.NET#FactoryMethod#AddSingleton#DependencyInjection#ServiceRegistration#ServiceCollection#dotnet#BestPractices

Share


Previous Article
Setting up SQL Dependency in a C# Application
Shady Nagy

Shady Nagy

Software Innovation Architect

Topics

AI
Angular
dotnet
GatsbyJS
Github
Linux
MS SQL
Oracle

Related Posts

Automate .NET Package Deployment to NuGet with GitHub Actions
Automate .NET Package Deployment to NuGet with GitHub Actions
October 01, 2024
1 min

Quick Links

Contact Us

Social Media