如何使用Autofac注册和解析具有两个类型参数的开放泛型作为具有一个类型参数接口

本文关键字:类型参数 泛型 接口 有一个 具有一 两个 和解 注册 Autofac 何使用 | 更新日期: 2023-09-27 18:12:05

问题

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

public interface ISomeService<T>
{
    // ...
}
public class SomeService<TA, TB> : ISomeService<TA>
{
    // ...
}

我使用Autofac注册它们,如下所示:

var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterGeneric(typeof(SomeService<,>))
    .As(typeof(ISomeService<>))
    .InstancePerLifetimeScope();
var container = containerBuilder.Build();

当尝试像这样解析ISomeService<Foo>的实例时:

var service = container.Resolve<ISomeService<Foo>>();

我得到一个Autofac.Core.Registration.ComponentNotRegisteredException异常,表示请求的服务ISomeService`1[[Foo]]尚未注册。

问题

  1. 使用Autofac我想做的事情是不可能的吗
  2. 如果是,是否有解决方法
  3. 如果没有,其他DI容器是否提供这种功能,例如SimpleInjector

如何使用Autofac注册和解析具有两个类型参数的开放泛型作为具有一个类型参数接口

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

container.Register(typeof(ISomeService<>),
    typeof(SomeService<,>).MakeGenericType(
        typeof(SomeService<,>).GetGenericArguments().First(),
        typeof(Bar)),
    Lifestyle.Scoped);

没有其他DI库可以处理这个问题,但在这种情况下,有一个简单的解决方法可以用于像Autofac这样的容器;您可以简单地从类型派生:

public class BarSomeService<TA> : SomeService<TA, Bar>
{
    public BarSomeService([dependencies]) : base([dependencies]) { }
}
containerBuilder.RegisterGeneric(typeof(BarSomeService<>))
    .As(typeof(ISomeService<>))
    .InstancePerLifetimeScope();