webForumDet fria alternativet

Håller på att laborerar lite med ASP.NET och skulle behöva...

.NET

2 svar · 514 visningar · startad av Fredde Mannen

Medlem sedan nov. 20014 054 inlägg
Frågan#1

.. lite assistans på en punkt.

Håller på att skapar en 3-skikt applikation. Har kommit så här pass långt:

- En class för hantering av sql-strängar och SP samt möjlighet till transaktionshantering. Jag kallar detta för DataAccess

- En class som jag kallat för User som jag låter finnas i namnutrymmet MittNamnUtrymme.Data

- En class som jag kallat för User som jag låter finnas i nmnutrymmet
MittNamnUtrymme.Business

- En aspx-sida som använder sig av klassan User i MittNamnUtrymme.Business för att skapa, redigera, radera och hämta användare.

Så kort och gott: Aspx-sidan <postar till sig själv och instansierar> MittNamnUtrymme.Business.User <instansierar och skickar till/hämtar från> MittNamnUtrymme.Data.User <instansierar skickar till/hämtar från> DataAccess <skickat till/hämtar från> Databasen

Har jag tänkt rätt så långt?

Hur som helst till själva gåtan, problemet:
I aspx-sidan:

// någon metod.. 

Business.User u = new Business.User();
u.Firstname = txtFname.Text;
u.Lastname = txtLname.Text;
// ytterligare .. 
u.Create();

Har i Business.User metoden Create som aspx-sidan anropar:

public int Create() { 
// kod... 
                Data.User data = new Data.User();
                int id = data.Create(this); // vill skicka hela objektet ned till Data.User
                data = null;
// mer kod.. 
 }

Har i Data.User denna metod då som skall ta emot objektet:

public int Create(Business.User _obj) { ... 
// skickar vidare till DataAccess
}

Är det "rätt" att sätta objekttypen på så sätt som jag gjort i Data.User.Create(..) ?

Hur bör man göra i detta fall egentligen?

Medlem sedan maj 20012 812 inlägg
#2

I princip är det rätt även om jag kanske hade valt lite andra namn för de olika lagren.

Jag hade haft kvar DataAccess lagret som du har. Ovanför detta så hade jag haft ett Business lager och ovanför detta så har jag min presentationslager, på tvärs genom alla dessa lager så hade jag haft ett Entity lager.

Entity lagret innehåller egentligen ingen logik, utan endast din definition av din Userklass, i princip så innehåller den endast variabler och property (vekligheten är dock annorlunda). Mitt Businesslager har som ansvar att utföra operationer på/mot mitt User entity.

Så i ditt exempel ovan så hade det blivit så här.

ASPX-codebehind.

Entity.User user = Business.CreateUser();

user.Name = txtName.Text;
user.Age = int.Parse(txtAge.Text);
...

Business.SaveUser(user);

Mitt Businesslager ser då ut så här.

public void SaveUser(Entity.User user)
{
   //-- Kontrollera så vi verkligen har ett objekt att jobba med
   if(user == null)
      return;

   //-- Kontrollera om detta är ett nytt objekt, eller ett förladdat som har ändrats
   if(user.Identifier == null){
      user.Identifier = new Identifier();
      DataAccess.InsertUser(user);
   } else
      DataAccess.UpdateUser(user);
}

Och sedan sist din DataAccess klass

public void InsertUser(Entity.User user){...}
public void UpdateUser(Entity.User user){...}

Där har du en variant som bygger på tanken att din objekt (Entity.User) endast är databärare och du har Managerklasser (Business) som opererar på dem. Detta kan sedan förfinas ut ytterligare så varje Entitysklass (User) har en egen ManagerKlass (UserManager) istället för att slå ihop alla till en Businessklass, men principen är det samma.

Alternativ 2 är att du bygger en domän modell där både logik och data finns i samma klass, man kan säga att du slår ihop Entity-lagret och Business-lagert till ett Domain-lager.

Typ så är.
ASPX-codebehind

Domain.User user = new Domain.User() 

user.Name = txtName.Text;
user.Age = int.Parse(txtAge.Text);
...

user.Save();

Och din Userklass kommer då innehålla logik för att hantera persistering av datan till databasen.

public class User{
 
  //-- Methods
  public void Save()
  {
      if(identifier == null){
        identifier = new identifier();
        DataAccess.InsertUser(this);
      }else
        DataAccess.UpdateUser(this);
  }
}

Så skillnaden är inte så stor i detta exemplet, men i riktig stora projekt så kommer man att märka att domänklasserna kommer bli stora och tunga, dessutom så kommer alltid frågan i vilken klass skall jag lägga denna funktion, när funktionen påverkar flera klasser. Med Managerklasserna så blir dessa klasser oftas flera och lite mindre, men kanske inte alltid är så lätta att hitta i...

I vilket fall som helst så spelar kanske inte det så stor roll för dig, vad du borde ha upptäck nu är att det kommer göras riktigt många funktioner i din DataAccess-klass.

InsertUser(), UpdateUser(), DeleteUser(), SelectAllUsers(), SelectUserByIdentifier(), SelectUserByCity()... osv osv... Och det är bara för din User klass, alla din klasser kommer få lika många funktioner i ditt DataAccesslager, samt att du som utvecklare måste hålla reda på om du skall göra en Insert/Update mot databasen, varför skall du i din businesslager ta ställning till det, du vill ju bara göra en Save(), det är ju inte ditt fel att SQL är så korkat så det har 2 olika kommand för att spara till databasen.

Och för att slipa undan allt detta så använder man givetviss en O/RMapper och din kod kommer istället skrivas om till.

ASPX-codebehind.

Entity.User user = Business.CreateUser();

user.Name = txtName.Text;
user.Age = int.Parse(txtAge.Text);
...

Business.SaveUser(user);

Mitt Businesslager ser då ut så här.

public void SaveUser(Entity.User user)
{
    ORMapper.Save<User>(user);
}

That's it...

- M

Medlem sedan nov. 20014 054 inlägg
#3

Man bockar och tackar för din tid! Mycket snällt..

Då var jag ju inte allt för långt ifrån i alla fall.. :e

257 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
122 ms — deklarationer (db)
0 ms — hämta statistik (cache)
129 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)