在哪里订阅内部对象的事件? [英] Where to subscribe to events of the inner object?

查看:201
本文介绍了在哪里订阅内部对象的事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常遇到一个情况,我必须决定在哪里订阅内部对象的事件?



例如,我有一个对象模型如下所示:

  class ClassA 
{
public event EventHandler SomeEvent1;
public event EventHandler SomeEvent2;
public event EventHandler SomeEvent3;
public event EventHandler SomeEvent4;
}

class ClassB
{
private ClassA a;
public ClassA A
{
get
{
return this.a;
}
}

public ClassB()
{
this.a = new ClassA();
//这里订阅一些事件(例如SomeEvent1和SomeEvent2)
// this.a.SomeEvent1 + = OnSomeEvent1Raised;
// this.a.SomeEvent2 + = OnSomeEvent2Raised;
}
}

class ClassC
{
public ClassB B {get; }
}

class ClassD
{
public ClassC C {get; }

public void SomeMethod()
{
//此处订阅对象C.B.A.的另一个事件。例如:
C.B.A.SomeEvent3 + = OnSomeEvent3Raised;
C.B.A.SomeEvent4 + = OnSomeEvent4Raised;
}

private void OnSomeEvent4Raised(object sender,EventArgs e)
{
throw new NotImplementedException();
}

private void OnSomeEvent3Raised(object sender,EventArgs e)
{
throw new NotImplementedException();
}
}

我试图创建像UML图:



我的项目的现有代码的结构有这样的对象模型存在的地方(它有一个地方,其中订阅事件实现如上面的例子 - CBASomeEvent + =)。
我不喜欢它,想改变它。
我想从这里得到关于这种情况的最佳实践。



替代方法是复制classB,classC,classD中的classA的所有事件。
然后将所有订阅的事件替换为 ONE PLACE (我的意思是在classB中,我们将订阅/取消订阅ClassA对象的所有事件,在classC中,我们将订阅/取消订阅对于classB的对象的所有事件,等等...)在这种情况下,所有的订阅和取消订阅将在一个地方。希望你明白我在这里的意思。



再次,请依靠您的知识和经验告诉我们如何解决这种情况。



更新



您是否同意我的订阅和取消订阅活动必须放在ONE PLACE中?
请回答这个附加问题。



提前感谢

解决方案

您可能对事件聚合器



它基本上是将发布者与订阅者分离 - 它是一种事件容器。您可以通过依赖注入获取事件聚合器(例如,MEF),用于每个您要订阅或发布的类。



我个人使用和喜欢它的方式最重要的是,Rob Eisenberg在Caliburn Micro中实施了事件聚合器:





在您的案例对象A ,B和C将共享事件聚合器的相同实例,这意味着一旦在此事件聚合器上发布事件,所有这些对象就会识别它。由于不同的处理事件,A,B和C类的行为可能会有所不同。



编辑



事件聚合器的使用是,您使用类的实例订阅聚合器本身。发布者和订阅者类之间的连接发生在依赖于事件聚合器的同一个实例。在Caliburn.Micro订阅某些事件时,通过实现通用接口( IHandle<> )。
例如:如果您要订阅 MyCustomEvent ,则实现 IHandle< MyCustomEvent> 界面在要订阅的班级。
这需要从 IHandle< MyCustomEvent> 界面中实现 void Handle(MyCustomEvent e)方法对于这种类型的事件。每次在共享事件聚合器上发布(新) MyCustomEvent 时,此方法被调用。


I'm often encountering a situation where I must decide where to subscribe to events of the inner object?

For example, I have an object model looks like this:

class ClassA
{
    public event EventHandler SomeEvent1;
    public event EventHandler SomeEvent2;
    public event EventHandler SomeEvent3;
    public event EventHandler SomeEvent4;
}

class ClassB
{
    private ClassA a;
    public ClassA A 
    {
        get
        {
            return this.a;
        }
    }

    public ClassB()
    {
        this.a = new ClassA();
        // here subscribe to some events (for example, SomeEvent1 and SomeEvent2)
        // this.a.SomeEvent1 += OnSomeEvent1Raised;
        // this.a.SomeEvent2 += OnSomeEvent2Raised;
    }
}

class ClassC
{
    public ClassB B { get; }
}

class ClassD
{
    public ClassC C { get; }

    public void SomeMethod()
    {
        // Here subscribe to another ones events of object C.B.A. For example:
        C.B.A.SomeEvent3 += OnSomeEvent3Raised;
        C.B.A.SomeEvent4 += OnSomeEvent4Raised;
    }

    private void OnSomeEvent4Raised(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    private void OnSomeEvent3Raised(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

I've tried to create something like a UML diagram:

Structure of existing code of my project has places where such object model exist (its has a places where subscribing to events implemented as in the example above - C.B.A.SomeEvent+= ). I don't like it and want to change it. I want to here from you the best practices about this situation.

Alternative approach is to duplicate all events of classA in the classB, classC, classD. And then replace all subscriptions to events to ONE PLACE (I mean that in the classB we will subscribe/unsubscribe to all events of the object of ClassA. In the classC we will subscribe/unsubscribe to all events of the object of classB. And so on...) In this case all subscriptions and unsubscriptions will be in one place. Hope, you understand what I mean here.

Again, please rely on your knowledge and experience tell we how to resolve this situation.

UPDATE

Do you agree with me that subscriptions and unsubscriptions to events must be placed in ONE PLACE ? Please, answer on this additional question too.

Thanks in advance.

解决方案

You might be interested in an event aggregator.

What it basically does is decoupling the publishers from subscribers - it's kind of a event container. You could get the event aggregator through dependency injection (e.g. MEF) for each class you'd like to subscribe or publish from.

The way I personally use and like it the most, is the way Rob Eisenberg implemented the event aggregator in Caliburn Micro:

In your case object A, B and C would share the same instance of an event aggregator, which means as soon as events are published on this event aggregator, all these objects recognize it. Class A, B and C are able behave differently, caused by different handling of certain events.

EDIT

The use of an event aggregator is, that you subscribe to the aggregator itself with an instance of a class. The connection between publisher and subscriber class happens through relying to the same instance of the event aggregator. In case of Caliburn.Micro subscription to certain events happens through implementing a generic interface (IHandle<>). For example: if you'd like to subscribe to MyCustomEvent you implement the IHandle<MyCustomEvent> interface in the class to be subscribed. This requires an implementation of the void Handle(MyCustomEvent e) method from the IHandle<MyCustomEvent> interface for this type of event. This method gets called everytime a (new) MyCustomEvent is published on the shared event aggregator.

这篇关于在哪里订阅内部对象的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