2011-01-06 12 views
7

Mam następujące warstwy dostępu do danych (DAL). Zastanawiałem się, czy jest poprawnie skonfigurowany, czy też muszę go poprawić?Jak poprawnie zaprojektować warstwę dostępu do danych?

public class User 
{ 

} 

//Persistence methods 
static class UserDataAccess 
{ 
    UsersDAL udal = // Choose SQL or FileSystem DAL impl. 


    InsertUser(User u) 
    { 
     // Custom logic , is 'u' valid etc. 

     udal.Insert(u); 
    } 
} 

abstract class UsersDAL 
{  
    GetUserByID(); 
    InsertUser(u); 
    ... 
} 

// implementaitons of DAL 

static class UsersSQLStore : UsersDAL 
{ 

} 

static class UsersFileSystemStore : UsersDAL 
{ 

} 

że oddziela warstwę pamięci z klasy użytkownikowi dostęp do metody, która ponadto zbiór wywołać jakichkolwiek niestandardowych DAL.

Czy użycie static w implementacji DAL jest poprawne?

Proszę zasugerować poprawki lub sposoby, w jakie mogę to ulepszyć. Nie mam dużego doświadczenia w pisaniu kodu w warstwach.

+2

Jeśli nie możesz poświęcić czasu na dokładne przeliterowanie pytania (za pomocą Pl. Zamiast Please), to jak możesz oczekiwać, że ktoś poświęci czas na udzielenie odpowiedzi na twoje pytanie lub pomoc? –

+7

@George, nie wiem, czy to kogoś boli, ale tylko po to, by ratować ludzi czytających zbyt dużo, używam tego regularnie. Zamiast tego skoncentrowałem się na spisaniu mojego przykładu. Nie znaczy to, że nie doceniam czasu ludzi i ich reakcji. –

+0

Dlaczego chcesz to zrobić zamiast używać ORM jak LLBLGen lub Dapper? Nie trzeba wymyślać koła. –

Odpowiedz

12

Żaden z tych klas powinny być static. Nie sądzę, że powinieneś również nazwać twoje klasy DAL, ponieważ jest skrótem od warstwy dostępu do danych, a klasa sama w sobie nie jest warstwą (przynajmniej w moim umyśle). Zamiast tego można użyć powszechnie przyjętego terminu repository. Proponuję zrobić coś jak następuje:

public class User{ 

} 

public abstract class UserRepository{ 
    public abstract void InsertUser(User user); 
} 

public class SqlUserRepository : UserRepository{ 
    public override void InsertUser(User user) 
    { 
     //Do it 
    } 
} 

public class FileSystemUserRepository : UserRepository{ 
    public override void InsertUser(User user) 
    { 
     //Do it 
    } 
} 

public class UserService{ 
    private readonly UserRepository userRepository; 

    public UserService(UserRepository userRepository){ 
     this.userRepository = userRepository; 
    } 

    public void InsertUser(User user){ 
     if(user == null) throw new ArgumentNullException("user"); 
     //other checks 
     this.userRepository.InsertUser(user); 
    } 
} 

Należy pamiętać, że jest wstrzykiwany UserService z instancji klasy abstrakcyjnej UserRepository w jego konstruktora. Możesz użyć struktury Dependency Injection (DI), aby zrobić to automatycznie, na przykład Windsor Castle z Castle Project. Pozwoli to na określenie mapowania z abstrakcji (UserRepository) do konkretnej implementacji (np. SqlUserRepository) w pliku konfiguracyjnym lub w kodzie.

Nadzieję, że to wskazuje ci właściwy kierunek i zapytaj, czy potrzebujesz więcej informacji.

+0

Thats szablon wzorca. Jesteś w dobrym kierunku z kilkoma zmianami sugerowanymi przez Hoffmanna i Janiego – hungryMind

+0

Doskonałe wyjaśnienie. Dlaczego shoudlnt używam statycznego? Jeśli nie dla repozytoriów, dla UserService mogę zrobić to statycznie, jak sądzę? Jeszcze jedna rzecz (może być niezwiązana z DAL): Jeśli próbujesz wstawić istniejącego użytkownika, to kto powinien dokonać tej kontroli, UserService lub klasa użytkownika przez konstruktorów (ponieważ nie wie, czy ma to wpływ na nowość) –

+0

@Munish Goyal, nie powinieneś używać 'static', ponieważ nie ma takiej potrzeby. W przypadku niewłaściwego użycia 'static' wprowadza niepotrzebny stan w aplikacji, co sprawia, że ​​zarówno trudniej jest debugować, jak i co najważniejsze, sprawia, że ​​** bardzo ** trudno jest przetestować automatycznie. Prawdopodobnie chcesz przeczytać dokładne znaczenie słowa "static" tutaj: http://msdn.microsoft.com/en-us/library/98f28cdx%28vs.71%29.aspx –

6

moim skromnym Opinions

  1. Używaj interfejsów zamiast klasy abstrakcyjnej, jeśli użytkownik nie ma żadnej hierarchii.
  2. Napisz ogólny DAL, aby ponownie użyć go jako elewacji warstwy DAL.
  3. rozwiązywać konkretne dal przez ramy DI
Powiązane problemy