我有一个继承自上下文绑定对象的类。类具有某些属性的属性。当某些属性发生更改时,PostProcess(IMessage msg, IMessage msgReturn)
会引发一个事件,并再次从该事件中触发具有相同属性的新属性。第二次更改也应该调用PostProcess
,但它没有发生。可能是因为,更改第二个属性的对象不是原始的.net对象,而是MarshalByRefObject / ContextBoundObject / Proxy Object
。我的查询是如何将代理转换为原始对象。我尝试了施放和SynchonizationAttribute
,但它没有帮助。只是为了让您知道事件以Async
方式执行,因此它不会阻止代码执行,代理和原始对象都存在于同一个应用程序域中。
我尝试了两个对象,一个持有第二个引用,当第一个属性发生更改时,它尝试更改第二个属性,但它没有调用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
请建议替代或更好的方式来实现我想要实现的目标。
答案 0 :(得分:1)
看起来你非常接近observer pattern,Observers订阅了主题的状态通知。
在该模式中,b1.IsOn = true将包含循环通过Observers并通知它们更改的代码。我想如果你想在一个对象上观察很多属性,你可以封装通知代码。然后b1.IsOn可能只有一行代表:
this.SendNotification("IsOn", Value);
这看起来很像你正在做的事情......如果你阅读了这个模式,你可能最终会感到更自信,也许你可以做一些改变来标准化你的代码。
顺便说一句,.Net中有一些内容 - IObservable(T)。我没有用过它,但它看起来很强大。