EF 4.2, Repository & UoW - how to include relationships? - entity-framework-4

Been working with EF 4.2 but not with the repository or unit of work patterns. I'm trying to move to them but running into an issue. I've followed models where you create a repostirotybase abstract class, but having trouble crafting queries where i want to use the .Include() method for eager loading. Is this something you bake into the repository (so each repository would need to implement it) or further up at the layer that's consuming the data.
What's confusing is that if I have to put it in the repository (which appears to be the case), it's that limiting as then I have to provide a one size fits all to my consumers?

Create specific repository and add specific methods to load entity with relations. For example:
public class ProductRepository
{
public Product GetProductWithFeatures(int key)
{
return context.Products
.Include(p => p.Features)
.FirstOrDefault(p => p.Id == key);
}
}
Another approach is exposing IQueryable on your repository so you can call Include directly but such repository partially fails in decoupling your upper layer from EF.

Related

Onion Architecture - Repository Vs Service?

I am learning the well-known Onion Architecture from Jeffrey Palermo.
Not specific to this pattern, but I cannot see clearly the separation between repositories and domain services.
I (mis)understand that repository concerns data access and service are more about business layer (reference one or more repositories).
In many examples, a repository seems to have some kind of business logic behind like GetAllProductsByCategoryId or GetAllXXXBySomeCriteriaYYY.
For lists, it seems that service is just a wrapper on repository without any logic.
For hierarchies (parent/children/children), it is almost the same problem : is it the role of repository to load the complete hierarchy ?
The repository is not a gateway to access Database. It is an abstraction that allow you to store and load domain objects from some form of persistence store. (Database, Cache or even plain Collection). It take or return the domain objects instead of its internal field, hence it is an object oriented interface.
It is not recommended to add some methods like GetAllProductsByCategoryId or GetProductByName to the repository, because you will add more and more methods the repository as your use case/ object field count increase. Instead it is better to have a query method on the repository which takes a Specification. You can pass different implementations of the Specification to retrieve the products.
Overall, the goal of repository pattern is to create a storage abstraction that does not require changes when the use cases changes. This article talks about the Repository pattern in domain modelling in great detail. You may be interested.
For the second question: If I see a ProductRepository in the code, I'd expect that it returns me a list of Product. I also expect that each of the Product instance is complete. For example, if Product has a reference to ProductDetail object, I'd expect that Product.getDetail() returns me a ProductDetail instance rather than null. Maybe the implementation of the repository load ProductDetail together with Product, maybe the getDetail() method invoke ProductDetailRepository on the fly. I don't really care as a user of the repository. It is also possible that the Product only returns a ProductDetail id when I call getDetail(). It is perfect fine from the repository's contract point of view. However it complicates my client code and forces me to call ProductDetailRepository myself.
By the way, I've seen many service classes that solely wrap the repository classes in my past. I think it is an anti-pattern. It is better to have the callers of the services to use the repositories directly.
Repository pattern mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
So, repositories is to provide interface for CRUD operation on domain entities. Remember that Repositories deals with whole Aggregate.
Aggregates are groups of things that belong together. An Aggregate Root is the thing that holds them all together.
Example Order and OrderLines:
OrderLines have no reason to exist without their parent Order, nor can they belong to any other Order. In this case, Order and OrderLines would probably be an Aggregate, and the Order would be the Aggregate Root
Business logic should be in Domain Entities, not in Repository layer , application logic should be in service layer like your mention, services in here play a role as coordinator between repositoies.
While I'm still struggling with this, I want to post as an answer but also I accept (and want) feedback about this.
In the example GetProductsByCategory(int id)
First, let's think from the initial need. We hit a controller, probably the CategoryController so you have something like:
public CategoryController(ICategoryService service) {
// here we inject our service and keep a private variable.
}
public IHttpActionResult Category(int id) {
CategoryViewModel model = something.GetCategoryViewModel(id);
return View()
}
so far, so good. We need to declare 'something' that creates the view model.
Let's simplify and say:
public IHttpActionResult Category(int id) {
var dependencies = service.GetDependenciesForCategory(id);
CategoryViewModel model = new CategoryViewModel(dependencies);
return View()
}
ok, what are dependencies ? We maybe need the category tree, the products, the page, how many total products, etc.
so if we implemented this in a repository way, this could look like more or less like this :
public IHttpActionResult Category(int id) {
var products = repository.GetCategoryProducts(id);
var category = repository.GetCategory(id); // full details of the category
var childs = repository.GetCategoriesSummary(category.childs);
CategoryViewModel model = new CategoryViewModel(products, category, childs); // awouch!
return View()
}
instead, back to services :
public IHttpActionResult Category(int id) {
var category = service.GetCategory(id);
if (category == null) return NotFound(); //
var model = new CategoryViewModel(category);
return View(model);
}
much better, but what is exactly inside service.GetCategory(id) ?
public CategoryService(ICategoryRespository categoryRepository, IProductRepository productRepository) {
// same dependency injection here
public Category GetCategory(int id) {
var category = categoryRepository.Get(id);
var childs = categoryRepository.Get(category.childs) // int[] of ids
var products = productRepository.GetByCategory(id) // this doesn't look that good...
return category;
}
}
Let's try another approach, the unit of work, I will use Entity framework as the UoW and Repositories, so no need to create those.
public CategoryService(DbContext db) {
// same dependency injection here
public Category GetCategory(int id) {
var category = db.Category.Include(c=> c.Childs).Include(c=> c.Products).Find(id);
return category;
}
}
So here we are using the 'query' syntax instead of the method syntax, but instead of implementing our own complex, we can use our ORM. Also, we have access to ALL repositories, so we can still do our Unit of work inside our service.
Now we need to select which data we want, I probably don't want all the fields of my entities.
The best place I can see this is happening is actually on the ViewModel, each ViewModel may need to map it's own data, so let's change the implementation of the service again.
public CategoryService(DbContext db) {
// same dependency injection here
public Category GetCategory(int id) {
var category = db.Category.Find(id);
return category;
}
}
so where are all the products and inner categories?
let's take a look at the ViewModel, remember this will ONLY map data to values, if you are doing something else here, you are probably giving too much responsibility to your ViewModel.
public CategoryViewModel(Category category) {
Name = category.Name;
Id = category.Id;
Products = category.Products.Select(p=> new CategoryProductViewModel(p));
Childs = category.Childs.Select(c => c.Name); // only childs names.
}
you can imagine the CategoryProductViewModel by yourself right now.
BUT (why is there always a but??)
We are doing 3 db hits, and we are fetching all the category fields because of the Find. Also Lazy Loading must be enable. Not a real solution isn't it ?
To improve this, we can change find with where... but this will delegate the Single or Find to the ViewModel, also it will return an IQueryable<Category>, where we know it should be exactly one.
Remember I said "I'm still struggling?" this is mostly why. To fix this, we should return the exact needed data from the service (also know as the ..... you know it .... yes! the ViewModel).
so let's back to our controller :
public IHttpActionResult Category(int id) {
var model = service.GetProductCategoryViewModel(id);
if (category == null) return NotFound(); //
return View(model);
}
inside the GetProductCategoryViewModel method, we can call private methods that return the different pieces and assemble them as the ViewModel.
this is bad, now my services know about viewmodels... let's fix that.
We create an interface, this interface is the actual contract of what this method will return.
ICategoryWithProductsAndChildsIds // quite verbose, i know.
nice, now we only need to declare our ViewModel as
public class CategoryViewModel : ICategoryWithProductsAndChildsIds
and implement it the way we want.
The interface looks like it has too many things, of course it can be splitted with ICategoryBasic, IProducts, IChilds, or whatever you may want to name those.
So when we implement another viewModel, we can choose to do only IProducts.
We can have our services having methods (private or not) to retrieve those contracts, and glue the pieces in the service layer. (Easy to say than done)
When I get into a fully working code, I might create a blog post or a github repo, but for now, I don't have it yet, so this is all for now.
I believe the Repository should be only for CRUD operations.
public interface IRepository<T>
{
Add(T)
Remove(T)
Get(id)
...
}
So IRepository would have: Add, Remove, Update, Get, GetAll and possibly a version of each of those that takes a list, i.e, AddMany, RemoveMany, etc.
For performing search retrieval operations you should have a second interface such as an IFinder. You can either go with a specification, so IFinder could have a Find(criteria) method that takes criterias. Or you can go with things like IPersonFinder which would define custom functions such as: a FindPersonByName, FindPersonByAge etc.
public interface IMyObjectFinder
{
FindByName(name)
FindByEmail(email)
FindAllSmallerThen(amount)
FindAllThatArePartOf(group)
...
}
The alternative would be:
public interface IFinder<T>
{
Find(criterias)
}
This second approach is more complex. You need to define a strategy for the criterias. Are you going to use a query language of some sort, or a more simple key-value association, etc. The full power of the interface is also harder to understand from simply looking at it. It's also easier to leak implementations with this method, because the criterias could be based around a particular type of persistence system, like if you take a SQL query as criteria for example. On the other hand, it might prevent you from having to continuously come back to the IFinder because you've hit a special use case that requires a more specific query. I say it might, because your criteria strategy will not necessarily cover 100% of the querying use cases you might need.
You could also decide to mix both together, and have an IFinder defining a Find method, and IMyObjectFinders that implement IFinder, but also add custom methods such as FindByName.
The service acts as a supervisor. Say you need to retrieve an item but must also process the item before it is returned to the client, and that processing might require information found in other items. So the service would retrieve all appropriate items using the Repositories and the Finders, it would then send the item to be processed to objects that encapsulates the necessary processing logic, and finally it would return the item requested by the client. Sometime, no processing and no extra retrievals will be required, in such cases, you don't need to have a service. You can have clients directly call into the Repositories and the Finders. This is one difference with the Onion and a Layered architecture, in the Onion, everything that is more outside can access everything more inside, not only the layer before it.
It would be the role of the repository to load the full hierarchy of what is needed to properly construct the item that it returns. So if your repository returns an item that has a List of another type of item, it should already resolve that. Personally though, I like to design my objects so that they don't contain references to other items, because it makes the repository more complex. I prefer to have my objects keep the Id of other items, so that if the client really needs that other item, he can query it again with the proper Repository given the Id. This flattens out all items returned by the Repositories, yet still let's you create hierarchies if you need to.
You could, if you really felt the need to, add a restraining mechanism to your Repository, so that you can specify exactly which field of the item you need. Say you have a Person, and only care for his name, you could do Get(id, name) and the Repository would not bother with getting every field of the Person, only it's name field. Doing this though, adds considerable complexity to the repository. And doing this with hierarchical objects is even more complex, especially if you want to restrict fields inside fields of fields. So I don't really recommend it. The only good reason for this, to me, would be cases where performance is critical, and nothing else can be done to improve the performance.
In Domain Driven Design the repository is responsible for retrieving the whole Aggregate.
Onion and Hexagonal Architectures purpose is to invert the dependency from domain->data access.
Rather than having a UI->api->domain->data-access,
you'll have something like UI->api->domain**<-**data-access
To make your most important asset, the domain logic, is in the center and free of external dependencies.
Generally by splitting the Repository into Interface/Implementation and putting the interface along with the business logic.
Now to services, there's more that one type of services:
Application Services: your controller and view model, which are external concerns for UI and display and are not part of the domain
Domain Services: which provide domain logic. In you're case if the logic you're having in application services starts to do more that it's presentation duties. you should look at extracting to a domain service
Infrastructure Services: which would, as with repositories, have an interface within the domain, and an implementation in the outer layers
#Bart Calixto, you may have a look at CQRS, building your view model is too complex when you're trying to use Repositories which you design for domain logic.
you could just rewrite another repo for the ViewModel, using SQL joins for example, and it doesn't have to be in the domain
is it the role of repository to load the complete hierarchy ?
Short answer: yes, if the repository's outcome is a hierarchy
The role of repository is to load whatever you want, in any shape you need, from the datasource (e.g. database, file system, Lucene index, etc).
Let's suppose a repository (interface) has the GetSomeHierarchyOrListBySomeCriteria operation - the operation, its parameters and its outcome are part of the application core!
Let's focus on the outcome: it doesn't matter it's shape (list, hierarchy, etc), the repository implementation is supposed to do everything necessary to return it.
If one is using a NoSql database than GetSomeHierarchyOrListBySomeCriteria implementation might need only one NoSql-database-query with no other conversions or transformations to get the desired outcome (e.g. hierarchy). For a SQL database on the other hand, the same outcome might imply multiple queries and complex conversions or transformations - but that's an implementation detail, the repository interface is the same.
repositories vs domain services
According to The Onion Architecture : part 1, and I'm pointing here about the official page, not someone's else interpretation:
The first layer around the Domain Model is typically where we would
find interfaces that provide object saving and retrieving behavior,
called repository interfaces. [...] Only the interface is in the application core.
Notice the Domain Services layer above Domain Model one.
Starting with the second official page, The Onion Architecture : part 2, the author forgets about Domain Services layer and is depicting IConferenceRepository as part of the Object Services layer which is right above Domain Model, replacing Domain Services layer! The Object Services layer continues in The Onion Architecture : part 3, so I ask: what Domain Services? :)))
It seems to me that author's intent for Object Services or Domain Services is to consist only of repositories, otherwise he leaves no clue for something else.

