2009-10-05 4 views
0

Я пытаюсь понять события домена. Предположим, у меня есть объект клиента, и он вызывает событие OnCustomerInserted. Я хочу, чтобы мой класс службы электронной почты подписался на это событие, чтобы всякий раз, когда событие было поднято, отправляется электронное письмо.Общие сведения о событиях домена

public class Customer 
    { 
     public delegate void CustomerInsertedHandler(); 

     public event CustomerInsertedHandler CustomerInserted; 

     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 

     public void OnCustomerInserted() 
     { 
      if(CustomerInserted != null) 
      { 
       CustomerInserted(); 
      } 
     } 
    } 

А вот CustomerRepository:

public class CustomerRepository 
    { 
     public void Add(Customer customer) 
     { 
      // add the customer 

      customer.Id = 2; 

      if(customer.Id > 0) 
      { 
       // raise the event! 
      } 
     } 
    } 

Наконец, вот простой класс EmailService:

public class EmailService 
    { 
     public EmailService() 
     { 

     } 

     public void Send() 
     { 
      Console.WriteLine("Email has been sent!"); 
     } 
    } 

UPDATE:

Еще ниже код немного некрасиво!

public class CustomerRepository 
    { 
     public delegate void CustomerInsertedHandler(Customer newCustomer); 
     public event CustomerInsertedHandler CustomerInserted; 

     public void OnCustomerInserted(Customer newCustomer) 
     { 
      if (CustomerInserted != null) 
       CustomerInserted(newCustomer); 
     } 

     public void Add(Customer customer) 
     { 
      // add the customer 

      customer.Id = 2; 


      if(customer.Id > 0) 
      { 
       var emailService = new EmailService(); 
       CustomerInserted += emailService.Send; 

       // raise the event! 
       OnCustomerInserted(customer); 
      } 
     } 


} 

Я обновил свой репозиторий и использую StructorMap для создания экземпляра репозитория

public class CustomerRepository : ICustomerRepository 
    { 
     public delegate void CustomerInsertedHandler(Customer newCustomer); 
     public event CustomerInsertedHandler CustomerInserted; 
     private IEmailService _emailService; 

     public CustomerRepository(IEmailService emailService) 
     { 
      _emailService = emailService; 
      CustomerInserted += _emailService.Send; 
     } 

код все еще не очень хорошо, так как в настоящее время конструктор CustomerRepository становится тесно. EmailService чист следующим образом:

public class EmailService : IEmailService 
    { 
     public EmailService() 
     { 

     } 

     public void Send(Customer customer) 
     { 
      Console.WriteLine("Email Sent!"); 
     } 
    } 
+0

Переместить код подписки _out_ 'CustomerRepository' и переместить его в конструктор' EmailService'. –

ответ

0

Move CustomerInserted от Customer к CustomerRepository, и вы будете просто отлично. И настроить CustomerInsertedHandler так, что она будет содержать ссылку на вставленные Customer объекта:

public delegate void CustomerInsertedHandler(Customer insertedCustomer); 

Или сделать это в соответствии с остальной частью .NET:

public delegate void CustomerInsertedHandler(object sender, CustomerInsertedEventArgs e); 

Таким образом, общая структура будет как следующим образом:

public delegate void CustomerInsertedHandler(Customer newCustomer); 

public class CustomerRepository 
{ 
    public event CustomerInsertedHandler CustomerInserted; 

    private void RaiseCustomerInserted(Customer newCustomer) 
    { 
     if(CustomerInserted != null) 
      CustomerInserted(newCustomer); 
    } 

    public void Add(Customer customer) 
    { 
     // add the customer 

     customer.Id = 2; 

     if(customer.Id > 0) 
      RaiseCustomerInserted(customer); 
    } 
} 

public class EmailService 
{ 
    // Using autoproperty syntax from C# 3.0 
    public CustomerRepository { get; set; } 

    public EmailService() 
    { 

    } 

    public void Initialize() 
    { 
     // 
     // You need to get hold of a reference to CustomerRepository somehow. 
     // Google for either "Dependency Injection" or "Service Locator". 
     CustomerRepository.CustomerInserted += delegate(Customer c) 
      { Send(c); }; 

    } 

    public void Send(Customer customer) 
    { 
     Console.WriteLine("Email has been sent to " + customer.Name); 
    } 
} 
+0

, но как я могу подписаться на событие в службу электронной почты. Я переместил событие в хранилище! – 2009-10-05 15:08:24

+0

Спасибо за помощь! Я проверю DI и Service Locator. – 2009-10-05 15:49:31

+0

Спасибо! Я обновил вышеуказанную запись, включив CustomerRepository в StructureMap и создав объект IEmailService. – 2009-10-05 19:43:07

1

Уди Даан есть хороший пример на своем блоге: http://www.udidahan.com/2008/08/25/domain-events-take-2/.

Основная идея - создать Событие как объект первого класса в вашей модели домена. Тогда кто-то, кто должен, может подписаться на это событие, а также опубликовать его.

+0

Пожалуйста, проверьте мою реализацию выше! – 2009-10-05 15:18:58

Смежные вопросы