0

I have an application that has 3 service :

  • A validator service that validates content based on type
  • A boss service that converts stuff in regard to boss people
  • An employee service that convert stuff in regard to employee people

It looks like this simplified :

public interface IValidatorService<T>
{
    void ValidateContent(AbstractValidator<T> validator, List<T> content);
}

public class ValidatorService <T> : IValidatorService<T>
{
    public void ValidateContent(AbstractValidator<T> validator, List<T> peopleContent)
    { ...does its job...}
}

public interface IPeopleService<T>
{
    List<T> Convert(string json);
}

public class BossService : IPeopleService<People>
{
    IValidatorService<Boss> _validatorService;

    public BossService (IValidatorService<Boss> validatorService)
    {
        _validatorService = validatorService;
    }

    public List<People> Convert(string json)
    { ...does its job for boss...}
}

public class EmployeeService : IPeopleService<People>
{
    IValidatorService<Employee> _validatorService;

    public EmployeeService (IValidatorService<Employee> validatorService)
    {
        _validatorService = validatorService;
    }

    public List<People> Convert(string json)
    { ...does its job for employee...}
}

Now in my main I am ok if I do this :

var serviceProvider = new ServiceCollection()
    .AddSingleton<IValidatorService<Boss>, ValidatorService<Boss>>()
    .AddSingleton<IPeopleService<People>, BossService>()
    .BuildServiceProvider();

var bosses = serviceProvider.GetService<IPeopleService<People>>().Convert(json);

But in fact I want to do something like this although my problem how can it know which implementation to execute for boss and for employee respectivly since they are of the same type in this case IPeopleService

var serviceProvider = new ServiceCollection()
    .AddSingleton<IValidatorService<Boss>, ValidatorService<Boss>>()
    .AddSingleton<IPeopleService<People>, BossService>()
    .AddSingleton<IValidatorService<Employee>, ValidatorService<Employee>>()
    .AddSingleton<IPeopleService<People>, EmployeeService>()
    .BuildServiceProvider();

var bosses = serviceProvider.GetService<IPeopleService<People>>().Convert(json);
var employees = serviceProvider.GetService<IPeopleService<People>>().Convert(json);
abatishchev
  • 98,240
  • 88
  • 296
  • 433
KaptainJ
  • 63
  • 1
  • 3
  • 10
  • 1
    Just inject both classes in the constructor instead of injecting `IPeopleService` make another 2 interfaces `IBossService` implement `IPeopleService` and inject `IBossService` and do the same for the other class. – Train Nov 27 '18 at 22:37

2 Answers2

0

It doesn't. Depending on which DI engine you use, that would throw some kind of ambiguous resolution exception or some lamer implementations might take the first one. Some others even allow you to get all implementations of IPeopleService<People> through an IEnumerable mechanism.

And why would the DI engine know which one you want? You haven't given it any context with which to make a decision.

You'd have to make one IPeopleService<Boss> and one IPeopleService<Employee>.

EDIT: Kit makes a good point... some DI engines support resolving by name or other type of contexts.

SledgeHammer
  • 7,338
  • 6
  • 41
  • 86
0

You can't do that directly using the built-in container. You will have to introduce a factory that acts as an intermediary and inject the factory instead. This allows you to specify additional context to get the right service (e.g. by name).

Take a look at the GitHub repo and NuGet package for DependencyInjection.Extensions.

This solution was inspired by a question about named resolution.

Kit
  • 20,354
  • 4
  • 60
  • 103