简体   繁体   English

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

[英]How to register and resolve open generic with two type arguments as interface with one type argument using Autofac

Problem 问题

I have a number of concrete, generic classes with two type arguments that implement a generic interface with one type argument. 我有许多带有两个类型参数的具体泛型类,它们实现了一个类型参数的泛型接口。 For example: 例如:

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

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

I register them using Autofac like this: 我使用Autofac像这样注册它们:

var containerBuilder = new ContainerBuilder();

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

var container = containerBuilder.Build();

When attempting to resolve an instance of ISomeService<Foo> like this: 尝试像这样解析ISomeService<Foo>的实例时:

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

I get an Autofac.Core.Registration.ComponentNotRegisteredException exception saying that the requested service ISomeService`1[[Foo]] has not been registered. 我收到一个Autofac.Core.Registration.ComponentNotRegisteredException异常,表明所请求的服务ISomeService`1[[Foo]]尚未注册。

Questions 问题

  1. Is what I'm trying to do impossible using Autofac? 使用Autofac我要做什么是不可能的?
  2. If so, is there a workaround? 如果是这样,是否有解决方法?
  3. If not, do other DI containers offer such a capability, eg SimpleInjector? 如果没有,其他DI容器是否提供这种功能,例如SimpleInjector?

With Simple Injector, you can make register a partially-closed generic type as follows: 使用Simple Injector,可以使注册部分封闭的通用类型如下:

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

There is no other DI library that can handle this, but in this case there is a simple workaround for containers like Autofac; 没有其他DI库可以处理此问题,但是在这种情况下,对于Autofac这样的容器有一个简单的解决方法; you can simply derive from the type: 您可以简单地从以下类型派生:

public class BarSomeService<TA> : SomeService<TA, Bar>
{
    public BarSomeService([dependencies]) : base([dependencies]) { }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM