Munish Goyal
Munish Goyal

Reputation: 1409

How do I design a Data Access Layer appropriately?

I have the following Data Access Layer (DAL). I was wondering if it's set up correctly, or if I need to improve it?

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
{

}

I separated the storage layer from the User class to access methods collection which further call any custom DAL.

Is use of static in DAL implementation correct?

Please suggest corrections or ways I can make this better. I don't have a lot of experience with writing code in layers.

Upvotes: 9

Views: 21460

Answers (3)

tijmenvdk
tijmenvdk

Reputation: 1758

Davy Brion has an excellent set of blog posts on this subject: located on GitHub

Upvotes: 6

Jahan Zinedine
Jahan Zinedine

Reputation: 14874

My Humble Opinions

  1. Use interfaces instead of abstract class if User hasn't any hierarchy.
  2. Write a generic DAL so that you can reuse it as a facade for DAL layer.
  3. Resolve the concrete DALs by a DI framework

Upvotes: 7

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 120937

None of those classes should be static. I don't think you should name your classes DAL either, because its short for Data Access Layer, and a class in itself is not a layer (in my mind at least). You can use the widely adopted term repository instead. I suggest you do something like the following:

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);
    }
}

Note that the UserService is injected with an instance of the abstract class UserRepository in its constructor. You can use a Dependency Injection (DI) framework to do this for you automatically, such as Windsor Castle from Castle Project. It will allow you to specify a mapping from abstraction (UserRepository) to concrete implementation (eg. SqlUserRepository) in a configuration file, or in code.

Hope this points you in the right direction, and please ask if you need more information.

Upvotes: 16

Related Questions