2012-04-10 9 views
0

Ich habe einen benutzerdefinierten Basistyp namens MyEntityBase für die Oberklasse der Typen in meiner selbst erstellten DataContext Klasse, MyContext. Beim Versuch, einen Scheindatenkontext zu erstellen, entschied ich mich, INotifyPropertyChanged unter MyEntityBase zu implementieren, damit ich Änderungen generisch verfolgen kann.INotifyPropertyChanged auf benutzerdefinierten DataContext Basistyp nicht ausgelöst

Hier ist, was meine Klasse wie folgt aussieht:

public abstract class MyEntityBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
} 

auf dieser Klasse basiert, ich habe eine generische Repository<T> Klasse erstellt für Instanzen eines bestimmten Typs von Einheit zu speichern. Die Grundidee dieser Klasse besteht darin, Methoden bereitzustellen, die einem Datenkontext ähnlich sind, aber stattdessen von einer speicherinternen Liste unterstützt werden. Ich möchte auch Tracking-Änderungen simulieren, da der Change-Set wichtig für die Geschäftslogik unserer Anwendung für die Synchronisierung mit 3rd-Party-Systemen ist.

Hier ist eine grundlegende Shell Implementierung von Repository<T>:

public class Repository<T> 
    where T : MyEntityBase, INotifyPropertyChanged 
{ 
    protected List<T> _data; 
    public Repository(List<T> data) 
    { 
     this._data = data; 
     foreach (var entity in this._data) 
     { 
      entity.PropertyChanged += new PropertyChangedEventHandler(entity_PropertyChanged); 
     } 
    } 

    protected void entity_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     Console.WriteLine("HERE"); 
    } 
} 

Jetzt erstelle ich ein einfaches Repository vom Typ Employee, einige Daten füllen, und versuchen, Eigenschaften der Daten zu ändern. Ich würde erwarten, dass das PropertyChanged-Ereignis ausgelöst wird, da das Objekt Employee Eigenschaftsänderungsbenachrichtigung von der automatisch generierten DataContext integriert hat. Allerdings, wenn ich den folgenden Code ausführen, sehe ich nicht HERE in der Ausgabe überall erzeugt:

var data = new List<Employee> { 
    new Employee { FirstName = "Bob" }, 
    new Employee { FirstName = "Joe" }, 
}; 

var repo = new Repository<Employee>(data); 

// This should fire the PropertyChanged event 
data[0].FirstName = "John"; 

Was mache ich falsch?


aktualisieren: Wenn ich die Zeile, die folgend auf das Ereignis abonniert ändern:

(entity as Employee).PropertyChanged += ... 

Dann funktioniert es gut. Jedoch ist T bereits bekannt Employee und entity ist eine Instanz des Typs Employee, also was ist der Unterschied? Selbst wenn ich die event in MyEntityBase zu virtual mache, funktioniert es immer noch nicht richtig.

+1

Ich kopierte Ihren Code hier http://dotnetpad.net/ViewPaste/HfGdC7ypCEC4TYZ-Vb7I0A (und zu Entity virtuell hinzugefügt). Das scheint zu funktionieren. Vielleicht gibt es etwas in Employee, das es kaputt macht? – Patrick

+0

Nun, ich habe keine Kontrolle über "Mitarbeiter", da es automatisch mit 'SQLMetal' generiert wird. Aber es sieht so aus, als ob der Unterschied darin bestünde, dass das Schlüsselwort "override" nicht vorhanden ist, und das Entfernen führt dazu, dass es erneut in Ihrem Testcode fehlschlägt. – mellamokb

+0

Es sieht also so aus, als müsste ich die geerbten Klassen wie 'Employee' zwingen,' PropertyChanged' immer zu überschreiben, obwohl das Schlüsselwort 'override' nicht vorhanden ist. Ist so etwas überhaupt möglich? – mellamokb

Antwort

0

Ich habe eine praktikable Lösung implementiert, so werde ich meine eigene Frage beantworten. Da ich bereits über ein Befehlszeilenprogramm FindAndReplaceText.exe verfüge, mit dem ich einige Anpassungen an der automatisch generierten Datei MyDataContext.dbml vornimmt, habe ich am Ende einen weiteren Aufruf hinzugefügt, bei dem alle Ereignisse in der generierten MyDataContext-Klasse geändert werden, um override einzuschließen. Gepaart mit meiner Basisklasse Gebrauch machen virtual in den Definitionen der Ereignisse, löst dies das Problem:

FindAndReplaceText.exe -c^
    MyDataContext.cs^
    "public event"^
    "public override event" 

Nun werden die Eigenschaftsänderungen benachrichtigen richtig in meinem Test-Code.

Verwandte Themen