Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net Core: register implementation with multiple interfaces and lifestyle Singleton

Considering the following interface and class definitions:

public interface IInterface1 { } public interface IInterface2 { } public class MyClass : IInterface1, IInterface2 { } 

is there any way to register one instance of MyClass with multiple interfaces like this:

... services.AddSingleton<IInterface1, IInterface2, MyClass>(); ... 

and resolve this single instance of MyClass with different interfaces like this:

IInterface1 interface1 = app.ApplicationServices.GetService<IInterface1>(); IInterface2 interface2 = app.ApplicationServices.GetService<IInterface2>(); 
like image 739
Maxim Avatar asked Jan 23 '17 16:01

Maxim


People also ask

What is difference between Addtransient and AddScoped and Addsingleton?

Singleton is a single instance for the lifetime of the application domain. Scoped is a single instance for the duration of the scoped request, which means per HTTP request in ASP.NET. Transient is a single instance per code request.

CAN interface have multiple implementations C#?

Using the delegate func Introduce three implementation classes as below- three different classes where we have implemented the same interface. ASP.NET Core has built-in support for dependency injection. However, multiple implementations of an interface in ASP.NET Core is tricky.

How do you specify the service life for a registered service that is added as a dependency?

Built-in IoC container manages the lifetime of a registered service type. It automatically disposes a service instance based on the specified lifetime. Singleton − IoC container will create and share a single instance of a service throughout the application's lifetime.

Can not consume scoped service from Singleton?

You should almost never consume scoped service or transient service from a singleton. You should also avoid consuming transient service from a scoped service. What is happening when you consume scoped service from a singleton service is known as a captive dependency.


2 Answers

The service collection by definition is a collection of ServiceDescriptors, which are pairs of service type and implementation type.

You can however get around this by creating your own provider function, something like this (thanks user7224827):

services.AddSingleton<IInterface1>(); services.AddSingleton<IInterface2>(x => x.GetService<IInterface1>()); 

More options below:

private static MyClass ClassInstance;  public void ConfigureServices(IServiceCollection services) {     ClassInstance = new MyClass();     services.AddSingleton<IInterface1>(provider => ClassInstance);     services.AddSingleton<IInterface2>(provider => ClassInstance); } 

Another way would be:

public void ConfigureServices(IServiceCollection services) {     ClassInstance = new MyClass();     services.AddSingleton<IInterface1>(ClassInstance);     services.AddSingleton<IInterface2>(ClassInstance); } 

Where we just provide the same instance.

like image 130
juunas Avatar answered Sep 20 '22 08:09

juunas


You can wrap user7224827's answer to create a nice extension method matching your original desired API:

    public static class ServiceCollectionExt     {         public static void AddSingleton<I1, I2, T>(this IServiceCollection services)              where T : class, I1, I2             where I1 : class             where I2 : class         {             services.AddSingleton<I1, T>();             services.AddSingleton<I2, T>(x => (T) x.GetService<I1>());         }     } 
like image 29
daw Avatar answered Sep 22 '22 08:09

daw