我想选择一个构造函数并传递运行时参数。我知道如何选择具有注册表提供的参数的构造函数,也知道如何提供运行时参数。但是我看不到将两者结合在一起的方法。
班级:
public class SomeClass
{
// This is the one I want to be the default by selecting it.
public SomeClass(string arg1, AnArgClass arg2) { }
// This is default if I don't purposely select it.
public SomeClass(string arg1, string arg2, string arg3) { }
}
如何注册(我知道这不起作用):
ForConcreteType<SomeClass>()
.Configure.SelectConstructor(() => new SomeClass(arg1?, arg2?)); I don’t see a way to get the runtime args in…
如果可以注册,这就是我将如何创建它并提供参数的方式:
var obj1 = _container.With(“arg1”).EqualTo(aRunTimeArg1)
.With<AnArgClass>(aRunTimeArg2)
.GetInstance<SomeClass>();
提前致谢。
(注意:我正在寻找一个StructureMap 3.x解决方案。一些看起来几乎可行的选项正在使用2.x语法,而3.x似乎不可用-否则它就会移动)
我找到了一些解决方案。
将该属性标记为所需的构造函数,然后关闭。绝对不是我的第一选择,因为它将注册分为实现部分,以及使用IoC属性的其他问题。但这是最简单的,如果您在代码中没有IoC容器属性的问题,请尝试一下。
下面是一种使用构造函数选择器策略查找构造函数的方法,并且有多个选择器按类型分隔。请注意,可以将其制成扩展方法解决方案,但我不想使其复杂化。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.Pipeline;
using StructureMap.TypeRules;
public class SomeClass
{
// This is the one I want to be the default by selecting it.
public SomeClass(string arg1, AnArgClass arg2) { }
// This is default if I don't purposely select it.
public SomeClass(string arg1, string arg2, string arg3) { }
}
public class AnArgClass { }
public class SampleRegistry : Registry
{
public SampleRegistry()
{
var selectors = new SelectorsList();
Policies.ConstructorSelector(selectors);
For<SomeClass>().Use<SomeClass>();
selectors.Add<SomeClass>(new SelectorByTypes(new[] { typeof(string), typeof(AnArgClass) }));
}
}
public class SelectorByTypes : IConstructorSelector
{
private Type[] mArgumentsTypes;
public SelectorByTypes(IEnumerable<Type> argumentsTypes)
{
mArgumentsTypes = argumentsTypes.ToArray();
}
public ConstructorInfo Find(Type pluggedType)
{
return pluggedType.GetConstructor(mArgumentsTypes); // GetConstructor() ext in SM.TypeRules
}
}
public class SelectorsList : IConstructorSelector
{
// Holds the selectors by type
private Dictionary<Type, IConstructorSelector> mTypeSelectors = new Dictionary<Type, IConstructorSelector>();
// The usual default, from SM.Pipeline
private GreediestConstructorSelector mDefaultSelector = new GreediestConstructorSelector();
public void Add<T>(IConstructorSelector selector)
{
mTypeSelectors.Add(typeof(T), selector);
}
public ConstructorInfo Find(Type pluggedType)
{
ConstructorInfo selected = null;
if (mTypeSelectors.ContainsKey(pluggedType))
{
var selector = mTypeSelectors[pluggedType];
selected = selector.Find(pluggedType);
}
else
{
selected = mDefaultSelector.Find(pluggedType);
}
return selected;
}
}
作为扩展,它将类似于:
For<SomeClass>()
.Use<SomeClass>()
.SetConstructor(selectors, new Type[] { typeof(string), typeof(AnArgClass) });
public static class Extensions
{
public static SmartInstance<TConcreteType, TPluginType> SetConstructor<TConcreteType, TPluginType>(
this SmartInstance<TConcreteType, TPluginType> instance,
ConstructorSelectors constructors,
IEnumerable<Type> types)
where TConcreteType : TPluginType
{
constructors.Add(typeof(TPluginType), new ArgTypesConstructorSelector(types));
return instance;
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句