How to implement Aggregate Root repository an add child entity with EF

I'm developing an MVC application. I have a Domain Model, and I use a repositry pattern for data access and Entity Framework Code First. I also have a UnitOfWork class which I call the repository operations through.
My problem mainly arises when I try to take advantage of aggregate roots and handle child objects through their parent repository.
This is the problem:
Parent class "Supplier" has several Contracts with Departments. I've chosen to make the contract a child of Supplier in this case.
To add a new contract I need to add a method to add a contract in my SupplierRepository, I tried:
public class SupplierRepository : GenericRepository<Supplier>
{
public SupplierRepository(MyContext context)
: base(context)
{
}
public void AddSupplierContract(SupplierContract contract)
{
var supplier = context.Suppliers.Find(contract.SupplierId);
supplier.Contract.Add(contract);
}
And I also tried:
public void AddSupplierContract(SupplierContract contract)
{
context.Entry(contract).State = EntityState.Added;
}
}
When i call
_unitOfWork.save();
I get an error telling me:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker
UnitOfWork instansiates my DbContext (myDbContext) and my SupplierRepository and calls the myDbContext.Save()
Why do I get this behavior
How should I implement an Aggregate Root Repository (CRUD operations for the child objects)
As far as I understand I should have a method in the repository that takes a contract and adds it, and not do this in the Controller of my MVC app, but I don't seem to get it working.
I've seen a lot of information about Aggregate Roots, but no examples of how to implement it.
Thanks.
Solution:
Well I finally figured it out.
So it was not a problem with the repository, but the new SupplierContract queryed the store for the user entity that created it (through an extension method). Obviously this context did not dispose and therefore i had two current DbContexts when I instansiated it to save the contract entity.
Hopefully someone saves time by reading this.
The Aggregate Root repository I solved by just doing like this in the SupplierRepository:
public void AddSupplierContract(SupplierContract contract)
{
db.SupplierContracts.Add(contract);
}
And calling UnitOfWork.Save() method.
While technically you may have solved this issue, I do hope you are aware there's something fundamentally flawed in your design (unless you're using Fowler repositories): repositories (the DDD kind) deal in aggregates only. The fact that SupplierContract needs to be added to the context is not a concern of the calling code. So, why expose that method? I would also reconsider having the repository delegate the save (why else have a UoW). As far as aggregates are concerned I get the feeling you seem to be treating them as structural objects, not as behavioral ones. Hence you seem to be in for a world of pain, going through some of the moves, but not getting any of the value.
To get rid of that error, you should use same MyContext instance to create all the repositories. If you use some dependency-injector, it should allow you to configure same MyContext object through single request. For example, for Ninject, that would be
kernel.Bind<MyContext>().ToSelf().InRequestScope();

