我正在尝试将Enterprise Library TypeRegistration ConstructorParameters转换为键/值对的集合(通常是HashTable或IDictionary)。
ConstructorParameters属性是一个IEnumerableOf(ParameterValue),所以我的问题是如何从每个ParameterValue对象中提取值。
每个ParameterValue对象都包含一个Type和一个Expression。
对于前。如果ParameterValue包含:“EventLoggingEnabled = false” 然后我可以使用expression.Member.Name获取密钥(即EventLoggingEnabled) 但我找不到获取价值的方法(这是“假”)。
有什么想法吗?
答案 0 :(得分:2)
您是否看过UnityContainerConfigurator的实现?即使您不想使用Unity,您也可以看到如何处理类型注册内容并适应Windsor API。
通常,您不需要对原始ParameterValue类进行编码,也不需要遍历lambda表达式。实际上有三个子类:
ConstantParameterValue直接为您提供.Value属性的值。当容器需要注入参数的值时使用ContainerResolvedParameter,并且当您有需要注入的集合时使用ContainerResolvedEnumerableParameter。 ParameterValue的每个实例实际上都是这些类型之一。
所以,你应该做的是尝试转换为每个,然后根据实际类型进行切换。有一个实用程序基类ParameterValueVisitor,它允许您在ParameterValues上实现Visitor模式,以使代码更清晰。
所以,我要做的就是放弃通过lambdas的选择 - 你不需要这样做。实现访问者使用基类提取您需要的信息,然后在具体类中提供预先消化的信息。请查看UnityContainerConfigurator,了解如何完成此操作。
答案 1 :(得分:0)
当Expression不是ResolvedEnumerable时,这是有效的。
var dependencies = new Hashtable();
foreach (ParameterValue pv in constructorParameters)
{
MemberExpression exp = pv.Expression as MemberExpression;
if (exp != null)
{
String key = exp.Member.Name;
Object val = GetValue(exp);
dependencies.Add(key, val);
}
}
// ...
private Object GetValue(MemberExpression member)
{
var objectMember = Expression.Convert(member, typeof(Object));
var getterLambda = Expression.Lambda<Func<Object>>(objectMember);
return getterLambda.Compile().Invoke();
}