0

Nur versuchen, Gedanken zu sammeln, was funktioniert/nicht funktioniert für die Manipulation von Business/Domain-Objekte über eine ASP.NET (2.0+) UI/Präsentationsebene. Insbesondere in klassischen ASP.NET LOB-Anwendungssituationen, in denen der ASP.NET-Code direkt mit der Business-Schicht kommuniziert. Ich stoße sehr oft auf diese Art von Entwurf und frage mich, was die ideale Lösung ist (d. H. Ein spezifisches Muster implementieren) und was die beste pragmatische Lösung ist, die kein vollständiges Neuschreiben erfordert, wo kein "Muster" implementiert ist.Business/Domain-Objekt in ASP.NET

Hier ist ein Beispielszenario.

Eine einzelne ASP.NET-Seite, die die Seite "Bearbeiten/Neu" für ein bestimmtes Business/Domain-Objekt ist, verwenden wir "Person" als ein Beispiel. Wir möchten Name und Adresse von dieser Seite aus bearbeiten. Während der Benutzer Änderungen vornimmt oder Daten eingibt, gibt es einige Situationen, in denen das Formular für die Aktualisierung reaktiviert werden sollte. Wenn Sie zum Beispiel ihre Adresse bearbeiten, wählen sie ein "Land". Danach wird ein Dropdown-Menü für Bundesstaat/Region aktiviert und mit relevanten Informationen für das ausgewählte Land aktualisiert. Dies ist im Wesentlichen Geschäftslogik (Einschränkung verfügbarer Auswahlen basierend auf einem abhängigen Feld) und diese Logik wird von der Business-Schicht gehandhabt (denken Sie daran, dies ist nur ein Beispiel, es gibt viele Geschäftssituationen, in denen die Logik während des Post-Back-For komplexer ist) Beispiel Versicherungsindustrie bei der Auswahl bestimmter Dinge diktiert, welche anderen Daten benötigt/benötigt werden).

Idealerweise wird diese Logik nur im Business/Domain-Objekt gespeichert (d. H. Die Logik ist im ASP.NET-Code nicht doppelt vorhanden). Um dies zu erreichen, müsste das Business/Domain-Objekt neu initialisiert werden und sein Zustand basierend auf den aktuellen UI-Werten für jedes Postback festgelegt werden.

Zum Beispiel:

private Person person = null; 

protected void Page_Load() 
{ 
    person = PersonRepository.Load(Request.QueryString["id"]); 

    if (Page.IsPostBack) 
     SetPersonStateFromUI(person); 
    else 
     SetUIStateFromPerson(person); 
} 

protected void CountryDropDownList_OnChange() 
{ 
    this.StateRegionDropDownList.Enabled = true; 
    this.StateRegionDropDownList.Items.Clear(); 
    this.StateRegionDropDownList.DataSource = person.AvailableStateRegions; 
    this.StateRegionDropDownList.DataBind(); 
} 

Andere Optionen, die ich gesehen habe, sind das Business-Objekt in Session speichern, anstatt sie aus dem Repository (auch bekannt als Datenbank) jedes Mal der Seite geladen werden wieder nach oben zu laden.

Gedanken?

Antwort

0

Ich würde Ihr Beispiel in meine "UI Enhancement" -Bucket statt BL, überprüfen, dass die Einträge korrekt sind, ist BL aber Erleichterung der Dateneingabe ist UI meiner Meinung nach.

+0

Das würde die Logik duplizieren, nicht wahr? Das heißt, wenn ich ein Land für diesen Objektstatus auswähle, weiß mein Address-Objekt, welche verfügbaren Status/Regionen für das ausgewählte Land verfügbar sind. Vielleicht mit Land/Regionen können wir damit durchkommen, aber was ist mit etwas komplizierteren wie, welche Felder benötigt werden, basierend auf der Auswahl eines anderen Feldes. – Brian

+0

