2010-08-08 47 views
1

说我有以下两类:如何将事件附加到普通类中的方法?

public class User 
    { 
     public int ID { get; } 

     public string Name { get; set; } 

     public void ChangeName(string newName) 
     { 
      Name = newName; 
     } 


    } 

    public class Mail 
    { 
     public void SendUserInfoChangeEmail() 
     { 
      throw new NotImplementedException(); 
     } 
    } 

和我想做的事情是:在使用该方法的人编辑用户对象名称ChangeNameSendUserInfoChangeEmail都会自动调用。

而且我知道我可以使用事件来处理这个问题,但我想要的是使第三静态类在它建立这样的活动,并且将在班说:附上ChangeNameSendUserInfoChangeEmail

我怎样才能做到这一点?

注:
我不想把任何事件 处理或代表两个用户 和电子邮件类我想要的一切 通过这个第三个新 静态类来管理。

+1

关于您的编辑:不要让不合理的技术要求。 – siride 2010-08-08 15:26:07

+0

其实我想制作类似http://weblogs.asp.net/rashid/archive/2009/03/05/use-event-aggregator-to-make-your-application-more-extensible.aspx但更简单,我想创建一个例子,完成这个http://martinfowler.com/eaaDev/EventAggregator.html – 2010-08-08 16:06:33

回答

0

你的用户类需要有一个与用户名的更改触发的事件。无论哪个对象跟踪用户都需要有一个订阅用户名更改事件的方法,并且可以创建一个新的Mail对象并发送必要的电子邮件。

要创建在用户类的事件,这样做:

public class User { 
    public event EventHandler UserNameChanged; 

    private string m_Name; 
    public string Name { 
     get { return m_Name; } 
     set { 
      if(m_Name != value) { 
       m_Name = value; 
       // assuming single-threaded application 
       if(UserNameChanged != null) 
        UserNameChanged(this, EventArgs.Empty); 
      } 
     } 
    } 

    // everything else is the same... 
} 

在管理代码,你将不得不处理该事件的方法:

private void Handle_UserNameChanged(object sender, EventArgs e) { 
    User user = (User)sender; 
    // create the mail object and send it   
} 

我不认为现在你的Mail类现在可以工作。如果Mail意图表示邮件消息,那么它应该提供设置邮件消息并发送所需的所有方法和属性。但是,如果您只需使用.NET框架的邮件系统发送电子邮件,则Mail可以是一个静态类,其中包含发送各种类型的预定义电子邮件的方法(不是最好的设计,但可以作为开始),包括一个方法SendUserInfoChangeEmail()。这可以由您的事件处理程序调用。

0

在设计模式方面,为什么你想除了Name物业供应完全相同的目的只是干净多了一个ChangeUser方法看看在Observer Pattern

0
  1. SendUserInfoChangeEmail是什么意思?它的目的是什么?为什么在Mail类中?在User课程或类似的课程中,这样做会更好吗?
  2. 为什么静态的第三课?

不管怎么说,我将在User类更改为这样的事情:

public class User : INotifyPropertyChanged 
{ 
    public int ID { get; } 

    private string name; 
    public string Name 
    { 
     get { return name; } 
     set 
     { 
      if(value != name) 
      { 
       name = value; 
       NotifyPropertyChanged("Name"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String name) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 
} 

然后在无论你喜欢它,你的静态类也好,都订阅该事件并发送电子邮件时,名称已更改。

+0

确保实施INotifyPropertyChanged。 – siride 2010-08-08 15:56:16

+0

事实上,我想使这样的http://weblogs.asp.net/rashid/archive/2009/03/05/use-event-aggregator-to-make-your-application-more-extensible.aspx但更多简单的,我想创建一个例子,完成这个http://martinfowler.com/eaaDev/EventAggregator.html – 2010-08-08 15:56:16

+0

@siride:谢谢,忘了补充 – Svish 2010-08-08 17:44:32

1

我认为你所说的有时被称为事件代理类。当你不想在两个类之间有很强的依赖关系时,它是一个充当中介的类。一般来说,我尽量避免每当我可以获得对触发对象的引用时使用它,但是有一些合法的场景,事件的使用者可能不知道所有可能触发它的实例。例如,我以前使用过这个功能的地方是在有多个数据视图并且数据不在可以直接引用的单个域对象中时提供全局数据刷新事件。

public class User 
{ 
    public int ID { get; } 

    public string Name { get; set; } 

    public void ChangeName(string newName) 
    { 
     Name = newName; 
     UserEventProxy.FireUserNameChanged(this); 
    } 
} 

public class UserEventArgs : EventArgs 
{ 
    public User User{get; set;} 
} 

/// <summary> 
/// 
/// </summary> 
public static class UserEventProxy 
{ 
    /// <summary> 
    /// Indicates that the associated user's name has changed. 
    /// </summary> 
    public static event EventHandler<UserEventArgs> UserNameChanged; 

    /// <summary> 
    /// Fires the UserNameChanged event. 
    /// </summary> 
    /// <param name="user">The user reporting the name change.</param> 
    public static void FireUserNameChanged(User user) 
    { 
     EventHandler<UserEventArgs> handler = UserNameChanged; 
     if (handler != null) 
     { 
      UserEventArgs args = new UserEventArgs() 
      { 
       User = user 
      }; 

      //Fire the event. 
      UserNameChanged(user, args); 
     } 
    } 
} 


public class Mail 
{ 
    public Mail() 
    { 
     UserEventProxy.UserNameChanged += new EventHandler<UserEventArgs>(UserEventProxy_UserNameChanged); 
    } 

    private void UserEventProxy_UserNameChanged(object sender, UserEventArgs e) 
    { 
     User user = e.User; 

     // 
     //Presumably do something with the User instance or pass it to 
     //the SendUserInfoChangedEmail method. to do something there. 
     // 

     SendUserInfoChangeEmail(); 
    } 


    public void SendUserInfoChangeEmail() 
    { 
     throw new NotImplementedException(); 
    } 
} 
1

你想要的图案似乎是Mediator。这个简单的例子给你的想法:

public class User { 
    public event EventHandler NameChanged = delegate { }; 
    public int ID { get; } 
    public string Name { get; private set; } 
    public void ChangeName(string newName) { 
    if (newName != Name) { 
     NameChanged(this, EventArgs.Empty); 
    } 
    Name = newName; 
    } 
} 

public class UserMediator { 
    User _user; 
    EventHandler _eh; 
    public UserMediator(User user, Action onNameChanged) { 
    _user = user; 
    _eh = (src, args) => onNameChanged(); 
    _user.NameChanged += _eh; 
    } 
    public void Detach() { 
    _user.NameChanged -= _eh; 
    } 
} 

别的地方:

var user = new User(); 
var mail = new Mail(); 
new UserMediator(user, mail.SendUserInfoChangeEmail); 
相关问题