3

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.

3
  • 4
    Could you make MyServiceOptions generic and register it twice as MyServiceOptions<MyService1> and MyServiceOptions<MyService2>? Commented May 22, 2019 at 12:43
  • Give each class its own unique options class. Commented May 22, 2019 at 12:47
  • @Kirk Larkin: That really seems to be the way of it. Ive almost got a DbContext kind of thing working but its sooo complex. There. Surely. Must be an easier way to configure services: This is a lot of boilerplate simply because I don't want hardcoded settings per service. Commented May 22, 2019 at 14:13

1 Answer 1

9

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"));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.