Nicht wirklich, die Logik würde nur die UI-Schicht existieren. Während Sie wahrscheinlich die Eingabe in der BL-Schicht verifizieren werden (vorausgesetzt, Sie haben eine Schnittstelle mit Ihrer Benutzeroberfläche, dh sie sind nicht Teil derselben monolithischen App), aber Sie würden die Status-/Regionskaskade in den Geschäftsobjekten nicht implementieren passt einfach nicht. Für mich erledigt die BL-Schicht Dinge, die mit maschinengenerierten oder Benutzereingaben aufgerufen werden können, sie ist nicht an eine Benutzerschnittstelle gebunden. Ich gebe zu, das ist eine Meinung und ich könnte mich irren :) – Lazarus

0

Für sehr einfache Dinge würde ich mich nicht mit einem regulären Post zurück kümmern, sondern würde einen Ajax-Ansatz verwenden. Wenn ich zum Beispiel eine Liste mit Städten benötige, könnte ich eine Seitenmethode (oder einen Webservice) haben, die mir eine Liste von Städten gibt.

Wenn Ihre Optionen von einer Vielzahl von Parametern abhängen, würde Ihre Arbeit gut funktionieren. Was das Speichern von Dingen in Session betrifft, gibt es Vorteile. Sind Ihre Entitäten zu mehreren gleichzeitig sichtbar? Wenn ja, was passiert, wenn Benutzer A und Benutzer B beide dasselbe bearbeiten? Auch wenn Sie jedes Mal geladen werden, sind Sie jedes Mal in der Datenbank? Was passiert, wenn ich meinen Namen bearbeite und dann Land auswähle, aber jetzt stürzt mein Browser ab. Hast du den Namen in der DB aktualisiert?

+0

Parallelität wird im Allgemeinen durch die DAL behandelt und sprudelt auf. Das heißt, wenn Benutzer A und Benutzer B dieselbe "Person" bearbeiten, gewinnt zuerst der Speichervorgang. Die zweite Zeile wird mit einer Fehlermeldung und der letzten Kopie des Business-Objekts angezeigt. – Brian

+0

Wird nicht in der Datenbank gespeichert, bis der Benutzer eine explizite Sicherungsaktion ausführt (denken Sie an die Schaltfläche "Speichern"). Lädt nur den aktuellen Status aus der Datenbank bei jeder Auslastung. .... Ahhhh jetzt sehe ich, was Sie über Nebenläufigkeit gefragt ... Was, wenn Benutzer A und Benutzer B zur gleichen Zeit bearbeiten, speichert Benutzer A, und Benutzer B tut soemhnning, dass in einem Postback resultiert, wird meine Ladung aus dem Repository Das Laden von Benutzer A würde irgendwie die aktuelle Version des Objekts mit einer Concurrency ID verfolgen müssen. – Brian

+0

Ja, darüber habe ich gesprochen. – JoshBerke

0

Das ist die Linie, die ich mit etwas nicht einverstanden ist:

this.StateRegionDropDownList.DataSource = person.AvailableStateRegions; 

Person ist ein Business/Domain-Objekt, aber es ist nicht das Objekt, das (zum Beispiel) Staat/Region Mapping Handhabung sollte, auch wenn das ist, wo die Information, um die Entscheidung zu leben.

In komplizierteren Beispielen, in denen mehrere Variablen benötigt werden, um eine Entscheidung zu treffen, sollten Sie im Allgemeinen von dem Domänenobjekt starten, mit dem Sie enden möchten, und eine Funktion für dieses Objekt aufrufen gegeben alle notwendigen Informationen, um eine geschäftliche Entscheidung zu treffen.

Vielleicht (eine statische Funktion auf der Staats-Klasse):

this.StateRegionDropDownList.DataSource = State.GetAvailableStateRegions(person, ipAddress); 

Als Folge der Abtrennung UI Helfer Bedenken von der Person Domain-Objekt, diese Art der Programmierung neigt „viel mehr prüfbar zu sein ".

+0

Ich bewege mich auch irgendwie von meinem ursprünglichen Denken weg. Ich habe das MVVM-Entwurfsmuster gelesen und es scheint, dass diese Logik wirklich im View-Modell enthalten sein sollte. Dies erleichtert wesentlich die Dateneingabe in die Business-Schicht (das Adressobjekt). – Brian