在Unity依赖注入c#中注入IEnumerable通用接口

时间:2017-07-14 18:34:16

标签: c# dependency-injection generic-interface

我正在开发一个Web API 2应用程序并使用Unity依赖注入。

我有多种类型的过滤器:名称,品牌,类型......

我想创建一个名为IFilterService的接口并强制每个其他类来实现它,然后我调用此接口的IEnumerable并使用正确的类型注入它。

界面是:

public interface IFilterService<T>
{
    bool CanHandle(FilterType type);

    Task<ServiceResult<T>> FilterAsync(T entity);
}

并且类如下:

public class NameService : IFilterService<Name>
{
    public bool CanHandle(FacetType type)
    {
        return type == FacetType.Name;
    }

    public async Task<ServiceResult<Name>> FilterAsync(Name entity)
    {
      // Code
    }
}

控制器就像:

public class FilterController
{
    private readonly IEnumerable<IFilterService> filters;

    public MediaController(IEnumerable<IFilterService> filters)
    {
        this.filters = filters;
    }

     public async Task<HttpResponseMessage> FilterAsync(FilterType type, Name entity)
     {
        foreach(var filter in this.filters.Where(x => x.CanHandle(type)))
        {
            filter.FilterAsync(entity); 
        }
        ....
    }
}

一切正常:唯一的问题是注册接口和Unity依赖注入中的类。

container.RegisterType<IEnumerable<IFilterService>, IFilterService[] >(
                new ContainerControlledLifetimeManager());
container.RegisterType<IFilterService, NameService>("Name Service",
                new ContainerControlledLifetimeManager());

我收到此错误:

  

错误CS0305使用泛型类型“IFilterService”需要1种类型   参数

我尝试过相同的代码但是使用非通用接口并且工作正常。

如何修复错误?一点点解释可能非常有用。谢谢。

1 个答案:

答案 0 :(得分:2)

您有两个选择,第一个是注册特定的过滤器类型

container.RegisterType<IEnumerable<IFilterService<Name>>, IFilterService<Name>[] >(
                new ContainerControlledLifetimeManager());
container.RegisterType<IFilterService<Name>, NameService>("Name Service",
                new ContainerControlledLifetimeManager());

一样使用
public class FilterController
{
    private readonly IEnumerable<IFilterService<Name>> filters;

    public MediaController(IEnumerable<IFilterService<Name>> filters)
    {
        this.filters = filters;
    }

     public async Task<HttpResponseMessage> FilterAsync(FilterType type, Name entity)
     {
        foreach(var filter in this.filters.Where(x => x.CanHandle(type)))
        {
            filter.FilterAsync(entity); 
        }
        ....
    }
}

第二个选项是使您的界面不通用,但保持功能通用

public interface IFilterService
{
    bool CanHandle(FilterType type);

    Task<ServiceResult<T>> FilterAsync<T>(T entity);
}

public class NameService : IFilterService
{
    public bool CanHandle(FacetType type)
    {
        return type == FacetType.Name;
    }

    public Task<ServiceResult<T>> FilterAsync<T>(T entity)
    {
      if(!entity is Name)
          throw new NotSupportedException("The parameter 'entity' is not assignable to the type 'Name'");

        return FilterAsyncInternal((Name)entity);
    }

    private async Task<ServiceResult<Name>> FilterAsyncInternal(Name entity)
    {
        //code
    }
}