解决接口的多重实现

时间:2018-11-27 22:26:52

标签: c# dependency-injection interface

我有一个具有3个服务的应用程序:

  • 根据类型验证内容的验证器服务
  • 一种老板服务,可以将有关老板的东西转换为东西
  • 将员工方面的东西转换为员工的员工服务

看起来像这样简化:

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...}
}

现在我可以的话,我很好:

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

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

但是实际上我想做这样的事情,尽管我的问题是它如何才能知道分别为老板和员工执行哪种实现,因为在这种情况下它们是同一类型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);

2 个答案:

答案 0 :(得分:0)

不是。根据您使用的DI引擎,这将引发某种歧义的解析异常,或者某些较慢的实现可能会采用第一个。其他一些甚至允许您通过IEnumerable机制获取IPeopleService 的所有实现。

为什么DI引擎会知道您想要哪一个?您尚未提供用于决策的任何上下文。

您必须创建一个IPeopleService 和一个IPeopleService

编辑:工具包很重要……某些DI引擎支持按名称或其他类型的上下文进行解析。

答案 1 :(得分:0)

您不能直接使用内置容器来执行此操作。您将必须引入充当中介的工厂,然后注入工厂。这样,您就可以指定其他上下文以获取正确的服务(例如,按名称)。

看看 DependencyInjection.Extensions 的GitHub repo和NuGet package

此解决方案的灵感来自question关于命名分辨率的信息。