2010-08-08 53 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); 
相關問題