鸭子在现有对象实例上的键入/动态代理

问题描述 投票:2回答:3

我有一个对象移到我们的库中并经过各种过程。当这些对象经过各个阶段并到达另一端时,我需要为其添加一些附加信息-我想是一种动态装饰器模式,除了添加其他属性而不是更改现有行为外。

我希望使用LinFu或Castle创建一个动态代理,并在对象上实现一个附加接口来存储它。知道扩展接口的组件可以强制转换和访问它,而那些不扩展的组件则可以忽略,因为基础类型没有改变。

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

有人对我如何更好地解决这个问题有任何建议吗?

非常感谢

c# castle duck-typing dynamic-proxy linfu
3个回答
0
投票

这不能完全解决您的情况,但是如何使用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;
    }
}

不幸的是,它不能满足您强大的键入/接口要求,而且考虑到此处的反射用法(从https://github.com/RickStrahl/Westwind.Utilities/blob/master/Westwind.Utilities/Utilities/ReflectionUtils.cs起,性能也不会达到最佳)


0
投票

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


0
投票

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

那样就不会出现内存泄漏

© www.soinside.com 2019 - 2024. All rights reserved.