了解域事件

时间:2009-10-05 14:55:26

标签: c#

我正在尝试了解域事件。假设我有一个客户对象,它会引发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!");
        }
    }

更新:

下面的代码仍然有点难看!

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

2 个答案:

答案 0 :(得分:1)

Udi Dahan在他的博客上有一个很好的例子:http://www.udidahan.com/2008/08/25/domain-events-take-2/

基本思想是将事件创建为域模型中的第一个类对象。然后,任何需要的人都可以订阅该活动,并发布它。

答案 1 :(得分:0)

CustomerInsertedCustomer移至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);
    }
}