webForumDet fria alternativet

C# DAL, DLL, PL osv, då tar vi det ett varv till.

.NET

20 svar · 1 018 visningar · startad av Sjodahl

Medlem sedan maj 20033 218 inlägg
Frågan#1

Hej!

Läst igenom väldigt mycket trådar och, sökt en hel del men tycker inte då inte jag får ihop bilden på hur man bygger upp de olika lagerna. Så jag tänkte börja ifrån början här så får ni sparka mig åt rätt håll eftersom ; )
Hade tänkt mig att skapa 3st lager för att hålla det väldigt generellt (kanske är fel?).

  1. Skapa ett Entity Layer(??).
    Lager för att skapa sina objekt, tex: personer, bilar, bollar osv.?
  2. Skapa ett Business Logic Layer (BLL).
    Här kommer själv get,set data funktionerna finnas?
  3. Skapa ett Data Access Layer (DAL).
    Detta skall användas som gränssnitt mellan min applikation och databasen.
  4. Skapa Presentation Layer (PL).
    Här skall datan presenteras, och skall inte bry sig om vad vi har för datakälla?

Flöde: PL <> BLL <> DAL

Medlem sedan maj 20033 218 inlägg
#2

clsDAL - Data Access Layer (DAL).

using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace MyApplication.classes
{
    class clsDAL
    {
        private String _connString;
        private SqlConnection _conn;
        private DataTable _dt;

        public DataTable Dt
        {
            get { return _dt; }
            set { _dt = value; }
        }

        public SqlConnection Conn
        {
            get { return _conn; }
            set { _conn = value; }
        }
        public String ConnString
        {
            get { return _connString; }
            set { _connString = value; }
        }
        public clsDAL()
        {

            try
            {
                _connString = "data source=servername;uid=dev;password=password;database=database;";
                _conn = new SqlConnection(_connString);
                _conn.Open();
            }
            finally
            {
                // close connection
                if (_conn != null)
                {
                    _conn.Close();
                }
            }
        }
        public DataTable createDataTable() 
        {

            return _dt;
        }
    }
}
}

clsPerson - Entity

using System;
using System.Collections.Generic;
using System.Text;

namespace MyApplication.classes
{
    class clsPerson
    {
        private String _firstname;
        private String _lastname;

        public clsPerson()
        {
        }

        public String Firstname
        {
            get { return _firstname; }
            set { _firstname = value; }
        }

        public String Lastname
        {
            get { return _lastname; }
            set { _lastname = value; }
        }
    }
}
Medlem sedan jan. 20022 440 inlägg
#3

lägg till ett lager...

1. Skapa Entity Layer

då får du ändra lite i numreringen så att nummer två blir

2. Skapa ett Business Logic Layer (BLL).
Här ska mappning till entiteterna finnas och den sköts efter ett anrop till

3. Skapa ett Data Access Layer (DAL).
Detta skall användas för att hämta data från tex databasen och vidarebefordra till BLL

4. Skapa Presentation Layer (PL).
Här skall datan presenteras, och denna hämtas genom anrop till BLL som i sin tur hämtar från databasen, mappar till tex en IList och skickar till PL.

Medlem sedan maj 20033 218 inlägg
#4

Entity layer är det ungefär som ett objekt lager, typ där jag skapar mina bilar,personer osv?

Medlem sedan aug. 20003 575 inlägg
#5

Jag vet inte men jag gillar inte lagerindelning, Entiteterna / Business anser jag är samma "lager", sedan är ju detta något som används av alla Lager i applikationen förutom möjligtvis själva "datahämtaren".

Medlem sedan maj 20033 218 inlägg
#6

Det är ett okej sätta att skapa en databas koppling på?

Medlem sedan jan. 20022 440 inlägg
#7

Sjodahl skrev:

Entity layer är det ungefär som ett objekt lager, typ där jag skapar mina bil,personer osv?

Precis rätt uppfattat. Det är själva modellen på din domän/ditt projekt.

Beroende på hur avancerat du vill göra själva instantieringen av dina objekt kan du ju kolla lite närmare på factory pattern. http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=645

Medlem sedan maj 20012 812 inlägg
#8

nickemannen skrev:

