我遵循this document来使用类型化工厂并将参数传递给构造函数。当我尝试传递代码中所示的2个参数(1,"fo")时,类型化工厂给出了这个错误。
public class SomeClass {
public ITypedFactory2 F2 { get; set; }
public void SomeFunction() {
var req = F2.Create<IGetFooRequest>(1, "fo"); // ERROR HERE
}
}
public class GetFooRequest : IGetFooRequest {
public int Bar { get; private set; }
public string Ton { get; private set; }
public GetFooRequest(int bar, string ton ) {
Bar = bar;
Ton = ton;
}
}
public interface IGetFooRequest{
int Bar { get; }
string Ton { get; }
}
public interface ITypedFactory2 {
T Create<T>(int param1, string param2);
void Release(object t);
}
这是windsor安装程序的一部分。
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactory2>().AsFactory());
container.Register(AllTypes
.FromAssemblyContaining<IGetFooRequest>()
.Where(type => type.Name.EndsWith("Request"))
.WithService.AllInterfaces().LifestyleTransient());
为什么它说无法解决非可选的依赖关系...?我传入了(1,"fo");我真的不明白为什么会发生这种情况……请帮帮忙。
发布于 2013-07-25 05:51:39
我也有同样的问题,只是想出了答案。工厂方法的参数名称和类构造函数的参数名称必须匹配,不区分大小写。
因此请将您工厂接口更改为
public interface ITypedFactory2 {
T Create<T>(int **bar**, string **ton**);
void Release(object t);
}
或您的类到
public class GetFooRequest : IGetFooRequest {
public int Bar { get; private set; }
public string Ton { get; private set; }
public GetFooRequest(int **param1**, string **param2**) {
Bar = bar;
Ton = ton;
}
}
发布于 2012-07-29 15:01:46
我看了看自己的代码,发现(int param1,string param2)看起来不太好。让我使用(int bar,string ton) ...命名解决了这个问题。LoL难以置信,我没有看到那个文档提到命名的重要性。
幸运的是,我记得intro here说依赖关系首先按名称解析,然后再按类型解析。这就是按名称工作的部分,以及按类型的部分进入水中。无论如何,我很高兴我知道了如何使用它,所以我在这里与任何需要它的人分享我的答案。
发布于 2019-04-10 23:30:27
如果想要按类型解析参数名称,可以创建自己的ComponentSelector
public class ComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override Arguments GetArguments(MethodInfo method, object[] arguments)
{
if (arguments == null)
return null;
Arguments argumentMap = new Arguments();
ParameterInfo[] parameters = method.GetParameters();
List<Type> types = parameters.Select(p => p.ParameterType).ToList();
List<Type> duplicateTypes = types.Where(t => types.Count(type => type == t) > 1).ToList();
for (int i = 0; i < parameters.Length; i++)
{
if (duplicateTypes.Contains(parameters[i].ParameterType))
argumentMap.Add(parameters[i].Name, arguments[i]);
else
argumentMap.Add(parameters[i].ParameterType, arguments[i]);
}
return argumentMap;
}
}
正如您在我的实现中看到的,当您的构造函数有多个相同类型的参数时,您需要处理这种情况。
在这种情况下,您必须按参数名称进行解析,因为Castle.Windsor
将对每个具有相同类型的参数使用某个类型的第一个参数。
要使用您自己的ComponentSelector
,您还必须向您的IWindsorContainer
注册它:
container.Register(Component.For<ComponentSelector, ITypedFactoryComponentSelector>());
最后,您必须告诉您的工厂使用您自己的ComponentSelector
作为组件选择器:
container.Register(Component.For<ITypedFactory2>().AsFactory(f => f.SelectedWith<ComponentSelector>()));
有关更多信息,请查看有关如何使用自定义组件选择器的official documentation。
https://stackoverflow.com/questions/11707141
复制相似问题