views:

594

answers:

1

Hi,

I'm trying to be a better developer...

What I'm working with:

  1. .Net MVC Framework 1.0
  2. Entity Framework 3.5

I've been doing some reading and I think what i want to do is:

  1. Create a repository for each aggregate in the domain. An Order repository for example will manage an Order's OrderItems.
  2. Create a service layer to handle business logic. Each repository will have a corresponding service object with similar methods.
  3. Create DTOs to past between the repository and service
  4. Possibly create ViewModels which are classes for the View to consume.

I have a base repository interface which my aggregate repository interfaces will implement...

public interface IRepository<T>
    {
        IEnumerable<T> ListAll();
        T GetById(int id);
        bool Add(T entity);
        bool Remove(T entity);
    }

My Order Repository interface is defined as follows...there will likely be additional methods as I get more into this learning exercise.

public interface IOrderRepository : IRepository<Order>
{
}

My service classes are essentially defined the same as the repositories except that each service implementation includes the business logic. The services will take a repository interface in the constructor (I'm not ready for IoC in this exercise but believe that is where I'd like to end up down the road).

  1. The repository implementations will push and pull from the database using Entity Framework. When retrieving data; the methods will only return the DTOs and not the EF generated objects
  2. The services (as I'm calling them) will control the repository and perform the business logic. The services are what you will see in the controller i.e. _orderService.GetById(1).
  3. This is where I started flip flopping and could use some feedback...should I maybe have my service classes populate ViewModel classes...should I not have ViewModel classes....maybe that is too much mapping from one type to another?

I would love to get some feedback on the direction I am heading with regards to a separation of concerns.

Thanks

+1  A: 

I think you are heading in the right direction about the Repository pattern. Regarding your question about the ViewModel classes, i suggest that you use something that transforms the output of the business service method outputs to some desired outputs. For example your Order business service may have a method called GetOrders(). Using a custom attribute you may define the view class type for it. The view is able to get the output of this method, possibly joins it with other kinds of data and returns the result as a collection of objects with anonymous types. In this case the view will take IQueryable<Order> or IEnumerable<Order> as input and returns IList as the output.

This method will help you greatly when you need to show different kinds of views of your data on the client side. We have already utilized something similar (but more complex) to this method in our company's framework.

O. Askari
Thanks for the feedback. This suggestion sounds very interesting. Are you basically saying that I could create a custom attribute that will provide another way of looking at the data...just like a view? If that is the case, can you point me in the right direction for this concept. Sounds like it could be a great idea.Also, when the repository returns DTO objects, they are generally the same name as the EF generated objects...would you suggest just using a different naming convention for the DTOs to avoid type conflicts?
Cedar Teeth
One way I do it is to create a ViewModel per View. Where the ViewModel classes are just aggregates of the data I want to display. I don't see any problem with moving the ORM Entities thru these ViewModels, but if that makes you uncomfortable, you can always just put the ORM models in another assembly, and make them private. Then use something like StuctureMap to transform them into your ViewModel and it's data.
Kris
Custom attribute will give you the ability to define different possible view models for business service methods. Thus those method's output will be fed to the view model and it will take care of generating the desired output. To implement this behavior you'll need a proxy class for the business service that calls the desired method, extracts the appropriate view name from meta data, passes the business output to the view then returns the view output.
O. Askari
Regarding the naming convention, if you are going to use many views i suggest to get their outputs as Anonymous types. Once you get the output, you may use Reflection to find out the output object's properties and types then you'll be able to render the view accordingly.
O. Askari
Thank you, I will have a look at your suggestion this weekend!
Cedar Teeth