2009-05-29 3 views
7

Angenommen, Sie haben 3 Ebenen: UI, Business, Data.Soll die Business-Schicht der Anwendung auf das Session-Objekt zugreifen können?

Ist das ein Zeichen für schlechtes Design, wenn die Business-Schicht auf Sitzungen zugreifen muss? Etwas daran fühlt sich nicht richtig an. Gibt es Richtlinien, die speziell auf die Web-App zugeschnitten sind?

Ich verwende C# 2.0 .net

+0

Danke für alle Antworten. Das Hauptproblem, das Sie sehen, ist die Fähigkeit, die Business-Schicht bei Bedarf zu "wechseln". Meine App wird IMMER im Web laufen, daher wird die Sitzung IMMER relevant sein, bis die Sitzung veraltet ist, also ist das kein Problem. – sarsnake

+0

also keine Unit-Tests? – Robert

+0

Sie sagen, dass dies immer eine Webseite sein wird, ist ein Implementierungsdetail ... sollte im Design nicht berücksichtigt werden. – CSharpAtl

Antwort

1

Mein Gefühl ist, dass die Business-Schicht der einzige Ort ist, um den Sitzungsdatenzugriff zu ermöglichen, weil es wirklich Teil Ihrer Logik ist. Wenn Sie es in der Präsentationsschicht einfrieren, wenn Sie ändern, wo diese Daten gespeichert sind (sagt, Sie möchten nicht mehr Sitzungsstatus verwenden), dann ist eine Änderung schwieriger.

Was ich tun würde, ist für alle Daten, die Session-Status ist, würde ich eine Klasse erstellen, um den Abruf dieser Daten zu kapseln. Dies wird zukünftige Änderungen ermöglichen.

Bearbeiten: Die Benutzeroberfläche sollte nur für folgende Aufgaben verwendet werden: 1. Rufen Sie die Business-Schicht. 2. Interagieren Sie mit dem Benutzer (Nachrichten und Ereignisse). 3. Manipulieren Sie das visuelle Objekt auf dem Bildschirm.

Ich habe gehört, dass Leute den Sitzungsdatenzugriff als Teil der Datenschicht betrachten, und dies ist semantisch und hängt davon ab, was Sie als Datenschicht betrachten.

+7

Ich habe mir die Business-Schicht immer als eine Reihe von Funktionen angesehen, um das eigentliche Problem des Benutzers zu lösen. Angenommen, Sie erstellen eine Anwendung zum Konvertieren von .doc-Dateien in .pdf. Sie möchten dies als eine Befehlszeilen-App (jeweils 1 Benutzer) und eine Web-App (viele Benutzer gleichzeitig) bereitstellen. Eine gute Kapselung würde es Ihnen ermöglichen, die gleiche Business-Logik-Ebene vollständig in beide zu löschen. Ich sehe nicht, wie dies mit einem Session-Objekt funktionieren würde, da es nicht auf die Befehlszeilen-Implementierung anwendbar ist. – AndreiM

+0

Tehblanx, siehe meinen Kommentar zum Fragetext. Meine App wird nie von irgendwo anders als von einer Webseite gestartet. – sarsnake

+0

Das ist Implementierungsdetail ..... nicht Design .... – CSharpAtl

3

Riecht mir komisch vor. Vielleicht benötigen Sie eine Präsentationsebene, um die Sitzung und andere statusbehaftete Informationen zu verwalten?

+1

+1, ich finde, dass das Entwerfen einer staatenlosen Ansichtsebene mit einer statusbehafteten Präsentationsschicht die Trennung von _Geschäftslogik_ von _Präsentationslogik_ fördert. Letzteres sollte die einzige Logik sein, die sich der Sitzung bewusst ist. –

+0

das ist ein Weg, es zu tun, Michael. – sarsnake

+0

das war eigentlich, was ich ursprünglich gedacht hatte. – sarsnake

0

Wenn Sie die drei aufgelisteten Layer beibehalten, ist die Ebene "Business" wahrscheinlich am besten geeignet, um mit Session-Objekten umzugehen.

Da eine Sitzung mehr damit zu tun hat, dass das eigentliche Framework die Anwendung verknüpft als mit jeder tatsächlichen Geschäftslogik, möchten Sie möglicherweise eine Steuerschicht erstellen, die Daten aus dem Session-Objekt in Geschäftsdateneingaben in die Business-Schicht umsetzt.

3

Ich denke, die Geschäftslogik sollte nicht an eine Präsentationsauswahl gebunden sein, und wenn Sitzung in dieser Ebene lebt, wird sie gebunden.

3

ich unnötige Verwendung von Session betrachte im Allgemeinen ein Codegeruch sein, oft querystrings, Kekse und Ansichtszustand ist Lighterweight und hat eine besseren ‚Umfang‘

