开发者

Enterprise Library - Get value from ParameterValue Expression

开发者 https://www.devze.com 2023-03-04 18:49 出处:网络
I开发者_Python百科 am trying to convert Enterprise Library TypeRegistration ConstructorParameters to a collection of key/value pair (a HashTable or an IDictionary in general).

I开发者_Python百科 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?


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.


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();
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消