Chris Becke
Chris Becke

Reputation: 36141

One service, two instances, how to configure with ASP.NET Core DI?

With ASP.NET Core's Options pattern one can create Service and register it with two separate calls.

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<MyService>();

    services.Configure<MyServiceOptions>(o => o.Param = 1);

    services.AddMvc();
};

However, I am entirely unclear on how and if it is possible to instantiate two instances of a service and bind different options to them? i.e. given two specialisations of some base class, how do we share a single options class between them?

public class MyService {}

public class MyService1 : MyService {}

public class MyService2 : MyService2 {}

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<MyService1>();
    services.AddTransient<MyService2>();

    // What goes here?
    // config for instance 1
    //services.Configure<MyServiceOptions>(o => o.Param = 1);
    // config for instance 2
    //services.Configure<MyServiceOptions>(o => o.Param = 2);

    services.AddMvc();
};

Basically I want something like the IServiceCollection.AddDbContext extension method, but for services, and I've looked at the EF Core extension methods and I don't get them at all.

Upvotes: 3

Views: 2085

Answers (1)

Chris Becke
Chris Becke

Reputation: 36141

Going with @Kirk Karkin's advice -

public class MyServiceOptions
{
    public int setting { get; set; }
}

public class MyService
{
    public MyService(IOptions<MyServiceOptions> options)
    {
        // TODO: Capture options.
    }
}

public class MyServiceOptions<TMyService> : MyServiceOptions
    where TMyService : MyService
{
}

Now I can create instances of this service by extending it:

public class MyService1 : MyService
{
    public MyService1(IOptions<MyServiceOptions<MyService1>> options>):base(options) 
    {
    }
 }

And then registering multiple instances is easy in Configure Services:

services.AddTransient<MyService1>();
services.AddScoped<MyService2>();
services.Configure<MyServiceOptions<MyService1>>(Configuration.GetSection("MyService1Settings"));
services.Configure<MyServiceOptions<MyService2>>(Configuration.GetSection("MyService2Settings"));

Upvotes: 9

Related Questions