Jag vet inte men jag gillar inte lagerindelning, Entiteterna / Business anser jag är samma "lager",

Det beror på vad det är du skapar och med vilken modell du skapra det. Om du bygger en tjänst så har du dels din logik och dels dina databärare (entiteter) som du skickar in och ut från din tjänst. Det är ett formellt fel att bygga in logik i dessa entiteter eftersom du aldrig kan vara säker på att denna logik fungerar på klient sidan, så därför brukar man göra sina entiteter som rena databärare (de fungerar då ungefär som dataset/datatable, men man änvder entiteter och arrayer istället.) och sedan så har man sitt businesslager där man opererar på dessa databärare.

Det betyder ju då också att i din applikation som använder sig av tjänsten kommer att ha entiteter som rena databärare i din applikation så för att använda dig av dem, så måste du antingen mappa om dessa till dina objekt som innehåller både data och logik, eller bygga ett businesslager som opererar på entiteterna...

Om du bara bygger en applikation och använder dig av domänmodellen så brukar man lägga sin logik och data tillsammans i objekten och då blir det lite som du säger att "entiteterna" och business blir samma lager.

- M

Medlem sedan jan. 20022 440 inlägg
#9

Nickemannen skrev:

Jag vet inte men jag gillar inte lagerindelning, Entiteterna / Business anser jag är samma "lager", sedan är ju detta något som används av alla Lager i applikationen förutom möjligtvis själva "datahämtaren".

Håller med till viss del, däremot är det ett bra steg i rätt riktning. Man ska ju börja någonstans och m han börjar med att gå blir det lättare att springa :)

Medlem sedan maj 20033 218 inlägg
#10

Hur generellt skall ett DAL vara?
Vad bör man returnera här? dataset/datatable?
Aldrig någora direkta get/setPersonName funktioner?

Medlem sedan jan. 20022 440 inlägg
#11

I mindre projekt har jag en DAL fil på 125 rader kod til hela min applikation som returnerar DataTable's.

Medlem sedan maj 20012 812 inlägg
#12

sjodahl skrev:

Hur generellt skall ett DAL vara?
Vad bör man returnera här? dataset/datatable?
Aldrig någora direkta get/setPersonName funktioner?

Mitt DAL är helt oberoende av applikation och har inga get/serPersonName funktioner, utan arbetar bara med IDBCommand object in, och returnerar object/int/DataTable/DataReader tillbaka. Det betyder att jag kan använda mitt DAL till vilket projekt som helst. Men igengäld så får man ju skriva ett nytt "DAL"-lager i applikationen som hanterar specifika frågor från ditt businesslager till DAL:et.

Nu är det inget problem för mig, då jag använder mig av en OR-Mapper som gör just det, alltså omvandlar data till och från entiteter som jag kan använda mig av i min applikation.

Typ så här.

UI
-----
BL
----
Projekts DAL
----
ORMapper
----
DAL

Eftersom ORMappern och det understa DAL:et är generella för alla projekt behöver de aldrig skrivas om. Så behöver bara skriva 3 (4 med entiteterna som ligger tvärs över alla) lager i min applikation om jag vill ha möjligheten att byta ut varifrån som min data kommer, behöver jag inte det så kan jag skippa Projekts DAL och kalla på min OR-Mapper från Businesslagret och skriver då bara 2 (3 med entiteterna) lager, så här.

UI
---
BL
--- 
ORMapper

Nu har jag dock låste min applikation betydligt mer hur jag hämtar data och till just denna ORMapper, så är det så att det är risk/chans att detta skall bytas ut, så är det bättre att lägga ett lager mellan BL och ORMappern (som ovan). Och ju större projekt och ju längre tid som det skall leva, destu viktigare är det att dela upp de i olika lager och använda sig av interfaces mellan lagrena så man enkelt kan byta ut något lager i framtiden utan att behöva skriva om halva applikationen.

- M

Medlem sedan maj 20033 218 inlägg
#13

Då börjar det klarna lite, skall det bara översättas till kod med ;)

Medlem sedan maj 20033 218 inlägg
#14

Okej låt oss säga att vi då skapar ett person objekt enligt ovan, hur går jag då tillväga för att fylla detta med data? Låt oss säga jag hämtar alla info ifrån databasen till en datatable men hur sätter jag smidigast värdena på mitt person objekt? För jag bör väl inte jobba direkt emot datatablen?