Real World ASP.NET MVC Repositories

In the real world, Controllers can potentially need to use data from a variety of database tables and other data stores. For example:
[Authorize]
public class MembersController : Controller
{
ICourseRepository repCourse;
IUserCourseRepository repUserCourse;
IMember member;
public MembersController(ICourseRepository repCourse, IUserCourseRepository repUserCourse, IMember member)
{
this.repCourse = repCourse;
this.repUserCourse = repUserCourse;
this.member = member;
}
So:
Should I use a repository for each table?
I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?
Do I just add as many Repositories as I need to the constructor of the Controller?
Is this a sign that my design is wrong?
NOTE:
The IMember interface essentially represents a helper object that puts a nice face on the Membership provider. Ie, it puts all the code in one place. For example:
Guid userId;
public Guid UserId
{
get
{
if (userId == null)
{
try
{
userId = (Guid) Membership.GetUser().ProviderUserKey;
}
catch { }
}
return userId;
}
}
One problem with that is surely caching this kind of output. I can feel another question coming on.
EDIT:
I'm using Ninject for DI and am pretty sold on the whole DI, DDD and TDD thing. Well, sort of. I also try to be a pragmatist...
1. Should I use a repository for each table?
Probably not. If you have a repository per table, you are essentially doing Active Record. I also personally prefer to avoid calling these classes "Repository" because of the confusion that can occur between Domain Driven Design's concept of a "Repository" and the class-per-table "Repository" that seems to have become commonly used with Linq2SQL, SubSonic, etc. and many MVC tutorials.
2. I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?
Yes and yes. If you are going to go this route.
'3.' Do I just add as many Repositories as I need to the constructor of the Controller?
I don't let my controllers touch my repositories directly. And I don't let my Views touch my domain classes directly, either.
Instead, my controllers have Query classes that are responsible for returning View Models. The Query classes reference whatever repositories (or other sources of data) they need to compile the View Model.
Well #awrigley, here is my advise:
Q: Should I use a repository for each table?
A: No, as you mentioned on question 2. use a repository per aggregate and perform the operations on aggregate root only.
Q: Do I just add as many Repositories as I need to the constructor of the Controller?
A: I guess you´re using IoC and constructor-injection, well, in this case, make sure you only pass real dependencies. this post may help you decide on this topic.
(pst! that empty catch is not a nice thing!!) ;)
Cheers!
This all depends on how "Domain Driven Design" your going to be. Do you know what an Aggregate Root is? Most of the time a generically typed repository that can do all your basic CRUD will suffice. Its only when you start having thick models with context and boundaries that this starts to matter.

