MVC: Repositories and Services - asp.net-mvc

I am confused as to the limitations of what gets defined in the Repositories and what to leave to the Services. Should the repository only create simple entities matching tables from the database or can it create complex custom object with combinations of those entities?
in other words: Should Services be making various Linq to SQL queries on the Repository? Or should all the queries be predefined in the Repository and the business logic simply decide which method to call?

You've actually raised a question here that's currently generating a lot of discussion in the developer community - see the follow-up comments to Should my repository expose IQueryable?
The repository can - and should - create complex combination objects containing multiple associated entities. In domain-driven design, these are called aggregates - collections of associated objects organized into some cohesive structure. Your code doesn't have to call GetCustomer(), GetOrdersForCustomer(), GetInvoicesForCustomer() separately - you just call myCustomerRepository.Load(customerId), and you get back a deep customer object with those properties already instantiated. I should also add that if you're returning individual objects based on specific database tables, then that's a perfectly valid approach, but it's not really a repository per sé - it's just a data-access layer.
On one hand, there is a compelling argument that Linq-to-SQL objects, with their 'smart' properties and their deferred execution (i.e. not loading Customer.Orders until you actually use it) are a completely valid implementation of the repository pattern, because you're not actually running database code, you're running LINQ statements (which are then translated into DB code by the underlying LINQ provider)
On the other hand, as Matt Briggs' post points out, L2S is fairly tightly coupled to your database structure (one class per table) and has limitations (no many-many mappings, for example) - and you may be better off using L2S for data access within your repository, but then map the L2S objects onto your own domain model objects and return those.

A repository should be the only piece of your application that knows anything about your data access technology. So it should not be returning objects generated by L2S at all, but map those properties to model objects of your own.
If you are using this sort of pattern, you may want to re think L2S. It generates up a data access layer for you, but doesn't really handle impedance mismatch, you have to do that manually. If you look at something like NHibernate, that mapping is done in a more robust fashion. L2S is more for a 2 tier application, where you want a quick and dirty DAL that you can extend on easily.

If you're using LINQ then my belief is that the repository should be a container for your LINQ syntax. This gives you a level of abstraction of the database access routines from your model object interfacing. As Dylan mentions above there are other views on the matter, some people like to return the IQueryable so they can continue to query the database at a later point after the repository. There is nothing wrong with either of these approaches, as long as you're clear in your standards for your application. There is more informaiton on the best practices I use for LINQ repositories here.

Related

Returning Custom Models from LINQ queries, using Repository and Unit of Work with Entity Framework

I have implemented Repository + UnitOfWork pattern in my DAL, I am using Entity Framework (EF) to connect to the DB.
The service layer calls UnitOfWork to get a specific repository, and then interacts with repository methods using EF Entities.
The returned EF Entities from Repository to Service, are then mapped into Models (POCO objects, only properties, no functionality), and then these POCOs are passed to the Controller that called the Service in the first place.
All looks good so far, except when:
I need to use "Joins" in my LINQ queries in my repository, and return a custom object to the service layer.
The problem here is, that I was making sure, my repository only takes in and sends out EF Entities. But if I need to use join, I'll be populating a custom Model object, and will then be passing back Model instead of EF Entity.
To tackle the above problem, I was thinking that I should change my repository such that, it takes IN entities (e.g. for ADD, DELETE, UPDATE), but returns back Models (for select methods etc).
This means, my service layer will be creating Entities from Models, and then passing entities to the Repository, for any ADD, UPDATE, DELETE
And my Repository will be creating Models from Entities when returning results of a select LINQ queries.
Any thoughts if I'll be in a greater problem later if I choose to go with the above design?
If the above design is not a good solution, any other advise?
You're using the wrong repository approach, the anti-pattern. The Repository makes sens only as a decoupling pattern i.e you want tot decouple the Business Layer(BL) from the Persistence Layer(PL).
This means, your Bl (and services) don't know about EF or any other ORM. This means that your repository interface only know about what BL knows,that is the business objects. Your repository should NEVER expose EF, IQueryable or other PL detail.
First of all you need UoW pattern ONLY when updating a model, never just for queries. Then, when you're asking the repository for something, you tell it what you want and the repository will use EF, create queries, joins etc and maps the query results to the POCO the repository returns . So the mapping from EF entities to domain objects is done inside the repository.
Actually, ALL work related to the database via EF (or any other ORM) is done inside the repository. The BL just gets their object in the final form. That's the whole point of the repository.
What you're doing now is wrong, because you are doing repository's work at the BL level, violating the Separation of Concerns principle. The proper use of repository is like I wrote above.
P.S: In case you wonder, the generic repository is an anti pattern, stay away from it. As a side note, a generic repository interface is not the same thing as a generic repository.

How can I query cross tables with Repository Pattern?

