2

I have an ASP.NET Core project (my first) that requires two internal "sequencers" for specific tasks. The first was implemented like this:

In Startup.cs ConfigureServices method:

services.AddSingleton<ISequencer, ProfileSequencer>();

And of course I have the interface and implementation defined, and it's working well. However I'm not sure how to add the second sequencer, which implements the same interface but has a slightly different implementation.

services.AddSingleton<ISequencer, ChargeSequencer>();

ASP.NET doesn't complain about this, but now when I inject ISequencer into my classes, I can't imagine how it knows which singleton to use. I suspect (but don't know for sure) that the second singleton effectively replaces the first.

There is probably some bad design decision here, so I'll accept an answer that describes how I can inject two different singletons that implement the same interface, or if necessary another reasonable approach to this problem. Thanks!

k3davis
  • 985
  • 12
  • 29
  • 1
    Possible duplication of http://stackoverflow.com/questions/39174989/how-to-register-multiple-implementations-of-the-same-interface-in-asp-net-core – Nibor Apr 21 '17 at 10:34
  • Thanks for the link - I agree this is essentially a duplicate. I got hung up in my search terms on the singleton implementation since I found other solutions for different service types. – k3davis Apr 21 '17 at 11:46

2 Answers2

2

Sorry for the late answer, but you can just inject IEnumerable<ISequencer> into your class or controller, and service locator will pass all the registered services under that interface

Wachburn
  • 2,842
  • 5
  • 36
  • 59
1

It is not possible to register two services of same interface - second registration would override first. But I suggest you quick solution of your problem:

1) Create nested interfaces and use them for registration:

ISomeSpecificSequencer : ISequencer {}
IOtherSpecificSequencer : ISequencer {}

2) Use factory pattern

interface ISequencerFactory
{
  ISequencer GetSequencer(ISequencerOptions someOptions)
}

So in your code you inject ISequencerFactory and then use some option (it could be string, enum, Type, etc) to determine which class you need

Denis Krasakov
  • 1,498
  • 2
  • 13
  • 17
  • This is a good solution to a bad question on my part - thanks. FWIW I am rethinking this to create the sequencers in SQL/stored procedures which is probably safer than creating my own in the first place. – k3davis Apr 21 '17 at 11:48
  • Are you sure that the second registration will override the first one? I am just curios about that. – Mohammed Noureldin Dec 31 '17 at 02:02
  • @MohammedNoureldin I think I tested it in the past. As I understand `IServiceCollection` class store mapping `interface > realization`. Adding interface second time will override first mapping. – Denis Krasakov Jan 01 '18 at 11:57