在我的域层中,所有域对象都会发出事件(类型为InvalidDomainObjectEventHandler),以指示调用IsValid属性时的无效状态。
在aspx代码隐藏中,我必须手动连接域对象的事件,如下所示:
_purchaseOrder.AmountIsNull += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoReason += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.BothNewAndExistingSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
请注意,在每种情况下都会调用相同的方法,因为InvalidDomainobjectEventArgs类包含要显示的消息。
有没有什么方法可以编写单个语句来一次性连接InvalidDomainObjectEventHandler类型的所有事件?
由于
大卫
答案 0 :(得分:5)
我认为你不能在一个声明中做到这一点..但你可以使代码更容易读取:
_purchaseOrder.AmountIsNull += HandleDomainObjectEvent;
_purchaseOrder.NoReason += HandleDomainObjectEvent;
_purchaseOrder.NoSupplier += HandleDomainObjectEvent;
_purchaseOrder.BothNewAndExistingSupplier += HandleDomainObjectEvent;
除此之外 - 似乎答案是否定的:(
答案 1 :(得分:3)
您可以在某个基类(或某个帮助程序类中,或在PurchaseOrder
类本身中创建聚合事件,如果您有权访问它):
abstract class BaseOrderPage : Page {
PurchaseOrder _purchaseOrder = new PurchaseOrder();
...
public event InvalidDomainObjectEventHandler InvalidDomainObjectEvent {
add {
_purchaseOrder.AmountIsNull += value;
_purchaseOrder.NoReason += value;
_purchaseOrder.NoSupplier += value;
_purchaseOrder.BothNewAndExistingSupplier += value;
}
remove {
_purchaseOrder.AmountIsNull -= value;
_purchaseOrder.NoReason -= value;
_purchaseOrder.NoSupplier -= value;
_purchaseOrder.BothNewAndExistingSupplier -= value;
}
}
}
然后在派生类中使用它:
InvalidDomainObjectEvent += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
C#2.0及以上:
InvalidDomainObjectEvent += HandleDomainObjectEvent;
我已成功使用此技术聚合events of the FileSystemWatcher
类。
答案 2 :(得分:2)
您可以使用反射自动执行此操作。我想你想要这样的东西:
public static void WireEvents(object subject)
{
Type type = subject.GetType();
var events = type.GetEvents()
.Where(item => item.EventHandlerType == typeof(InvalidDomainObjectEventHandler));
foreach (EventInfo info in events)
info.AddEventHandler(subject, new InvalidDomainObjectEventHandler(HandleDomainObjectEvent));
}
然后,在创建新对象时所要做的就是:
PurchaseOrder _purchaseOrder = new PurchaseOrder();
HelperClass.WireEvents(_purchaseOrder);
不要忘记,如果您创建PurchaseOrder
和其他类似对象,那么反射会对性能造成影响。
编辑 - 其他说明:您需要using System.Reflection
指令。就目前而言,此代码需要var
关键字的C#3和Where()
方法的.net框架3.5(如果它不是自动生成的,则需要using System.Linq;
)。
正如David在稍后的回答中所做的那样,可以在不更改早期版本的基本功能的情况下重写它。
答案 3 :(得分:0)
您可以考虑将事件处理程序放入接口。然后你附上界面:
public interface IPurchaseOrderObserver
{
void AmountIsNullEventHandler(WhateverArgs);
void NoReasonEventHandler(WhateverArgs);
void NoSupplierEventHandler(WhateverArgs);
void BothNewAndExistingSupplierEventHandler(WhateverArgs);
}
_purchaseOrder.RegisterObserver(DomainObject);
您可以将这四行放入RegisterObeserver方法,或者替换事件并直接调用接口。
答案 4 :(得分:0)
我看了Bob Sammers的建议。编译器不喜欢GetEvents()返回的EventInfo []的.Where方法,但是我将代码略微更改为以下内容:
private void HookUpEvents()
{
Type purchaseOrderType = typeof (PurchaseOrder);
var events = purchaseOrderType.GetEvents();
foreach (EventInfo info in events)
{
if (info.EventHandlerType == typeof(Kctc.Data.Domain.DomainObject.InvalidDomainObjectEventHandler))
{
info.AddEventHandler(_purchaseOrder, new Kctc.Data.Domain.DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent));
}
}
}
在我将这个方法添加到页面之后,这一切都非常适合hunky dory。我可以将事件添加到采购订单对象中,而不必记住将它们单独连接起来,这正是我想要的。