2009-08-14 16 views
2

Ich bin Teil eines Teams mit der Aufgabe, unsere alte VB6 UI/COBOL-Datenbank-Anwendung zu modernen Zeiten zu überarbeiten. Bevor ich angestellt wurde, wurde die Entscheidung getroffen (vor allem auf Verkauf, ich bin sicher), die UI vor der Datenbank zu wiederholen. So, jetzt verwenden wir WPF und MVVM mit großer Wirkung, es war bisher erstaunlich, vor allem mit CSLA als Model-Layer.C# CSLA Business-Objekt-Dilemma: schreibgeschützt vs lesen/schreiben

Da unsere Entwicklung jedoch Seite an Seite mit der nächsten Version des alten Produkts läuft, sind wir ein wenig eingeschränkt. Wir können keine Änderungen (oder minimale Änderungen) an den an die COBOL-Datenbank gerichteten Anrufen vornehmen. Dies ist bisher in Ordnung, wenngleich Sie sich an die glorreichen Tage von SQL Server erinnern, wenn Sie es glauben können.

Wo ich einen besonders bösen Roadblock bezüglich unseres BO-Designs getroffen habe, ist im Umgang mit "leichten" Geschäftsobjekten, die in Listen zurückgegeben werden, und ihren "vollen" Gegenstücken. Lassen Sie mich versuchen, ein Beispiel zu konstruieren:

Nehmen wir an, wir haben ein Personenobjekt in der DB mit einer Reihe von Feldern. Wenn wir nach dieser Tabelle suchen, geben wir nicht alle Felder zurück, daher füllen wir unser lite-Objekt mit diesen Feldern. Diese Felder können eine Untergruppe der vollständigen Person sein oder auch nicht. Wir haben möglicherweise ein oder zwei Joins durchgeführt, um einige andere Informationen zu erhalten, die für die Suche spezifisch sind. Wenn wir jedoch unser Personenobjekt bearbeiten möchten, müssen wir einen weiteren Aufruf ausführen, um die Vollversion zum Füllen der Benutzeroberfläche zu erhalten. Dies lässt uns zwei Objekte und versuchen, ihren Zustand in 1 VM zu jonglieren, während wir versuchen, die Personenliste nach dem Löschen, Bearbeiten und Hinzufügen auf dem übergeordneten Objekt synchron zu halten. Ursprünglich habe ich unser Lite-Person-Objekt von ReadOnlyBase <> ableiten lassen. Aber jetzt, da ich mit dem gleichen Listenverhalten wie bei einer Liste voller BOs arbeite, außer mit halb voll, halb lite, denke ich, ich hätte einfach machen sollen, dass sowohl die Lite- als auch die Vollversion von BusinessBase < abstammen > und machte einfach die Setter-Eigenschaften der Lite-Version privat.

Hat jemand anders da draußen eine Lösung gefunden? Nachdem ich darauf geschlafen habe, habe ich diese mögliche Lösung gefunden. Was passiert, wenn wir die volle und Lite-Version unseres BO in einem anderen BO, wie diese wickeln:

public class PersonFull : BusinessBase<PersonFull> 
{ 
    ... 
} 
public class PersonLite : BusinessBase<PersonLite> 
{ 
    ... 
} 

public class Person : BusinessBase<Person> 
{ 
    public PersonFull PersonFull; 
    public PersonLite PersonLite; 
} 
public class PersonList : BusinessListBase<PersonList, Person> 
{ 
} 

Offensichtlich wäre alles CSLA registrierten Eigenschaften und so, aber aus Gründen der Kürze sind sie Felder. In diesem Fall würde Person and PersonList alle Factory-Methoden enthalten. Nach einer Suchoperation würde PersonList von Person-Objekten gefüllt, deren PersonLite-Mitglieder alle ausgefüllt waren und die PersonFull-Objekte alle null waren. Wenn wir die Vollversion benötigen, sagen wir einfach das Person-Objekt dazu, und jetzt haben wir unser PersonFull-Objekt, so dass wir die Editieroberfläche auffüllen können. Wenn das Person-Objekt gelöscht werden soll, können wir dies einfach mit den CSLA-Löschprozeduren durchführen, während wir gleichzeitig die Integrität unserer Listen über alle VMs aufrechterhalten, die es hören.

