Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have recently been reading an article about creating a blog using ASP.NET and MVC, and in the article the user splits the Data Access Layer into a separate Class Library, and creates an interface for this to allow the DAL to be mocked for testing.

This works great for small projects, but I am struggling to see how this will scale. For example in the article you end up with the following Interface:

public interface IBlogRepository
{
    IList<Objects.Post> Posts(int pageNo, int pageSize);
    int TotalPosts(bool checkIsPublished = true);

    IList<Objects.Post> PostsForCategory(string categorySlug, int pageNo, int pageSize);
    int TotalPostsForCategory(string categorySlug);
    Objects.Category Category(string categorySlug);

    IList<Objects.Post> PostsForTag(string tagSlug, int pageNo, int pageSize);
    int TotalPostsForTag(string tagSlug);
    Objects.Tag Tag(string tagSlug);

    IList<Objects.Post> PostsForSearch(string search, int pageNo, int pageSize);
    int TotalPostsForSearch(string search);

    Objects.Post Post(int year, int month, string titleSlug);

    IList<Objects.Category> Categories();
    IList<Objects.Tag> Tags();

    IList<Objects.Post> Posts(int pageNo, int pageSize, string sortColumn, bool sortByAscending);

    void AddPost(Objects.Post post);
}

There is then an associated .cs file with the implementation of this interface.

How would you implement a similar architecture for a much larger project? For example the project I have at work consists of 25 controllers, each having as a minimum list, add, edit, view, delete and count. That would lead to an interface with 150+ functions.

Is this kind of architecture still suitable for larger projects, and if so how would you structure this to avoid having a single file implementing 150+ functions?

share|improve this question
    
Best way is to use existing ORM solution and learn how to use it. Trying to abstract it using your own DAL layer will only result in pain. More at stackoverflow.com/questions/5625746/… –  Euphoric May 28 '13 at 13:07
    
@Euphoric: A DAL and a repository are not necessarily the same thing. You can use a DAL as part of a repository or BLL. –  Robert Harvey May 28 '13 at 14:22
    
@Euphoric / Robert Harvey - I am using Entity Framework as part of my DAL, perhaps BLL would be a more appropriate term? In my current project all the code sits in the Controllers, and there is a lot of duplication as a result. I'm hoping moving to a separate DAL/BLL structure may help to avoid some of this duplication. –  Gavin Coates May 28 '13 at 15:52

1 Answer 1

Take a look at using a generic base repository that contains some of the common functionality between all repositories.

interface IRepository<T>
{
     void Save();
     T GetById(int id);
     int GetCount();
}

From this you can create custom repositories for each action.

interface IUserRepository : IRepository<UserPosts>
{
    UserPosts GetPostsByUserId(int userId);
}

interface IOtherRepository : IRepository<OtherObject>
{
    void OtherRepositoryAction(int id);
}

This way you can reduce the number of actions each individual repository has. It also saves having a single "God" repository that does all actions for the application.

Strategies for creating repositories include:

  • One per database table
  • One per aggregate route

For the aggregate route model take a look at Domain Driven Design. Eric Evans has an excellent book on Domain Driven Design.

For each repository that you create you should apply dependency injection to bind the interface to a concrete type. DI containers include:

  • Autofac
  • StructureMap
  • Ninject

Depending on your architecture, these repositories can be called as follows (NOTE: I am not saying this is the best way, but it is a way):

public class UserController: Controller
{
    private readonly IUserService _userService;
    UserController(IUserService userService)
    {
         _userService = userService;
    }
    public void SaveUser(User user)
    {
        _userService.SaveUser(user);
    }
}

public UserService : IUserService
{
     private readonly IUserRepository _userRepository;
     public UserService(IUserRepository userRepository)
     {
        _userRepository = userRepository;
     }
     public void SaveUser(User user)
     {
         _userRepository.Save(user);
     }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.