我正在尝试了解域事件。假设我有一个客户对象,它会引发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!");
}
}
答案 0 :(得分:1)
Udi Dahan在他的博客上有一个很好的例子:http://www.udidahan.com/2008/08/25/domain-events-take-2/。
基本思想是将事件创建为域模型中的第一个类对象。然后,任何需要的人都可以订阅该活动,并发布它。
答案 1 :(得分:0)
将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);
}
}