Утиная печать / динамические прокси на существующих экземплярах объектов - PullRequest
2 голосов
/ 12 ноября 2011

У меня есть объект, переданный в нашу библиотеку и прошедший через различные процессы.Мне нужно прикрепить некоторую дополнительную информацию к этим объектам, поскольку они проходят через различные стадии и выходят на другой конец - я думаю, что это своего рода динамический шаблон декоратора, за исключением добавления дополнительных свойств, а не изменения существующего поведения.

Я былнадеясь использовать LinFu или Castle для создания динамического прокси-сервера и реализовать дополнительный интерфейс для объекта, чтобы сохранить это.Компоненты, которые знают о расширенном интерфейсе, могут приводить и получать к нему доступ, в то время как те, которые не забывают, поскольку базовый тип не изменился.

Однако я не оценил, что все эти механизмы предполагают, что вы имеете контрольв момент, когда тип создается изначально - чего я не делаю.

У кого-нибудь есть предложения о том, как мне лучше подойти к этому?

Большое спасибо

Ответы [ 3 ]

0 голосов
/ 17 ноября 2011

Похоже на излишество ... просто создайте новый класс, содержащий только ваши "дополнительные" свойства.Определить статический Dictionary<MainClass,ExtensionsClass>.Когда ваши компоненты «в курсе» хотят посмотреть на расширенные свойства объекта, они просто ищут этот объект в словаре.

0 голосов
/ 06 июня 2012

Вы хотите использовать подход отсюда добавление свойств expando к типизированному объекту во время выполнения в c #

Таким образом, вы не получите утечки памяти

0 голосов
/ 17 ноября 2011

Это не относится к вашему сценарию точно, но как насчет использования реализации 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;
    }
}

К сожалению, оно не отвечает вашим строгим требованиям к типизации / интерфейсу, и производительность не будет самой высокой, учитывая использование Reflection здесь (с *)1006 *http://www.west -wind.com: 8080 / SVN / WestwindWebToolkit / багажник / Westwind.Utilities / Утилиты / ReflectionUtils.cs )

...