In my asp.net mvc 3 application, I'm using the repository pattern.
I have 3 entities, Company, Country, City. Each of them has their own repository. Company entity has FoundedCountry and FoundedCity foreign keys.
Now in a view, I want to show the company details. In this view I want to view Company details as well as, FoundedCountry name and FoundedCity name. In my opinion I have to handle this with a kind of JOIN query. But I'm stuck at how to achieve this in repository pattern. How can I handle this JOIN in repository pattern?
Thank you.
The repository should have a task-based interface. This means that ORM's, joins etc are inside the repository. The app just sees an interface whtch returns an object that it can use.
This means you don't create a repository around a table (it pretty much defeats the purpose). In your scenario I suggest you have (at least) 2 repositories: one will handle everything related to updating the model and the other will serve only reads (queries).
This means the query repository will return only the data you want (it basically returns view model bits). Of course, the actual tables and joins are an implementation detail of the repository.
Don't construct your repository pattern in a way that is preventing joins! This usually means to use the same ORM context (DataContext/ObjectContext) for all instances associated with the current HTTP request.
I consider it to be an anti-pattern to have a generic IRepository because database access is rarely constrained to a single type of entity at the same time.
You could consider the DataContext/ObjectContext to be a repository by itself.
A last advice: If you don't know what a repository abstraction is good for - don't use one.

Can a pure DDD approach be used with NHibernate?

I've been reading up on DDD a little bit, and I am confused how this would fit in when using an ORM like NHibernate.
Right now I have a .NET MVC application with fairly "fat" controllers, and I'm trying to figure out how best to fix that. Moving this business logic into the model layer would be the best way to do this, but I am unsure how one would do that.
My application is set up so that NHibernate's session is managed by an HttpModule (gets session / transaction out of my way), which is used by repositories that return the entity objects (Think S#arp arch... turns out a really duplicated a lot of their functionality in this). These repositories are used by DataServices, which right now are just wrappers around the Repositories (one-to-one mapping between them, e.g. UserDataService takes a UserRepository, or actually a Repository). These DataServices right now only ensure that data annotations decorating the entity classes are checked when saving / updating.
In this way, my entities are really just data objects, but do not contain any real logic. While I could put some things in the entity classes (e.g. an "Approve" method), when that action needs to do something like sending an e-mail, or touching other non-related objects, or, for instance, checking to see if there are any users that have the same e-mail before approving, etc., then the entity would need access to other repositories, etc. Injecting these with an IoC wouldn't work with NHibernate, so you'd have to use a factory pattern I'm assuming to get these. I don't see how you would mock those in tests though.
So the next most logical way to do it, I would think, would be to essentially have a service per controller, and extract all of the work being done in the controller currently into methods in each service. I would think that this is breaking with the DDD idea though, as the logic is now no longer contained in the actual model objects.
The other way of looking at that I guess is that each of those services forms a single model with the data object that it works against (Separation of data storage fields and the logic that operates on it), but I just wanted to see what others are doing to solve the "fat controller" issue with DDD while using an ORM like NHibernate that works by returning populated data objects, and the repository model.
Updated
I guess my problem is how I'm looking at this: NHibernate seems to put business objects (entities) at the bottom of the stack, which repositories then act on. The repositories are used by services which may use multiple repositories and other services (email, file access) to do things. I.e: App > Services > Repositories > Business Objects
The pure DDD approach I'm reading about seems to reflect an Active Record bias, where the CRUD functions exist in the business objects (This I call User.Delete directly instead of Repository.Delete from a service), and the actual business object handles the logic of things that need to be done in this instance (Like emailing the user, and deleting files belonging to the user, etc.). I.e. App > (Services) > Business Objects > Repositories
With NHibernate, it seems I would be better off using the first approach given the way NHibernate functions, and I am looking for confirmation on my logic. Or if I'm just confused, some clarification on how this layered approach is supposed to work. My understanding is that if I have an "Approve" method that updates the User model, persists it, and lets say, emails a few people, that this method should go on the User entity object, but to allow for proper IoC so I can inject the messagingService, I need to do this in my service layer instead of on the User object.
From a "multiple UI" point of view this makes sense, as the logic to do things is taken out of my UI layer (MVC), and put into these services... but I'm essentially just factoring the logic out to another class instead of doing it directly in the controller, and if I am not ever going to have any other UI's involved, then I've just traded a "fat controller" for a "fat service", since the service is essentially going to encapsulate a method per controller action to do it's work.
DDD does not have an Active Record slant. Delete is not a method that should be on an Entity (like User) in DDD.
NHibernate does support a DDD approach very well, because of how completely divorced it remains from your entity classes.
when that action needs to do something
like sending an e-mail, or touching
other non-related objects
One piece of the puzzle it seems you are missing is Domain Events. A domain entity shouldn't send an email directly. It should raise an event in the Domain that some significant event has happened. Implement a class whose purpose is to send the email when the event occurs, and register it to listen for the Domain Event.
or, for instance, checking to see if
there are any users that have the same
e-mail before approving
This should probably be checked before submitting the call to "approve," rather than in the function that does the approving. Push the decision up a level in calling code.
So the next most logical way to do it,
I would think, would be to essentially
have a service per controller
This can work, if it's done with the understanding that the service is an entry point for the client. The service's purpose here is to take in parameters in a DTO from the front end/client and translate that into method calls against an entity in order to perform the desired funcitonality.
The only limitations NHibernate creates for classes is all methods/properties must be virtual and a class must have a default constructor (can be internal or protected). Otherwise, it does not [edit] interfere with object structure and can map to pretty complex models.
The short answer to you question is yes, in fact, I find NHibernate enhances DDD - you can focus on developing (and altering) your domain model with a code first approach, then easily retro-fit persistence later using NHibernate.
As you build out your domain model following DDD, I would expect that much of the business logic that's found you way into you MVC controllers should probably reside in your domain objects. In my first attempt at using ASP.NET MVC I quickly found myself in the same position as yourself - fat controllers and an anemic domain model.
To avoid this, I'm now following the approach of keeping a rich domain model that implements the business logic and using MVC's model as essentially simple data objects used by my views. This simplifies my controllers - they interact with my domain model and provide simple data objects (from the MVC model) to the views.
Updated
The pure DDD approach I'm reading about seems to reflect an Active Record bias...
To me the active record pattern means entities are aware of their persistance mechanism and an entity maps directly to a database table record. This is one way of using NHibernate e.g. see Castle Active Record, however, I find this pollutes domain enitities with knowledge of their persistence mechanism. Instead, typically, I'll have a repository per aggregate root in my domain model which implements an abstract repository. The abstract repository provides basic CRUD methods such as:
public IList<TEntity> GetAll()
public TEntity GetById(int id)
public void SaveOrUpdate(TEntity entity)
public void Delete(TEntity entity)
.. which my concrete repositories can supplement/extend.
See this post on The NHibernate FAQ which I've based a lot of my stuff on. Also remember, NHibernate (depending on how you set up your mappings) will allow you to de-persist a complete object graph, i.e. your aggregate root plus all the objects hanging off it and once you've finished working with it, can cascade saves through you entire object graph, this certainly isn't active record.
...since the service is essentially going to encapsulate a method per controller action to do it's work...
I still think you should consider what functionality that you currently have in your controllers should, more logically, be implemented within your domain objects. e.g. in your approval example, I think it would be sensible for an entity to expose an approve method which does whatever it needs to do to within the entity and if, as in your example, needs to send emails, delegate this to a service. Services should be reserved for cross-cutting concerns. Then, once you've finished working with your domain objects, pass them back to your repository to persist changes.
A couple of books I've found useful on these topics are:
Domain-Driven Design by Eric Evans
Applying Domain-Driven Design and Patterns by Jimmy Nilsson

