在现有对象实例上打字/动态代理

时间:2011-11-11 22:05:37

标签: c# castle duck-typing dynamic-proxy linfu

我将一个对象传递到我们的库中并通过各种过程。我需要在这些对象通过各个阶段和另一端时附加一些额外的信息 - 我想这是一种动态装饰模式,除了添加其他属性而不是改变现有行为。

我希望使用LinFu或Castle来创建动态代理,并在对象上实现一个额外的接口来存储它。了解扩展接口的组件可以转换和访问它 - 而那些不是遗忘的组件,因为基础类型没有改变。

但是,我没有意识到所有这些机制都假设您可以控制最初创建类型的点 - 我不这样做。

有没有人对我如何更好地接近这个提出建议?

非常感谢

3 个答案:

答案 0 :(得分:0)

似乎有点过分......只需创建一个只包含“额外”属性的新类。定义静态Dictionary<MainClass,ExtensionsClass>。当“知道”的组件想要查看对象的扩展属性时,它们只是在字典中查找该对象。

答案 1 :(得分:0)

您想使用此处的方法adding expando properties to a typed object at runtime in c#

这样你就不会出现内存泄漏

答案 2 :(得分:-1)

这并不能完全解决您的场景,但如何使用充当对象周围装饰器的DynamicObject实现?它允许您访问原始对象以及其他属性。类似于ExpandoObject,但是从您自己的实例数据开始。

这样的事情:

public class Expando : DynamicObject
{
    public dynamic Instance;
    Dictionary<string, dynamic> ExtraProperties = new Dictionary<string, dynamic>();

    public Expando(object instance)
    {
        Instance = instance;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        try
        {
            result = ReflectionUtils.GetProperty(Instance, binder.Name);
            return true;
        }
        catch
        {
            if (ExtraProperties.Keys.Contains(binder.Name))
            {
                result = ExtraProperties[binder.Name];
                return true;
            }
        }

        result = null;
        return false;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        try
        {
            ReflectionUtils.SetProperty(Instance, binder.Name, value);
        }
        catch (Exception ex)
        {
            ExtraProperties[binder.Name] = value;
        }

        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        try
        {
            result = ReflectionUtils.CallMethod(Instance, binder.Name, args);
            return true;
        }
        catch
        {}

        result = null;
        return false;
    }
}

遗憾的是,它没有解决您的强类型/接口要求,并且考虑到此处的反射使用(来自http://www.west-wind.com:8080/svn/WestwindWebToolkit/trunk/Westwind.Utilities/Utilities/ReflectionUtils.cs

,性能不会是最好的