2012-11-16 68 views
1

这里是Register方法的singature:为什么我们需要为IMessenger.Subscribe()明确设置收件人?

IMessanger.Register<TMsg>(object recipient, Action<TMsg> action); 

为什么我们需要收件人如果动作保持在其目标属性的参考? 当给定动作不使用定义类的实例成员时,则Target为空。
但这种情况很少发生。我的意思是,这不是我们使用事件处理程序的常见方式。

我想了解为什么没有附加的Register方法签名没有收件人参数?我错过重要的东西吗?

IMessanger.Register<TMsg>(Action<TMsg> action); 

回答

2

实际上,您可以从应用程序中的任何位置注册收件人,而不仅仅是收件人的类。例如,请考虑以下情形:

public class ClassA : ViewModelBase 
{ 
    public ClassA() 
    { 
     Messenger.Default.Register<SomeMessage>(this, SomeAction); 
     Messenger.Default.Register<SomeMessage>(ViewModelLocator.ClassB, SomeAction); 
    } 

    private void SomeAction(SomeMessage msg) 
    { 
     // do something 
    } 
} 

public class ClassB : ViewModelBase 
{ 
    public ClassB() 
    { 

    } 
} 

在第二Registor方法调用的情况下,工作的对象属性将不会是相同的收件人参数。因此,为了保持一致,始终需要收件人参数是最安全的。

当然,您认为这种情况可能不如您仅仅通过this作为收件人的情形。因此,在这种情况下,如果输入this变得繁冗的你,那么你总是可以定义它只是沿着实际Register方法传递目标属性自己Register扩展方法:

public static class MessengerHelper 
{ 
    public static void Register<TMessage>(this IMessenger messenger, Action<TMessage> action) 
    { 
     messenger.Register<TMessage>(action.Target, action); 
    } 
} 

然后,您可以注册类似的消息这个:

public class ClassA : ViewModelBase 
{ 
    public ClassA() 
    { 
     Messenger.Default.Register<SomeMessage>(SomeAction); 
    } 

    private void SomeAction(SomeMessage msg) 
    { 
     // do something 
    } 
} 
+0

但是如何使用收件人价值?是不是只有行动足以对绑定的消息作出反应?或者TDaver已经说过,这是一个通过单一呼叫注销所有处理程序的工具。 –

+1

如何使用收件人值?各种消息类具有对应于特定收件人的“目标”属性。因此,如果您在发送消息之前设置了“目标”属性,那么只有该对象才会收到消息。因此,消息系统需要您在调用“注册”方法时指定收件人,以便将正确的消息发送给正确的收件人。如果您在注册邮政服务时未给您的名字,您是否希望收到您的邮件? – bugged87

+0

答案TDaver提供的解释只是解释了Messenger类提供的便利,因为您的消息已经注册到收件人。但是,它并没有解释收件人的目的。该目的仅用于在设置消息的目标属性时查找正确的对象。 – bugged87

0

这样做,你可以说Messenger.UnregisterRecepient(recepient);然后取消订阅注册到这个接收器的每个动作。

+1

我认为OP意味着什么的影响“为什么注册'方法假设收件人基于Action参数的Target属性?” – bugged87