解析Autofac中实现泛型接口的所有类型的IEnumerable

Resolve IEnumerable of All Types that Implement Generic Interface in Autofac

我希望能够解析来自 Autofac 的服务集合,该集合表示实现开放通用接口的所有已注册类型。

public interface IEntityService<in T> where T : Entity
{
    void DoEntityWork(T entity);
}

我有许多继承 Entity 的 类 和许多为该实体实现 IEntityService 的相应服务 类。

public class EntityA : Entity { }
public class EntityB : Entity { }
public class EntityC : Entity { }

public class EntityAService : IEntityService<EntityA>
{
    public void DoEntityWork(EntityA entity)
}

public class EntityBService : IEntityService<EntityB>
{
    public void DoEntityWork(EntityB entity)
}

public class EntityCService : IEntityService<EntityC>
{
    public void DoEntityWork(EntityB entity)
}

以下是我如何使用 Autofac 注册它们:

builder.RegisterType<EntityAService>().As<IEntityService<EntityA>();
builder.RegisterType<EntityBService>().As<IEntityService<EntityB>();
builder.RegisterType<EntityCService>().As<IEntityService<EntityC>();

我希望能够解决集合中的每个 IEntityService 注册。但是,尝试使用以下代码向它们注入 returns 一个空集合:

public class MyProcessingClass(IEnumerable<IEntityService<Entity>> entityServices)
{
    _entityServices = entityServices;
}

我曾尝试将它们全部注册 As<IEntityService<Entity>>(),但这会引发 ArgumentException 并显示以下消息:

The type 'MyProject.Services.EntityAService' is not assignable to service 'MyProject.Interfaces.IEntityService'1[[MyProject.Models.Entity]]

如何使用实现 Entity 的类型参数解析所有实现 IEntityService 的类型?

这就是 contravariance 在 C# 中的工作方式,EntityAService 不是 IEntityService<Entity>,这种关系以另一种方式工作:

public class EntityService : IEntityService<Entity>
{
    public void DoEntityWork(Entity entity) { }
}

IEntityService<EntityA> x = new EntityService();

一种解决方法是引入 IEntityService 的 non-generic 版本,将所有实体服务注册为该服务并解析 IEnumerable<IEntityService>.

Autofac 不支持开箱即用的此类功能。有一个 ContravariantRegistrationSource 但它确实与此相反 - 如果您注册 IEntityService<Entity> 然后解析 IEntityService<EntityA> 它会为您解析 IEntityService<Entity> 实例。它不允许您解析 IEnumerable<IEntityService<Entity>> 并定位所有派生类型。