Medlem sedan jan. 20023 327 inlägg
#15

Varför inte använda dig av en OR-Mapper, exempelvis NHibernate? NHibernate fyller objekten åt dig när hämtar data från databasen. Dessutom kan du minska kodmängden avsevärt in dina projekt.

Medlem sedan maj 20012 812 inlägg
#16

Det enklaste sättet att börja är helt enkelt att du mappar upp ditt person objekt från datan i din datatable, det gör du i det "projekts DAL"

namspace MyProject.DAL
{
   public class DALManager{
   
     List<Person> GetPersons()
     {
              IDbCommand command = new SqlCommand(_Connection);
              command.Text = "Select * from person";
              command.CommandType = CommandType.Text;

              DataTable dt = myGenericDAL.Execute(command);
              return MapPerson(dt);
     }

     List<Person> MapPerson(DataTable dt)
     {
         List<Person> persons = new List<Person>();

         foreach(DataRow dr in dt.Rows)
            persons.Add(MapPerson(dr));

         return persons;
     }

     Person MapPerson(DataRow dr)
     {
         Person p = new Person();

         //-- Map data from datarow to object
         p.Name = dr["Name"].ToString();
         p.Age = (int)dr["Age"];
         .
         .
         .

         return p;
     }
   }
}

Nu har du omvandlat data från din databas till en lista med entiteter. Du kommer dock snabbt inse att det är riktigt mycket mappande som måste göras och det är riktigt tråkigt i längden. Så för att slippa allt det så kan du använda dig av ORMappers som gör denna mappning och sköter kommunikationen med databasen åt dig. NHibernate är väl den ORMapper som är störst inom .NET världen och antagligen den som du lättast kan få hjälp med om du har problem.

om du vill ha en väldigt enkel ORMapper så kan du läsa här hur man kan bygga en: http://www.webforum.nu/showthread.php?t=163666

- M

Medlem sedan maj 20033 218 inlägg
#17

Tack, skall ta en titt på hur det fungera.
Mycket matnyttigt kommer nu känner jag.

Medlem sedan maj 20033 218 inlägg
#18

Gladh skrev:

om du vill ha en väldigt enkel ORMapper så kan du läsa här hur man kan bygga en: http://www.webforum.nu/showthread.php?t=163666- M

Japp började följa med där men kändes som jag tappade bort mig efter ett tag, men skall läsa igenom det igen med.

NHibernate, mycket nytt då skall man förstå hur man blandar in det i projektet med.

Medlem sedan maj 20012 812 inlägg
#19

Sjodahl skrev:

NHibernate, mycket nytt då skall man förstå hur man blandar in det i projektet med.

Visst blir det så, när man väl tar första steget så är det svårt att ta det i små nätta steg, då allt liksom hör ihop på något sätt. Om du inte känner för att blanda in ORMapper redan så bygg som i mitt exempel ovan där du har ditt BusinessLager som kallar på ditt "projekts DAL" som i sin tur hämtar data från ett DAL och mappar om det till entiteter (det blir en massa mappande), och när du sedan känner att du har koll på det andra och börjar bli trött på att mappa data, så läs på om NHibernatet, och sätt in det i ditt "projekt DAL".

Men visst blir det mycket, och det finns så otroligt mycket mer, miljoner (känns det som iallafall) olika sätt och patterns, och vissa är rena motsatser motvarandra, och någonstans i allt detta så måste DU bestämma dig för hur DU vill ha det och välja din väg och dina lösningar och din arkitektur.

Jag kan ju själv säga att jag bryter mot massor med patterns och best-practis i varje projekt som jag gör. Helt enkelt för att det tar onödigt med tid att alltid följa dem. En gyllende regel är dock, ju större projekt och ju längre tid som projektet skall leva, destu viktigare är det att få ordning på sin arkitektur och följa patterns och best-practis, de finns ju där av en anledning :)

- M

Medlem sedan maj 20033 218 inlägg
#20

Ja det låter vettigt spinner vidare på det ovan tillsvidare. Återkommer med lite kod och nya funderingar ; )

340 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
195 ms — deklarationer (db)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)
194 ms — ändringar (db)