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]]
尚未注册
问题
使用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确实令人印象深刻!