Service Layer are repeating my Repositories

I'm developing an application using asp.net mvc, NHibernate and DDD. I have a service layer that are used by controllers of my application. Everything are using Unity to inject dependencies (ISessionFactory in repositories, repositories in services and services in controllers) and works fine.
But, it's very common I need a method in service to get only object in my repository, like this (in service class):
public class ProductService {
private readonly IUnitOfWork _uow;
private readonly IProductRepository _productRepository;
public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) {
this._uow = unitOfWork;
this._productRepository = productRepository;
}
/* this method should be exists in DDD ??? It's very common */
public Domain.Product Get(long key) {
return _productRepository.Get(key);
}
/* other common method... is correct by DDD ? */
public bool Delete(long key) {
usign (var tx = _uow.BeginTransaction()) {
try
{
_productRepository.Delete(key);
tx.Commit();
return true;
} catch {
tx.RollBack();
return false;
}
}
}
/* ... others methods ... */
}
This code is correct by DDD ? For each Service class I have a Repository, and for each service class need I do a method "Get" for an entity ?
Thanks guys
Cheers
Your ProductService doesn't look like it followed Domain-Driven Design principles. If I understand it correctly, it is a part of Application layer between Presentation and Domain. If so, the methods on ProductService should have business meaning with regard to products.
Let's talk about deleting products. Is it as simple as executing delete on the database (NHibernate, or whatever?) I think it is not. What about orders which reference the to-be-deleted product? And so on and so forth. Btw, Udi Dahan wrote a great article on deleting entities.
Bottom line is, if your application is so simple that services do really replicate your repositories and contain only CRUD operations, you probably shouldn't do DDD, throw away your repositories and let services operate on entities (which would be simple data containers in that case).
On the other hand, if there is a complicated behavior (like the one with handling 'deleted' products), there is a point in going DDD path and I strongly advocate doing so.
PS. Despite which approach (DDD or not) you will eventually take I would encourage you to use some Aspect Oriented Programming to handle transaction and exception related stuff. You would end up with way to many methods such as DeleteProduct with same TX and exception handling code.
That looks correct from my perspective. I really didn't like repeating service and repository method names over and over in my asp.net MVC project, so I went for a generic repository approach/pattern. This means that I really only need one or two Get() methods in my repository to retrieve my objects. This is possible for me because I am using Entity Framework and I just have my repository's get() method return a IQueryable. Then I can just do the following:
Product product = from p in _productRepository.Get() where p.Id == Id select p;
You can probably replicate this in NHibernate with linq -> NHibernate.
Edit: This works for DDD because this still allows me to interchange my DAL/repositories as long as the data library I am using (Nhibernate, EF, etc..) supports IQueryable.
I am not sure how to do a generic repository without IQueryable, but you might be able to use delegates/lambda functions to incorporate it.
Edit2: And just in case I didn't answer your question correctly, if you are asking if you are supposed to call your repository's Get() method from the service then yes, that is the correct DDD design as well. The reason is that the service layer is supposed to handle all your business logic, so it decides exactly how and what data to retrieve (for example, do you want it in alphabetical order, unordered, etc...). It also means that it can perform validation after loading if needed or validation before deleting and/or saving.
This means that the service layer doesn't care exactly how that data is stored and retrieved, it only decides what data is stored and retrieved. It then calls on the repository to handle the request correctly and retrieve/store the data in the way the service layer tells it to. Thus you have correct separation of concerns.

Separation of Concerns the Repository Pattern & Entity Framework 3.5

I'm trying to be a better developer...
What I'm working with:
.Net MVC Framework 1.0
Entity Framework 3.5
I've been doing some reading and I think what i want to do is:
Create a repository for each aggregate in the domain. An Order repository for example will manage an Order's OrderItems.
Create a service layer to handle business logic. Each repository will have a corresponding service object with similar methods.
Create DTOs to past between the repository and service
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).
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
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).
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
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.

Resources