ASP.NET MVC - model decision: how to design it?

This is concerning an enterprise application with a very generic database (all objects are identified using data in the database and internationalized/globalized/localized).
Make a model for Repository pattern, then make (generate 1:1) another model for DB access (LINQ2SQL or EF) and use the later as repository model data access layer?
Just use L2S/EF/NHibernate model directly, mapping model to DB and opening persistence layer?
Will this dual model idea (repository pattern) popup problems making dynamic stackable LINQ search queries possible when using L2S/EF model directly in a dual model environment?
Please advise.
As long as you are exposing IQueryable objects in your repository, you should have no problem stacking queries in the manner you suggest.
I would be cautious about using Entity Framework for this, since lazy loading is not supported in the way you might expect. Linq to SQL will handle lazy loading without problems.
For more information about lazy loading in the Entity Framework, see: http://www.singingeels.com/Articles/Entity_Framework_and_Lazy_Loading.aspx
Take a look at sharp architecture.
Regarding returning IQueryable from your repository objects, it is my opinion that doing such blurs a proper separation of concerns in your application. I'm all for working with IQueryable within your data access layer but once you start returning objects as IQueryable you provide the opportunity for your controllers and/or views to start meddling with data access. Such may even negatively impact the testability of your application as well.

Repository Pattern - MVC storefront

Have been looking at the MVC storefront and see that IQueryable is returned from the repository classes. Wondering if you are not using LINQ does it makes sense to return that object? In the case of LINQ in makes sense because of deferred execution, so adding filtering in the service layer makes sense, but if you don't use LINQ you would want to filter in the DB in many cases. In this case would I just add methods that do the filtering to the repository? If I do, is the service layer really useful?
Arguments can be made either way, see this recent blog posting: Should my repository expose IQueryable?
The IQueryable stuff that Rob Conery put into the MVC Storefront is innovative, but by no means the norm when it comes to creating repositories. Usually, a repository is responsible for mapping your domain to and from the database. Returning IQueryable doesn't really perform any mapping and relies on the services layer to do that. This has its advantages and disadvantages, but suffice it to say that it's not the only way to do it.
You will notice, however, that your services end up becoming a little smelly because of all the duplicate code. For instance, if you just want to get a list of all the users in your database you'd have to define that function in both the repository and the service layer. Where the service layer shines, however, is when multiple transactions to/from the database are needed for one operation.
The issue I have with exposing IQueryable to the Service Layer is that if you ever wanted to wrap the Repository layer behind a Web Service without breaking the Service Layer code you couldn't, well not without using ADO.NET Data Services but then all your Repository code would essentially become redundant.
Whilst I think it can be pretty productive for small apps, when you start looking at scaling and distribution it does more bad than good.

Resources