Was Sessions Rolle in einem Business-Tiere, hängt es von welcher architektonischen Guru, du liest gerade. Wenn die Business-Logik-Ebene ein Ort für Code ist, der von der Benutzeroberfläche unabhängig ist, ist die Sitzung keine Sache, die in die Geschäftsschicht eingeführt werden soll.

Beispielsweise in einer Konsolenanwendung, einer ASP.NET-Webanwendung, einem Windows-Dienst und einer Windows Forms-App - nur ASP.NET verfügt über eine Sitzung.

Das heißt, die Unterstützung mehrerer Benutzeroberflächen ist eine stark überbewertete Funktion, und es ist nicht perfekt vorauszusehen, ob Sie Ihre App jemals auf eine andere Benutzeroberfläche portieren werden. Wenn Sie sehr zuversichtlich sind, dass Ihre Logik nur in einer ASP.NET-App ab sofort und für immer ausgeführt wird, dann ist das in Ordnung.

Eine Ausnahme wäre Unit-Tests. nUnit-Testläufer stellen eine andere Benutzeroberfläche dar und es ist schwierig, Anforderung, Antwort, Sitzung, Anwendung usw. zu simulieren.

5

Nein. Wenn Sie eine "Controller" -Schicht hätten, sollten Sie dort darauf zugreifen. Holen Sie sich die benötigten Informationen aus der Sitzung und übergeben Sie sie an Ihre Business-Schicht.

0

Ich denke, es hängt von der Verwendung ab, aber ja, wir greifen die Sitzung von unserer Business-Schicht die ganze Zeit. Es gibt auch hier ein Argument "Reinheit gegen Realität".

Zum Beispiel haben wir in unserer Anwendung eine Datenbank pro Client, aber eine Codebasis. So haben wir die Client-Informationen in der Sitzung für jeden Benutzer. Sicher, wir könnten diese Daten dann in der Webschicht aus der Sitzung herausholen und dann an die Business-Schicht übergeben. Natürlich kümmert sich die Business-Schicht nicht einmal darum, aber sie wird von der Datenschicht benötigt, um sich mit der richtigen Datenbank zu verbinden. Dann müsste die Business-Schicht sie an die Datenschicht übergeben. Scheint wie viele Parameter, die ohne guten geschäftlichen Grund überschritten werden. In unserem Fall überprüft unsere Datenschicht das Session-Objekt für die Verbindungszeichenfolge und läuft von dort. Ich codierte, um das Problem der nicht-Session, wenn es nicht ein Web-App (und wir haben Windows-Dienste und Exe-Helfer-Anwendungen) wie folgt:

protected virtual string GetConnectionString() 
{ 
string connectionString; 
string connectionStringSource; 

//In app.config? 
if (ConfigurationManager.AppSettings[_ConnectionStringName] != null && 
    ConfigurationManager.AppSettings[_ConnectionStringName] != "") 
{ 
    connectionString = ConfigurationManager.AppSettings[_ConnectionStringName]; 
    connectionStringSource = "Config settings"; 
} 
//Nope? Check Session 
else if (null != HttpContext.Current && null != HttpContext.Current.Session && 
    null != HttpContext.Current.Session[_ConnectionStringName]) 
{ 
    connectionString = (string)HttpContext.Current.Session[_ConnectionStringName]; 
    connectionStringSource = "Session"; 
} 
//Nope? Check Thread 
else if (null != System.Threading.Thread.GetData(
     System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName))) 
{ 
    connectionString = (string)System.Threading.Thread.GetData(
      System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName)); 
    connectionStringSource = "ThreadLocal"; 
} 
else 
{ 
    throw new ApplicationException("Can't find a connection string"); 
} 

if (debugLogging) 
    log.DebugFormat("Connection String '{0}' found in {1}", connectionString, 
      connectionStringSource); 

return connectionString; 
} 
0

die Sitzung von der Business-Schicht Zugriff ist auf jeden Fall ein Code Geruch.

Wenn Sie die Business-Schicht wie angegeben "umschalten" müssen, müssen Sie sich nur um die Darstellungsschicht oder den Controller kümmern, was die Sitzungsvariable betrifft.

Angenommen, Sie möchten einen Satz Objekte für eine Sitzungsvariable und einen anderen Satz für eine andere Variable verwenden. Ihr Controller könnte eine Service-Schicht aufrufen und die Variable übergeben. Die Serviceschicht würde dann das entsprechende Geschäftsobjekt zurückgeben.

Ihre Business-Schicht hat nichts mit der Sitzung zu tun, in dem Sinne, dass Ihre Präsentationsschicht nichts darüber weiß, wie Sie mit der DB verbunden sind.

+0

sehe meinen Kommentar - Wechsel ist kein Problem, aber ich verstehe es. es ist ein Argument der Reinheit gegen die Realität. – sarsnake

0

