C# Autofac:从单个接口的多个实现和不同制造商的解决方案
Autofac是否可以实例化实现相同接口但具有不同构造函数的类,并推断要实例化的类C# Autofac:从单个接口的多个实现和不同制造商的解决方案,c#,autofac,C#,Autofac,Autofac是否可以实例化实现相同接口但具有不同构造函数的类,并推断要实例化的类 public sealed class LoginModuleTypeItemViewModel : IInternalModuleTypeItemViewModel { public LoginModuleTypeItemViewModel(LoginModuleTypeExtraModel model) { } } public sealed class TypeObjectModu
public sealed class LoginModuleTypeItemViewModel : IInternalModuleTypeItemViewModel
{
public LoginModuleTypeItemViewModel(LoginModuleTypeExtraModel model)
{
}
}
public sealed class TypeObjectModuleTypeItemViewModel : IInternalModuleTypeItemViewModel
{
public TypeObjectModuleTypeItemViewModel(TypeObjectModuleTypeExtraModel model)
{
}
}
builder.RegisterType<TypeObjectModuleItemViewModel>().As<IInternalModuleItemViewModel>().SingleInstance();
builder.RegisterType<LoginModuleItemViewModel>().As<IInternalModuleItemViewModel>().SingleInstance();
_container.Resolve<IInternalModuleItemViewModel>(new TypedParameter(model.GetType(), model));
公共密封类LoginModuleTypeItemViewModel:IInternalModuleTypeItemViewModel
{
公共LoginModuleTypeItemViewModel(LoginModuleTypeExtraModel模型)
{
}
}
公共密封类TypeObjectModuleTypeItemViewModel:IInternalModuleTypeItemViewModel
{
公共类型ObjectModuleTypeItemViewModel(类型ObjectModuleTypeExtraModel)
{
}
}
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
_Resolve(新的TypedParameter(model.GetType(),model));
是的,这很好用。但请确保使用构造函数中的相同类型正确解析(如果您正在注册LoginModuleItemViewModel
,则该模型必须为LoginModuleTypeExtraModel
类型,除非您在LoginModuleItemViewModel
类中具有类型objectmoduletypeextramodel
的有效构造函数).当您注册多个组件(“类”)以公开同一接口(“服务”)时,它是wins中的最后一个组件。也就是说,如果您有:
var builder=newcontainerbuilder();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
var container=builder.Build();
然后,当你试图解决一个问题时,它总是最后一个问题
var thing=container.Resolve();
Assert.IsType(thing);//这是真的
传递什么参数并不重要。如果你只解决一个实例,它将永远是wins中的最后一个。没有“根据我传入的参数选择对象”。如果你仔细想想,这是有意义的——从依赖注入/控制反转的角度来看,使用者永远不应该知道或关心实现接口的类型
如果你扩展你所要求的逻辑,如果你有这个呢
公共类优先:I
{
公共优先(依赖项部门):{}
}
公共课第二名:伊辛
{
公共秒(依赖项dep,其他依赖项其他):{}
}
然后你注册了
var builder=newcontainerbuilder();
//我们可以从容器中解析OtherDependency
RegisterType();
//我们从中挑选的两件事
builder.RegisterType().As();
builder.RegisterType().As();
var container=builder.Build();
//OtherDependency可以来自容器
//但您将依赖项作为参数提供
var thing=container.Resolve(新类型参数(typeof(Dependency),newdependency());
在那个例子中,…什么类型的东西
?它是第一个
,因为唯一的参数是依赖项
?还是第二个
,因为标准的“最后一个赢”和其他依赖项
可以来自容器
如果它是首先
然后…拥有依赖项注入容器有什么用,因为您实际上是基于您必须知道的构造函数参数“更新”特定类型
如果是秒
,那么……你没有得到你想要的,你不知何故得到了“与构造函数参数匹配的东西”
我知道上面的内容并没有给你一个答案,但我希望它能让你明白为什么你所要求的东西可能不是Autofac(或任何DI容器)所能提供的——你有一点设计问题
您的问题涉及到如何“根据上下文选择实现。”
我的猜测是,在这条线的某个地方,您有一个参数(或其他什么),基于此,您需要“选择”不同的视图模型类型
我链接到的常见问题解答解释了这是一个设计问题的原因,并提供了一些解决方法。我不会在这里重复全部内容,但简而言之:
您可以重新设计/更改接口,使它们不完全相同。如果不能将它们视为完全相同,则即使它们看起来具有相同的方法,它们也不完全相同
您可以更新注册使用各种物品的物品的方式,使它们在某种程度上符合预期的类型。这是一件涉及ResolvedParameters
和lambda注册的复杂事情,FAQ页面上有一个工作示例来解释这一点
您可以使用键控服务为每个供应商的组件提供一个ID,然后在属性中或在手动解析操作期间使用这些键/ID来指示您想要的东西
您可以使用元数据将供应商ID或其他ID附加到每个供应商的注册中,以便在运行时“选择”正确的备份组件
它深入解释了这些选项的工作原理。当我想实例化一个LoginModuleTypeItemViewModel
时,“model”的类型是“LoginModuleTypeExtraModel”。与TypeObjectModuleTypeItemViewModel
相同,“model”是类型TypeObjectModuleTypextramodel
。但这目前不起作用,它只考虑最后注册的类型LoginModuleItemViewModel
。你有办法解决这个问题吗?我认为@travis illig的上述回答澄清了一些问题,这首先是一个设计问题,而不是Autofac。