事件链/原始对象的代理
我有一个从上下文绑定对象继承的类。类在某些属性上具有属性。当某些属性发生更改时,PostProcess(IMessage msg, IMessage msgReturn)
会引发一个事件,并从该事件中再次触发具有相同属性的新属性。第二次更改也应该调用 PostProcess,但它没有发生。可能是因为,第二个属性被更改的对象不是原始的.net对象,而是MarshalByRefObject / ContextBoundObject / Proxy Object
。我的查询是如何将代理转换为原始对象。我尝试了强制转换和 SynchronizationAttribute,但没有帮助。只是为了让您知道事件正在以异步方式执行,因此它不会阻止代码执行,并且代理和原始对象都存在于同一应用程序域中。
我尝试使用两个对象,一个保存第二个对象的引用,当第一个对象的属性更改时,它尝试更改第二个对象的属性,但它没有调用 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
请建议替代或更好的方法来实现我想要实现的目标。
I have a class which is inherited from context bound object. Class has attribute on some properties. When some property is changed, PostProcess(IMessage msg, IMessage msgReturn)
raise an event and from the event again a new property with same attribute is fired. Second change should also call PostProcess
, but it is not happening. Probably because, the object where second property is changed is not original .net object but MarshalByRefObject / ContextBoundObject / Proxy Object
. My query is how to cast the proxy to original object. I tried casting and SynchonizationAttribute
, but it does not help. Just to let you know the events are executing in Async
manner so it does not block code execution, and both proxy and original object exist in same app domain.
I tried with two object, one holding reference of second, and when property of first is changed, it try to change property of second, but it did not invoke PostProcess
.
Basically I need to make a tree where various objects are depending on property of other objects. And when any one property is changed, it should trigger its watcher, and this could spread like a chain untill no watcher is found. I am trying it with ContextBoundObject.
Sample:
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);
});
}
}
Main method
PowerSwitch s1 = new PowerSwitch();
Bulb b1 = new Bulb();
b1.Watch(s1, "IsOn");
s1.IsOn = true; //<-- b1.update is called after this
Please suggest alternate or better way to implement what I want to achieve.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来您非常接近观察者模式,其中观察者订阅某个对象上的状态通知主题。
在该模式中,b1.IsOn = true 将包含循环浏览观察者并通知它们更改的代码。我想如果你想观察一个对象的很多属性,你可以封装通知代码。然后 b1.IsOn 可以只包含一行内容,如下所示:
这看起来很像您正在做的事情...如果您阅读了该模式,您可能最终会感到更加自信,也许您可以进行一些更改以标准化您的代码。
顺便说一句,.Net 中内置了一些用于此目的的东西 - IObservable(T) 。我没用过这个,但看起来很强大。
It looks like you're very close to the observer pattern, where Observers subscribe to status notifications on a Subject.
In that pattern, b1.IsOn = true would contain code that cycles through the Observers and notifies them of changes. I guess if you wanted to observe a lot of properties on one object, you could encapsulate the notification code. Then b1.IsOn could just have a single line that says something like:
This seems a lot like what you're doing... If you read up on the pattern you might end up feeling a little more confident, and maybe you could make a few changes to standardize your code.
By the way, there is something built into .Net for this -- IObservable(T). I haven't used this, but it looks strong.