5

I am trying to organize data access layer in asp.net mvc project. I've read a lot different articles about this, so still I have some questions in order to finish with this problem:

  1. Should I create instances of repository for every entity in database or for all or one genereal instance, for example PostRepository can include entities like Post, Comment and Tag?

  2. In controller I have to get some data, transform in into ViewModel and pass it into view. Where is the best place to do this? Services, Controller or something else?

  3. If it is Service. How many services should I create? Also for every entity and pass into Controller 3 or 4 services if it is necessery? Or maybe do it like I wanted to do it in repository? (Create one common service which would contain some count of repositories. PostService, with repositories like PostRepository, CommentRepository and TagRepository)

Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
Mutex
  • 430
  • 2
  • 5
  • 14
  • 5
    This is primarily opinion-based as there is no general "right and wrong". It also depends on your specific use cases and preferences. I for myself don't like repositories in such cases at all, as a `DbContext` is my repository IMO... – Christoph Fink Feb 05 '15 at 08:04

2 Answers2

3

Here is my take:

Should I create instances of repository for every entity in database or for all or one genereal instance, for example PostRepository can include entities like Post, Comment and Tag?

Having one single generic repository will save you a lot of maintenance headache. You could implement single generic repository like:

/// <summary>
/// This interface provides an abstraction for accessing a data source.
/// </summary>
public interface IDataContext : IDisposable
{
    IQueryable<T> Query<T>() where T : class;

    T Add<T>(T item) where T : class;

    int Update<T>(T item) where T : class;

    void Delete<T>(T item) where T : class;

    /// <summary>
    /// Allow repositories to control when SaveChanges() is called
    /// </summary>
    int SaveChanges();
}

and implement above interface in single context class.

Some people implement separate specific repositories as well.

In controller I have to get some data, transform in into ViewModel and pass it into view. Where is the best place to do this? Services, Controller or something else?

Define all your model (DTO or entities or POCO) classes in a separate assembly accessible from DA, service and Web. Service methods returns model instance, controller convert them into viewmodel (use AutoMapper) and pass to view. Again in post method controller first convert VM into Model and then pass to Service layer for persistance or processing.

If it is Service. How many services should I create? Also for every entity and pass into Controller 3 or 4 services if it is necessery? Or maybe do it like I wanted to do it in repository? (Create one common service which would contain some count of repositories. PostService, with repositories like PostRepository, CommentRepository and TagRepository)

I strongly suggest you define service very specific. Use Single Responsibility Principle to define your services. Each service should provide related set of functions. E.g. AuthService will authenticate user not sending them email, that EmailService job.

The pattern I suggest work very nicely with different services. For example:

public class DriverSearchService : IDriverSearchService
{
    private readonly IBlobService _blobService;
    private readonly IDataContext _dataContext;

    public DriverSearchService(IDataContext dataContext, IBlobService blobService)
     {
         _blobService = blobService;
        _dataContext = dataContext;
     }

    public void SaveDriveSearch(int searchId)
    {
        // Fetch values from temp store and clear temp store
        var item = context.Query<SearchTempStore>().Single(s => s.SearchId == searchId);

        // Temp object is latest so update the main store
        var mainSearch = context.Query<Search>().Single(s => s.Id == searchId);
        mainSearch.LastExecutedOn = DateTime.UtcNow;
        mainSearch.DataAsBlob = item.DataAsBlob;
        context.Update(mainSearch);
    }
}
SBirthare
  • 5,117
  • 4
  • 34
  • 59
1

Basically I agree what @ChrFin commented on your post but I want to answer your questions anyway.

  1. Yes but only if you needed to. You should consider that Post entity might have virtual properties referencing to other entities. In case of that, you might not need separated repository. However you should consider performance issues while loading related entities.

  2. From my experience the best place to map to the ViewModel is service layer or manager layer - depends how you want to call it. I always try to keep my controllers thin as possible. As your applications grows you might want to reuse of your logic in other applications e.g. WCF. If you have transformations, business logic, other things in your controllers you'll be not able to share them.

  3. Depends. If you want to avoid multiple dependencies in your controller (which aslo have impact in unit testing), you should create just one service per controller - as I said it's not the rule. Service might contain multiple repositories. Generally, you don't want to as many services as repositories.

If you're starting developing application you should check this useful links before you decide to use repository pattern:

Favor query objects over repositories

Say No to the Repository Pattern in your DAL

MacGyver
  • 2,983
  • 1
  • 17
  • 14