C# 在Unity依赖项注入c中注入泛型接口的IEnumerable#

C# 在Unity依赖项注入c中注入泛型接口的IEnumerable#,c#,dependency-injection,generic-interface,C#,Dependency Injection,Generic Interface,我正在开发一个WebAPI2应用程序,并使用Unity依赖项注入 container.RegisterType<IEnumerable<IFilterService>, IFilterService[] >( new ContainerControlledLifetimeManager()); container.RegisterType<IFilterService, NameService>("Name Service",

我正在开发一个WebAPI2应用程序,并使用Unity依赖项注入

container.RegisterType<IEnumerable<IFilterService>, IFilterService[] >(
                new ContainerControlledLifetimeManager());
container.RegisterType<IFilterService, NameService>("Name Service",
                new ContainerControlledLifetimeManager());
我有多种类型的过滤器:名称、品牌、类型

我想创建一个名为:IFilterService的接口,强制其他所有类实现它,然后调用该接口的IEnumerable,并将其注入正确的类型

界面为:

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

    Task<ServiceResult<T>> FilterAsync(T entity);
}
公共接口IFilterService
{
布尔CanHandle(过滤器类型);
任务过滤器同步(T实体);
}
课程如下:

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

    public async Task<ServiceResult<Name>> FilterAsync(Name entity)
    {
      // Code
    }
}
公共类名称服务:IFilterService
{
公共布尔CanHandle(FacetType)
{
返回类型==FacetType.Name;
}
公共异步任务FilterAsync(名称实体)
{
//代码
}
}
控制器类似于:

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); 
        }
        ....
    }
}
公共类过滤器控制器
{
私有只读IEnumerable过滤器;
公共媒体控制器(IEnumerable筛选器)
{
this.filters=过滤器;
}
公共异步任务FilterAsync(FilterType类型,名称实体)
{
foreach(this.filters.Where(x=>x.CanHandle(type))中的var过滤器)
{
FilterAsync(实体);
}
....
}
}
一切正常:唯一的问题是在Unity依赖项注入中注册接口和类

container.RegisterType<IEnumerable<IFilterService>, IFilterService[] >(
                new ContainerControlledLifetimeManager());
container.RegisterType<IFilterService, NameService>("Name Service",
                new ContainerControlledLifetimeManager());
container.RegisterType(
新的ContainerControlled LifetimeManager());
container.RegisterType(“名称服务”,
新的ContainerControlled LifetimeManager());
我收到这个错误:

错误CS0305使用泛型类型“IFilterService”需要1个类型 论据

我也尝试过同样的代码,但是使用了非泛型接口,效果很好


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

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

container.RegisterType<IEnumerable<IFilterService<Name>>, IFilterService<Name>[] >(
                new ContainerControlledLifetimeManager());
container.RegisterType<IFilterService<Name>, NameService>("Name Service",
                new ContainerControlledLifetimeManager());
container.RegisterType(
新的ContainerControlled LifetimeManager());
container.RegisterType(“名称服务”,
新的ContainerControlled LifetimeManager());

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); 
        }
        ....
    }
}
公共类过滤器控制器
{
私有只读IEnumerable过滤器;
公共媒体控制器(IEnumerable筛选器)
{
this.filters=过滤器;
}
公共异步任务FilterAsync(FilterType类型,名称实体)
{
foreach(this.filters.Where(x=>x.CanHandle(type))中的var过滤器)
{
FilterAsync(实体);
}
....
}
}
第二个选项是使接口非泛型,但保持函数的泛型

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
    }
}
公共接口IFilterService
{
布尔CanHandle(过滤器类型);
任务过滤器同步(T实体);
}
公共类名称服务:IFilterService
{
公共布尔CanHandle(FacetType)
{
返回类型==FacetType.Name;
}
公共任务筛选器同步(T实体)
{
如果(!实体为名称)
抛出新的NotSupportedException(“参数'entity'不可分配给类型'Name'”);
返回FilterAsyncInternal((名称)实体);
}
专用异步任务筛选器同步内部(名称实体)
{
//代码
}
}

第二个解决方案中的返回值是什么?从示例控制器返回一个
任务,任务
中的
T
将是任何类型的
实体
。我更新了第二个示例,通过将其拆分为两个函数,使其更清楚地返回什么。错误CS0029无法隐式地将类型“Bms.Domain.Services.ServiceResult”转换为“Bms.Domain.Services.ServiceResult”名称=实体名称;返回等待此。FilterAsyncInternal(名称);它工作时,返回值被强制转换为ServiceResult:return等待这个。FilterAsyncInternal(制造商)作为ServiceResult;