Цепочка событий / Прокси к исходному объекту - PullRequest
2 голосов
/ 21 июля 2011

У меня есть класс, который унаследован от объекта, привязанного к контексту.У класса есть атрибут по некоторым свойствам.Когда какое-либо свойство изменяется, PostProcess(IMessage msg, IMessage msgReturn) вызывает событие, и из события снова запускается новое свойство с тем же атрибутом.Второе изменение также должно вызвать PostProcess, но этого не происходит.Вероятно потому, что объект, в котором изменено второе свойство, не является исходным объектом .net, а MarshalByRefObject / ContextBoundObject / Proxy Object.Мой запрос - как привести прокси к исходному объекту.Я пробовал кастинг и SynchonizationAttribute, но это не помогает.Просто чтобы вы знали, что события выполняются Async способом, чтобы он не блокировал выполнение кода, и прокси и исходный объект существуют в одном домене приложения.

Я пробовал с двумя объектами, один из которых содержит ссылку наво-вторых, и когда свойство first изменяется, оно пытается изменить свойство second, но оно не вызывает PostProcess.

В основном мне нужно сделать дерево, в котором различные объекты зависят от свойств других объектов.И когда какое-либо одно свойство изменяется, оно должно запускать своего наблюдателя, и это может распространяться как цепочка, пока наблюдатель не будет найден.Я пытаюсь сделать это с ContextBoundObject.

Пример:

public class PowerSwitch : ObjectBase
{
    [Watchable]
    public bool IsOn { get; set; }
    public bool IsWorking { get; set; }
}

public class Bulb : ObjectBase
{
    public Color Color { get; set; }
    [Watchable]
    public bool IsOn { get; set; }
    protected override void Update(object sender, PropertyChangeEventArgs e)
    {
        ((Bulb)this).IsOn = !((Bulb)this).IsOn; 
          //<-- b1.update should be called after this, but it is not
    }
}

[Watchable]
public class ObjectBase : ContextBoundObject
{
     public virtual void Watch(ObjectBase watch, string propertyName)
     {
         watch.Watcher.Add(this, propertyName);
     }

     protected virtual void Update(object sender, 
                            PropertyChangeEventArgs e) { }

     public Dictionary<ObjectBase, string> Watcher
                      = new Dictionary<ObjectBase, string>();

     internal void NotifyWatcher(
             PropertyChangeEventArgs propertyChangeEventArgs)
     {
          Watcher.Where(sk => sk.Value == propertyChangeEventArgs.Name)
                        .ToList()
                        .ForEach((item) =>
                        {
                            item.Key.Update(this, propertyChangeEventArgs);

                            });
          }
    }

Основной метод

        PowerSwitch s1 = new PowerSwitch();
        Bulb b1 = new Bulb();
        b1.Watch(s1, "IsOn");
        s1.IsOn = true; //<-- b1.update is called after this

Пожалуйста, предложите альтернативный или лучший способ реализовать то, чего я хочу достичь.

1 Ответ

1 голос
/ 22 июля 2011

Похоже, вы очень близки к шаблону наблюдателя , где наблюдатели подписываются на уведомления о статусе субъекта.

В этом шаблоне b1.IsOn = true будет содержать код, который циклически просматривает Обозреватели и уведомляет их об изменениях. Я думаю, если вы хотите наблюдать множество свойств одного объекта, вы можете инкапсулировать код уведомления. Тогда b1.IsOn может просто иметь одну строку, которая говорит что-то вроде:

this.SendNotification("IsOn", Value);

Это похоже на то, что вы делаете ... Если вы читаете шаблон, вы можете почувствовать себя немного увереннее, и, возможно, вы могли бы сделать несколько изменений, чтобы стандартизировать ваш код.

Кстати, для этого есть что-то встроенное в .Net - IObservable (T) . Я не использовал это, но выглядит сильным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...