2009-10-05 9 views
0

J'essaie de comprendre les événements de domaine. Disons que j'ai un objet client et qu'il déclenche l'événement OnCustomerInserted. Je souhaite que mon cours de service de messagerie électronique s'abonne à cet événement afin que chaque fois que l'événement est déclenché, un e-mail est envoyé.Comprendre les événements de domaine

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(); 
      } 
     } 
    } 

Et voici le CustomerRepository:

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

      customer.Id = 2; 

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

Enfin, voici la classe simple EmailService:

public class EmailService 
    { 
     public EmailService() 
     { 

     } 

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

MISE À JOUR:

encore le code ci-dessous est un peu laid!

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); 
      } 
     } 


} 

Je mis à jour mon dépôt et utilise StructorMap de créer une instance du référentiel

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; 
     } 

Le code est toujours pas bon puisque maintenant le constructeur CustomerRepository est se bondé. Le EmailService est propre comme suit:

public class EmailService : IEmailService 
    { 
     public EmailService() 
     { 

     } 

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

Déplacez le code d'abonnement _out of_ 'CustomerRepository' et placez-le dans le constructeur' EmailService'. –

Répondre

0

Déplacer CustomerInserted de Customer à CustomerRepository et vous serez très bien. Et tweak CustomerInsertedHandler pour qu'il contient une référence à l'objet Customer inséré:

public delegate void CustomerInsertedHandler(Customer insertedCustomer); 

Ou faire plus en ligne avec le reste du .NET:

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

Ainsi, la structure globale sera aussi suit:

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

mais comment m'abonner à l'événement au service de messagerie. J'ai déplacé l'événement dans le dépôt! –

+0

Merci pour votre aide! Je vais vérifier DI et Service Locator. –

+0

Merci! J'ai mis à jour le post ci-dessus pour inclure CustomerRepository dans StructureMap et il crée un objet de IEmailService. –

1

Udi Dahan a un bon exemple sur son blog: http://www.udidahan.com/2008/08/25/domain-events-take-2/.

L'idée de base est de créer un événement en tant qu'objet de première classe dans votre modèle de domaine. Celui qui en a besoin peut s'abonner à l'événement et le publier.

+0

S'il vous plaît vérifier ma mise en œuvre ci-dessus! –

Questions connexes