4

We are moving from ASP.NET Web Forms to MVC 2.0. In most of our projects we have a typical setup to communicate with a database.

Common (objects/entities like 'SiteMenu' and 'Users')

Business Logic Layer (with calls to de Data Access Layer)

Data Access Layer

The DAL has a DatabaseHelper with common database operation, an OdbcHelper with database specific operations (eg MySQL) and a StoredProcedure class with all the stored procedures.

How is this design translated into a repository design? We want to use our own database helpers instead of NHibernate etc.

What would you suggest?

tereško
  • 56,151
  • 24
  • 92
  • 147
jpderooy
  • 73
  • 1
  • 5

2 Answers2

3

You could leverage repositories using every data access technology. An repository is abstraction over existing data access helpers / services, allowing decoupling of the business logic from the data access layer. Repositories used together with Query to enable filtering. It is often used together with unit of work to store the changes back into database.

A repository has at least:

  1. Get-object-by-key operation(s)
  2. Get-all-objects operation
  3. Get-first-object-by-query operation(s)
  4. Get-objects-by-query operation(s)

A very simple example :):

A. Product class , defined in Common:

public class Product
{
    public int Id { get; private set; }

    public string Code { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }
}

B. Classes for Query, IRepository and IUnitOfWork are defined in DAL.interfaces.dll or Common.dll (but NOT in DAL!).

public class Query
{
    public string Text { get; set; }
}

public interface IRepository<TEntity>
    where TEntity : class
{
    bool TryGet(int key, out TEntity value);

    TEntity this[int key] { get; }

    IEnumerable<TEntity> GetAll();

    bool TryGetFirst(Query condition, out TEntity value);

    TEntity GetFirst(Query condition);

    IEnumerable<TEntity> GetAll(Query condition);

    int Count { get; }
}


public interface IUnitOfWork
{
    void SetAdded(TEntity value); // Marks entity as added for further INSERT

    void SetRemoved(TEntity value); // Marks entity as removed for further DELETE

    void SetChanged(TEntity value); // Marks entity as modified for further UPDATE

    void Save(); // Save all the changes 
}

IUnitOfWork is aware of the changed entities. Save() calls an appropriate DatabaseHelper / OdbcHelper CRUD method for every changed entity in order to persist the changes in the database.

The implementation of IRepository<Product>, ... IRepository<EntityXY> and IUnitOFWork should be placed in DAL. The BLL then uses IRepository and IUnitOFWork in order to implement business (domain) logic. The BLL itself could be organized as service layer on the top of domain model, but it is out of the scope of the discussion :).

I hope my answer helps.

Please feel free to ask me a question ...

Links: Patterns of enterpise application architecture by Martin Fowler

Easy-Rider
  • 31
  • 3
1

You can maintain the same layered approach when moving to MVC. Your BLL that returns entities/objects can be your M in MVC. Often you'll see in samples where people create an instance of the repository directly in their Controller, in your case you'll be creating an instance of your BLL class.

e36M3
  • 5,494
  • 4
  • 33
  • 47
  • We use entities/object in the M (models) when we want to expose them to a view. Otherwise we now have them put in a seperate Domain class library. But how to use the repository design? And where to put the database calls (generic and database specific)? Maybe its just a naming thing, but ány thoughts are welcome! – jpderooy Feb 08 '11 at 13:34
  • A repository is nothing more than a different spin on your DAL classes that utilize whatever database technology that you use. I don't want to get into the details of how the Repository is different than your DAL classes, it's an easy google query to make. However in essence they server similar purposes. Otherwise you would still create an instance of your BLL class in your controller, which in turn would create an instance of the Repository, eventually returning the entity all the way up to use as the M in MVC. – e36M3 Feb 08 '11 at 13:37
  • Hi, that makes sense. I think the Repository <> DAL difference or similarity isn't clear (even through a google search). Can you give me some more information about the setup? Entities, Business Logic and a Repository which communicates with the database? Where - in a logical folder structure and name - do we put the database specific operations like db.run() e.g.? Thanks! – jpderooy Feb 08 '11 at 13:44
  • I think Repositories really work well with ORMs like Entity Framework or NHibernate. What you're using is probably more of a DAO (Data Access Object). [Here is a good starting point](http://stackoverflow.com/questions/291344/repository-pattern-vs-dal). There isn't one right answer when it comes to architecture, and I'm by no means an expert. Your typical setup of Controller creates an instance of the business layer object which creates an instance of the data access object (repository or dao) which returns an entity is one absolutely correct approach. – e36M3 Feb 08 '11 at 13:51