C# 如何使用Autofac注册和解析带有两个类型参数的OpenGeneric作为与一个类型参数的接口 问题

C# 如何使用Autofac注册和解析带有两个类型参数的OpenGeneric作为与一个类型参数的接口 问题,c#,dependency-injection,autofac,simple-injector,open-generics,C#,Dependency Injection,Autofac,Simple Injector,Open Generics,我有很多具体的泛型类,它们有两个类型参数,实现了一个带有一个类型参数的泛型接口。例如: public interface ISomeService<T> { // ... } public class SomeService<TA, TB> : ISomeService<TA> { // ... } 公共接口服务 { // ... } 公共类SomeService:ISomeService { // ... } 我使用Autofac注册它

我有很多具体的泛型类,它们有两个类型参数,实现了一个带有一个类型参数的泛型接口。例如:

public interface ISomeService<T>
{
    // ...
}

public class SomeService<TA, TB> : ISomeService<TA>
{
    // ...
}
公共接口服务
{
// ...
}
公共类SomeService:ISomeService
{
// ...
}
我使用Autofac注册它们,如下所示:

var containerBuilder = new ContainerBuilder();

containerBuilder.RegisterGeneric(typeof(SomeService<,>))
    .As(typeof(ISomeService<>))
    .InstancePerLifetimeScope();

var container = containerBuilder.Build();
var service = container.Resolve<ISomeService<Foo>>();
var containerBuilder=new containerBuilder();
集装箱建造商.注册通用(类型(SomeService))
.As(类型(服务))
.InstancePerLifetimeScope();
var container=containerBuilder.Build();
尝试解析
ISomeService
的实例时,如下所示:

var containerBuilder = new ContainerBuilder();

containerBuilder.RegisterGeneric(typeof(SomeService<,>))
    .As(typeof(ISomeService<>))
    .InstancePerLifetimeScope();

var container = containerBuilder.Build();
var service = container.Resolve<ISomeService<Foo>>();
var service=container.Resolve();
我收到一个
Autofac.Core.Registration.ComponentNotRegisteredException
异常,表示请求的服务
ISomeService`1[[Foo]]
尚未注册

问题
  • 用Autofac我想做的是不可能的吗
  • 如果是,是否有解决办法
  • 如果没有,其他DI容器是否提供这种功能,例如SimpleInjector

  • 使用Simple Injector,您可以使寄存器成为部分闭合的通用类型,如下所示:

    container.Register(typeof(ISomeService<>),
        typeof(SomeService<,>).MakeGenericType(
            typeof(SomeService<,>).GetGenericArguments().First(),
            typeof(Bar)),
        Lifestyle.Scoped);
    
    container.Register(类型(服务),
    typeof(SomeService).MakeGenericType(
    typeof(SomeService).GetGenericArguments().First(),
    类型(条形),
    生活方式(范围);
    
    没有其他DI库可以处理这个问题,但在这种情况下,对于Autofac这样的容器有一个简单的解决方法;您可以简单地从类型派生:

    public class BarSomeService<TA> : SomeService<TA, Bar>
    {
        public BarSomeService([dependencies]) : base([dependencies]) { }
    }
    
    containerBuilder.RegisterGeneric(typeof(BarSomeService<>))
        .As(typeof(ISomeService<>))
        .InstancePerLifetimeScope();
    
    公共类BarSomeService:SomeService
    {
    公共BarSomeService([dependencies]):基([dependencies]){}
    }
    集装箱建造商.注册通用(类型(BarSomeService))
    .As(类型(服务))
    .InstancePerLifetimeScope();
    
    容器如何知道类型
    TB
    ?@YacoubMassad问得好。我怀疑这是问题的根源。那么,如何注册服务而不必单独显式注册每个泛型类型(例如,
    containerBuilder.RegisterType().As())
    ?类型
    TB
    SomeService
    的一个实现细节,而不是我想泄漏到
    SomeService
    接口的东西。所有实现对
    TB
    都有相同的值吗?@Steven-不,不幸的是没有。实际上,
    TA
    TB
    是一个域模型分别是face和entity框架实体。有一个直接的(和唯一的)它们之间的映射,例如
    SomeService
    。实体框架实体部分是我不想泄露到我的业务层的部分,其中所有内容都应该是域模型对象,例如
    IPerson
    。从类型派生是一个有趣的解决方法,因此感谢您的建议。但是,我不确定这是否是pr可以显式注册每个映射。如果我理解正确,您上面的第一个代码片段仍然需要显式注册每个映射(即上面的
    typeof(Bar)
    )。再次感谢您的想法和想法。顺便说一句,Simple Injector确实令人印象深刻!