2010-05-12 12 views
6

In meiner Domäne-Ebene emittieren alle Domänenobjekte Ereignisse (vom Typ InvalidDomainObjectEventHandler), um einen ungültigen Status anzugeben, wenn die IsValid-Eigenschaft aufgerufen wird.C#: Schließen Sie alle Ereignisse von Objekt in Einzelanweisung an

Auf einem aspx Code-Behind, habe ich die Ereignisse für das Domain-Objekt wie folgt manuell verdrahten:

_purchaseOrder.AmountIsNull += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent); 
_purchaseOrder.NoReason += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent); 
_purchaseOrder.NoSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent); 
_purchaseOrder.BothNewAndExistingSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent); 

Beachten Sie, dass die gleiche Methode in jedem Fall aufgerufen wird, da die Nachricht der InvalidDomainobjectEventArgs Klasse enthält anzuzeigen .

Gibt es eine Möglichkeit, eine einzelne Anweisung zu schreiben, um alle Ereignisse vom Typ InvalidDomainObjectEventHandler auf einmal zu verkabeln?

Dank

David

Antwort

0

Ich sah Bob Sammers Vorschlag. Der Compiler wurde nicht gefällt die .Where Methode des Eventinfo [] von GetEvents() zurückgegeben wird, aber ich habe den Code leicht wie folgt geändert:

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

Nachdem ich diese Methode der Seite hinzugefügt, es Alles hat absolut gut gelaunt funktioniert. Und ich kann Ereignisse zu dem Bestellobjekt hinzufügen, ohne daran denken zu müssen, sie einzeln anzuhängen, was genau das ist, was ich wollte.

5

Ich glaube nicht, dass Sie dies in einer einzigen Anweisung tun .. Aber Sie können den Code readible wie diese machen:

_purchaseOrder.AmountIsNull += HandleDomainObjectEvent; 
_purchaseOrder.NoReason += HandleDomainObjectEvent; 
_purchaseOrder.NoSupplier += HandleDomainObjectEvent; 
_purchaseOrder.BothNewAndExistingSupplier += HandleDomainObjectEvent; 

Other than that - scheint wie die Antwort nein :(

+0

'Nein kann' ist immer noch eine gute Antwort! Danke – David

0

Sie könnten in Betracht ziehen, die Event-Handler in eine Schnittstelle zu bringen. Dann befestigen Sie die Schnittstelle:

Sie fügen diese vier Zeilen entweder in die Methode RegisterObeserver ein, oder Sie ersetzen die Ereignisse und rufen die Schnittstellen direkt auf.

+0

Nicht sicher, ich folgte diesem, aber es scheint immer noch, dass ich alle Ereignisse irgendwo direkt erwähnen muss, in der Schnittstelle, wenn nicht auf der Webseite ... ist das richtig? – David

+0

Ja, Sie müssen alle Ereignisse irgendwo erwähnen, aber nur an einem einzigen Ort. –

2

Sie können Reflektionen verwenden, um dies automatisch zu tun. Ich denke, dass Sie so etwas wie dies wollen:

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

Dann alles, was Sie tun müssen, wenn Sie ein neues Objekt erstellen, ist dies:

PurchaseOrder _purchaseOrder = new PurchaseOrder(); 
HelperClass.WireEvents(_purchaseOrder); 

Vergessen Sie nicht, dass es eine Leistungseinbuße mit Reflexion das wird offensichtlich, wenn Sie PurchaseOrder s und andere ähnliche Objekte in großen Zahlen erstellen.

Bearbeiten - andere Hinweise: Sie benötigen eine using System.Reflection Richtlinie. So wie es steht, benötigt dieser Code C# 3 für das Schlüsselwort var und .NET Framework 3.5 für die Methode Where() (und - wenn es nicht automatisch generiert wird - using System.Linq;).

Wie David in einer späteren Antwort getan hat, kann es ohne Änderung der grundlegenden Funktionalität für frühere Versionen neu geschrieben werden.

+0

Wow! Ich kann nur Danke sagen! – David

+0

Ich konnte den Compiler nicht dazu bringen, die .Where-Methode zu akzeptieren, aber ich habe Ihren Code leicht umgeschrieben und ihn erneut hochgeladen. Vielen Dank für Ihre Hilfe! – David

+0

Hmmm. Mir geht es heute nicht sehr gut! Noch einmal, dieser Code ist getestet und ich habe derzeit eine Arbeitskopie in meinem Code-Editor. Ich schätze, wir sind nicht auf den gleichen Versionen. Sie haben nicht gesagt, worauf Sie abzielen, aber vielleicht hätte ich sagen sollen, dass dieser Code nur auf VS2008/.net 3.5 aufwärts funktioniert. –

3

Sie können ein Aggregat Ereignis in einem gewissen Basisklasse (oder in einer Hilfsklasse oder in der PurchaseOrder Klasse selbst, wenn Sie den Zugriff darauf) erstellen:

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

} 

Und dann einfach in der Verwendung abgeleiteten Klassen:

InvalidDomainObjectEvent += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent); 

C# 2.0 und höher:

InvalidDomainObjectEvent += HandleDomainObjectEvent; 

ich verwendet habe, th ist Technik erfolgreich zu aggregieren events of the FileSystemWatcher Klasse.

+0

Ich habe das vorher nicht gesehen, danke! – David

Verwandte Themen