企业库 - 从ParameterValue Expression获取值

时间:2011-05-10 20:06:28

标签: dependency-injection unity-container enterprise-library ioc-container

我正在尝试将Enterprise Library TypeRegistration ConstructorParameters转换为键/值对的集合(通常是HashTable或IDictionary)。

ConstructorParameters属性是一个IEnumerableOf(ParameterValue),所以我的问题是如何从每个ParameterValue对象中提取值。

每个ParameterValue对象都包含一个Type和一个Expression。

对于前。如果ParameterValue包含:“EventLoggingEnabled = false” 然后我可以使用expression.Member.Name获取密钥(即EventLoggingEnabled) 但我找不到获取价值的方法(这是“假”)。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您是否看过UnityContainerConfigurator的实现?即使您不想使用Unity,您也可以看到如何处理类型注册内容并适应Windsor API。

通常,您不需要对原始ParameterValue类进行编码,也不需要遍历lambda表达式。实际上有三个子类:

  • ConstantParameterValue
  • ContainerResolvedParameter
  • ContainerResolvedEnumerableParameter

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();
    }
相关问题