Also ich hoffe, dass dies für alle Sinn ergab, und wenn jemand eine andere Lösung hat sie erfolgreich eingesetzt oder Kritik an diesem einen, auf alle Fälle!

Danke!

(Reposted aus: http://forums.lhotka.net/forums/thread/35576.aspx)

Antwort

-1

Wenn Sie Rocky Beispiele Blick über die mit dem CSLA Rahmen kommen, werden Sie feststellen, dass er immer nur Objekte aus der Lese/Schreib-Objekte lesen trennt. Ich denke, dass dies aus gutem Grund getan wird, weil die Verhaltensweisen sich drastisch unterscheiden werden. Nur-Lese-Objekte sind leistungsbasierter, ihre Validierung wird sehr unterschiedlich sein und in der Regel weniger Informationen enthalten. Die Lese-/Schreibobjekte sind nicht so leistungsbasiert und verlassen sich stark auf Validierung, Autorisierung usw.

Das lässt jedoch das Dilemma offen, in dem Sie sich gerade befinden.Was ich tun würde ist überladen Sie den Konstruktor jeder Klasse, so dass Sie sie zwischen einander übergeben können und "kopieren", was Sie voneinander brauchen.

Etwas wie folgt aus:

public class PersonLite : BusinessBase<PersonLite> 
{ 
    public PersonLite(PersonFull fullPerson) 
    { 
     //copy from fullPerson's properties or whatever 
    } 
} 

public class PersonFull : BusinessBase<PersonFull> 
{ 
    public PersonFull(PersonLite litePerson) 
    { 
     //copy from litePerson's properties or whatever 
    } 
} 

Sie dies auch mit einer Fabrik Muster tun konnte, was bevorzugt Rockys ist, glaube ich.

+0

Ich bin mir nicht ganz sicher, was Sie vorschlagen, soll lösen. Ein lite BO würde nie ein vollständiges BO füllen, da wir einfach zur Datenbank gehen können, um einen vollständigen BO mit den eindeutigen Daten aus der Lite-Version zu hydratisieren. Ich denke, ich könnte eine Vollversion sehen, die die Lite-Version nach einer Bearbeitung aktualisiert, aber das ist nicht der richtige Weg. – opedog

+0

Die Lite-Version ist nicht in der Lage, die vollständige Version vollständig zu füllen, aber es könnte ausreichen, damit sie dem Benutzer angezeigt werden kann und die verbleibenden Daten können faul geladen werden. Ich habe das in der Vergangenheit mit etwas Erfolg getan. Wenn Sie versuchen, Speicherobjekte zu ändern, wird Ihre Herangehensweise völlig anders aussehen. – Joseph

+0

Wenn die Back-End-BOs jetzt neu erstellt werden sollen, nachdem das Front-End fertiggestellt ist, verwenden Sie dies als Testfall, um mit neuen CSLA-Objekten zu beginnen, die alle Eigenschaften enthalten. –

3
public class PersonLite : ReadOnlyBase<PersonLite> 
{ 
    public void Update(PersonFull person) { } 
} 

public class PersonFull : BusinessBase<PersonFull> 
{ 
    // blah blah 
} 

Ich würde aktualisieren, um das „lite“ Objekt mit den zum „full“ Objekt vorgenommenen Änderungen, und es als ReadOnlyBase verlassen. Beachten Sie, dass "ReadOnly" in ReadOnlyBase ein Objekt bedeutet, das nur aus der Datenbank gelesen und nicht gespeichert wird. Ein weniger eleganter, aber genauerer Name wäre NotSavableBase, weil solchen Objekten die DataPortal_XYZ Maschinerie für alles außer Fetches fehlt. Aus offensichtlichen Gründen haben solche Objekte normalerweise unveränderbare Eigenschaften, müssen dies aber nicht tun. ReadOnlyBase leitet sich von Core.BindableBase ab und implementiert INotifyPropertyChanged, sodass das Ändern der Werte seiner Eigenschaften problemlos mit der Bindung funktioniert.

Wenn Sie Ihr "vollständiges" Objekt speichern, übergeben Sie die neu gespeicherte Instanz an die Methode Update(PersonFull) der Instanz in Ihrer Liste und aktualisieren die Eigenschaften des Objekts "lite" vom Objekt "full".

Ich habe diese Technik viele Male verwendet und es funktioniert gut.