Das Sitzungsobjekt ist an eine bestimmte UI-Implementierung gebunden. Wenn Sie also Ihre Business-Schicht an Ihre Sitzung verlieren, ist das ein Geruch.

Außerdem sollten Sie in der Lage sein, Ihre Business-Schicht im Unit-Test zu testen - wie werden Sie das machen, wenn Abhängigkeiten von einer Sitzung bestehen?

5

Seufz.

Der breite Konsens wird nein sein; Die Business-Schicht und die Controller/Web-Schicht sollten anders gepflegt werden, da sie separate Anliegen sind.

Tatsache ist, Sie scheinen dies als eine "Reinheit vs. Realität" -Frage zu bezeichnen, die unglaublich kurzsichtig und leicht anstößig ist. Es widerspricht auch dem Punkt, die Frage zu stellen; Wenn Sie die präsentierten Meinungen nicht in Betracht ziehen, warum sollten Sie diese dann einholen?

Es ist wahr, dass etwas mehr Sorgfalt im Voraus erfordert mehr Aufwand, mehr Zeit und letztlich ein wenig mehr kosten kann. Es ist auch wahr, dass Sie möglicherweise keinen unmittelbaren Nutzen daraus ziehen können. Eine Fülle von Schluchtromanen, die mehrere Jahrzehnte lang von einer großen Anzahl von Programmierern geteilt wurden, legt jedoch nahe, dass Ihre so genannte "Reinheit", wenn möglich, den Schmerz in fünf Jahren reduziert. Meine Güte; Sie müssen wirklich knutschen und ein wenig Refactoring machen, und es ist nicht im entferntesten angenehm wegen all der Risse, durch die Ihre Verantwortlichkeiten sickern.

Eine etwas bessere Möglichkeit, sich die Schichten für eine Webanwendung vorzustellen, könnte die Darstellung, Interaktion, Geschäftsregeln und Daten sein; von oben nach unten. Ihre Daten sind die Datenbank, der Datenzugriff usw., und die Geschäftsregeln erzwingen zusätzliche Beschränkungen für diese Daten, verarbeiten Valutierungen, Berechnungen usw.Die Interaktion verzweigt dann zwischen der Darstellungsschicht (die im Grunde Ihre Benutzeroberfläche ist) und der Geschäftslogik, wobei die Anwendungsfälle ausgeführt werden, die Ihre Anwendung steuern.

Bis zu diesem Punkt ist die Benutzeroberfläche allesamt immateriell; Es spielt keine Rolle, ob der Benutzer z. B. Kundendaten in einer Befehlszeilenanwendung eingibt oder ein mehrseitiges Webformular mit in der Sitzung gespeicherten Daten navigiert. Nehmen wir an, Sie wählen das Letztere. kleben Sie ein Web-Front-End drauf. Jetzt geht es darum, relativ einfachen Code zu schreiben, um die angeforderten Daten abzurufen und sie dem Benutzer zu präsentieren. Der Punkt ist, Ihre Webanwendung; das Front-End, , das ist Ihre gesamte Benutzeroberfläche; Sitzungen und alle. Nur an dem Punkt, an dem Sie bereit sind zu sagen, "hey, lasst uns diese Kundendaten in die Datenbank stecken", rufen Sie diese ach so liebevoll gestalteten Service-Layer auf und geben jedes Bit an Information weiter, das Ihre Webanwendung hat verstaut; die Benutzereingabe, der Name des Benutzers, der die Änderung vornimmt; all dieser Mist. Und deine Service-Schicht geht damit um. Oder, alternativ, Hündinnen, weil Sie ein Pflichtfeld vergessen haben.

Da Sie die Dinge sauber getrennt haben, kann der Mut Ihrer Anwendung, wie andere vorgeschlagen haben, umgestaltet (oder "geborgt") werden, um in jeder anderen Anwendung zu verwenden, und die Serviceebene bleibt staatenlos, sauber. und bereit, mit den Dingen umzugehen. Und es macht Ihre Validierung, und so ist Ihre Validierung überall konsistent. Aber es weiß nicht, wer sich im Web-Frontend oder in der Konsolenanwendung oder der ausgeklügelten Rich-Client-Anwendung, die auf einem Terminal ausgeführt wird, angemeldet hat, und es ist auch egal, da dieses Detail nur für diese Anwendungen wichtig ist.

Müssen Sie eine neue Validierungsregel hinzufügen? Kein Problem; Sorgen Sie dafür, dass die Serviceschicht die Validierung durchführt, und sorgen Sie dafür, dass die Probleme der Benutzeroberfläche oben in der Kette weiter oben behandelt werden. Müssen Sie die Art und Weise ändern, wie etwas berechnet wird? Ändern Sie das auf der Business-Schicht. Nichts anderes muss beeinflusst werden.

+0

Stimmen Sie hier völlig überein. Service-Ebene ist von größter Bedeutung für die Wartbarkeit. –