企业库 - 从 ParameterValue 表达式获取值

发布于 2024-11-06 10:40:16 字数 415 浏览 3 评论 0原文

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

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

每个 ParameterValue 对象都包含一个类型和一个表达式。

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

有什么想法吗?

I am trying to convert Enterprise Library TypeRegistration ConstructorParameters to a collection of key/value pair (a HashTable or an IDictionary in general).

The ConstructorParameters property is an IEnumerableOf(ParameterValue) so my problem is how to extract the values from each ParameterValue object.

Every ParameterValue object contains a Type and an Expression.

For ex. if a ParameterValue contains: "EventLoggingEnabled = false"
then I can get the key (which is the EventLoggingEnabled) using expression.Member.Name
but I can't find a way to get the value (which is "false").

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海蓝天 2024-11-13 10:40:16

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

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

  • ConstantParameterValue
  • ContainerResolvedParameter
  • ContainerResolvedEnumerableParameter

ConstantParameterValue 直接将值作为 .Value 属性提供。当参数的值需要由容器注入时使用ContainerResolvedParameter,当你有一个集合需要注入时使用ContainerResolvedEnumerableParameter。 ParameterValue 的每个实例实际上都是这些类型之一。

因此,您应该做的是尝试强制转换为每一种,然后根据实际类型进行切换。有一个实用程序基类 ParameterValueVisitor,它允许您在 ParameterValues 上实现访问者模式,以使代码更简洁。

所以,我要做的就是放弃通过 lambda 进行选择 - 你不需要这样做。实现一个访问者使用基类提取您需要的信息,然后在具体类中您将可以使用预先消化的信息。查看 UnityContainerConfigurator 以了解如何完成此操作的示例。

Have you looked at the implementation of the UnityContainerConfigurator? Even if you don't want to use Unity, you can see how the type registration stuff is handled there and adapt to the Windsor API.

You generally don't need to code to the raw ParameterValue class and poke through the lambda expressions. There are actually three subclasses:

  • ConstantParameterValue
  • ContainerResolvedParameter
  • ContainerResolvedEnumerableParameter

The ConstantParameterValue gives you the value directly as the .Value property. ContainerResolvedParameter is used when the value of the parameter needs to be injected by the container, and ContainerResolvedEnumerableParameter is used when you have a collection that needs to be injected. Every instance of ParameterValue is actually one of these types.

So, what you should do is try to cast to each one, and then switch based on the actual type. There's a utility base class, ParameterValueVisitor, that lets you implement the Visitor pattern over ParameterValues to make your code cleaner.

So, what I'd do is drop the picking through lambdas - you don't need to do it. Implement a visitor to pull out the information you need using the base class, then the pre-digested information will be available to you in the concrete classes. Look at the UnityContainerConfigurator for an example of how this is done.

我还不会笑 2024-11-13 10:40:16

当表达式不是 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();
    }

This works, when the Expression is not 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();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文