带有嵌套开放泛型的Autofac
本文关键字:泛型 Autofac 嵌套 | 更新日期: 2024-09-22 17:01:17
我是Autofac的新手,在解决嵌套的开放通用服务类型时遇到了一些问题。
我希望我的ContactService
实现两个接口。两个接口都使用相同的泛型类型参数,但第二个是嵌套的:
class ContactService<TParent>
: IContactService<TParent>,
IFeatureProvider<ContactFeature<TParent>>
where TParent : class, IDomainModel
{ }
如果我这样做:
builder
.RegisterGeneric(typeof(ContactService<>))
.As(typeof(IContactService<>))
.As(typeof(IFeatureProvider<>);
然后尝试解析服务IFeatureProvider<ContactFeature<Household>>
(例如)会导致Autofac尝试实例化
ContactService<ContactFeature<Household>>
而不是
ContactService<Household>
我理解为什么以上不起作用。于是我尝试了这个:
builder
.RegisterGeneric(typeof(ContactService<>))
.As(typeof(IContactService<>))
.As(typeof(IFeatureProvider<>)
.MakeGenericType(typeof(ContactFeature<>)));
然而,我仍然得到一个类似的错误:
TypeLoadException: GenericArguments[0], 'ContactFeature`1[Household]',
on 'Contact`1[TParent]' violates the constraint of type parameter 'TParent'.
System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst,
Int32 numGenericArgs, ObjectHandleOnStack type)
ArgumentException: GenericArguments[0], 'ContactFeature`1[Household]',
on 'IContactService`1[TParent]' violates the constraint of type 'TParent'.
System.RuntimeType.ValidateGenericArguments(MemberInfo definition,
RuntimeType[] genericArguments, Exception e)
看起来Autofac正试图将ContactFeature<Household>
作为TParent
而不仅仅是Household
传递。
抱歉解释太长。我希望有人能帮我把这件事做好!
谢谢。
您所要做的似乎只是将打开的通用注册拆分为两个单独的注册,如下所示:
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(ContactService<>))
.As(typeof(IContactService<>));
builder.RegisterGeneric(typeof(ContactService<>))
.As(typeof(IFeatureProvider<>));
var container = builder.Build();
var service = container.Resolve(typeof(IFeatureProvider<ContactFeature<Household>>));
var service2 = container.Resolve(typeof(IContactService<Household>));
Console.WriteLine(service.GetType());
Console.WriteLine(service2.GetType());
Console.ReadKey();
这两个解析都会为您提供ContactService<Household>
的实例。但老实说,我不知道为什么当你把它放在一个注册中时,它会单独工作,而不工作。
我使用了以下类和接口来测试解决方案:
class ContactService<TParent> : IContactService<TParent>, IFeatureProvider<ContactFeature<TParent>>
where TParent : class, IDomainModel
{
}
interface IContactService<T> where T : class, IDomainModel
{
}
interface IFeatureProvider<TProvider>
{
}
interface IDomainModel
{
}
class Household : IDomainModel
{
}
class ContactFeature<TDomainModel> where TDomainModel: class, IDomainModel
{
}