I am utilizing ASP.NET WebAPI 2 & EF6 for a very small project which utilizes AutoFac to inject my DbContext directly into my controllers. I am not using a repository pattern as per Ryan's answer here: NOT using repository pattern, use the ORM as is (EF). To perform the injection, I went ahead and created an interface like so:
public interface IMoveGroupEntities : IDisposable
{
System.Data.Entity.DbSet<HostEntry> HostEntries { get; set; }
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Task<int> SaveChangesAsync();
}
Then implemented the interface on a partial class which sits in conjunction with my generated entities like so:
public partial class MoveGroupEntities : IMoveGroupEntities
{
}
I have a sneaking suspicion I'm doing something incorrectly here as I feel like this line:
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Shouldn't be needed, but it does appear to be necessary as "Entry" is used from within my scaffolded API controller.
Can anyone chime in here on a better way to achieve this?
The best you can say about scaffolded code is: it works. It's not the best code architecturally. I fully agree with the link you quote, but that doesn't mean that the controllers should be in touch with EF artifacts directly (including Entry).
I think it's a mistake to replace one DbSet wrapper (repository) by another wrapper. The gist of the answer is: use the context (and DbSets, etc.) directly in your code. That is: don't use wrappers. That is not: use contexts (etc.) anywhere. You're doing the exact opposite: you create a different type of wrapper in order to use EF anywhere. But it's a good thing that your gut feeling doesn't really like it.
I always prefer to keep action methods (MVC, Web API) small. Basically, I just make them call a service method. It's the service that deals with contexts and everything EF has to offer. These services may be in a separate assembly, but wherever they are, they are injected into the controllers by dependency injection and, likewise, they obtain their contexts by DI.
I have watched Julie Lerman's videos about using EF in an enterprise application. Now I am developing a website using "Bounded Contexts" and other stuff she has taught in that series.
The problem is I do not know how to use bounded contexts (BC) from within my "Business Layer". To make it clearer: How should the BL know that which specific BC it should use.
Suppose the UI requests a list of products from the business layer. In BL I have a method that returns a list of products: GetAll(). This method does not know which part of the UI (site admin, moderator or public user) has requested the list of products. Since each user/scenario has its own bounded context, the list needs to be pulled using that related context. How should the BL choose the appropriate BC?
Moreover I do not want the UI layer to interact with data layer.
How can this be done?
If by business layer you mean a place where all your business rules are defined, then that is a bounded context.
A bounded context looks at your system from a certain angle so that business rules can be implemented in a compartmentalised fashion (with the goal that it is easier to handle the overall problem by splitting in to smaller chunks).
http://martinfowler.com/bliki/BoundedContext.html
Front-end
So assuming you have a ASP MVC front end, this controllers are the things that will call your use cases/user stories that are presented from the domain to be called via a standard known interface.
public class UserController : Controller
{
ICommandHandler<ChangeNameCommand> handler;
public UserController(ICommandHandler<ChangeNameCommand> handler)
{
this.handler = handler;
}
public ActionResult ChangeUserName(string id, string name)
{
try
{
var command = new ChangeNameCommand(id,name);
var data = handler.handle(command);
}
catch(Exception e)
{
// add error logging and display info
ViewBag.Error = e.Message;
}
// everything went OK, let the user know
return View("Index");
}
}
Domain Application (Use Cases)
Next, you would have an domain application entry point that implements the use case (this would be a command or query handler).
You may call this directly and have the code run in-process with your front end application, or you may have a WebAPI or WCF service in front of it presenting the domain application services. It doesn't really matter, how you the system is distrusted depends on the system requirements (it is often simpler from an infrastructure perspective to not to distribute if not needed).
The domain application layer then orchestrates the user story - it will new up repositories, fetch entities, perform an operation on them, and then write back to the repository. The code here should not be complex or contain logic.
public class NewUserHandler : ICommandHandler<ChangeNameCommand>
{
private readonly IRepository repository;
public NewUserHandler(IRepository repository)
{
this.repository = repository;
}
public void Handle(ChangeUserName command)
{
var userId = new UserId(command.UserId);
var user = this.repository.GetById<User>(userId);
user.ChangeName(command.NewName);
this.repository.Save(newUser);
}
}
Domain Model
The entities them selves implement their own business logic in the domain model. You may also have domain services for logic which doesn't naturally fit nicely inside an individual entity.
public class User
{
protected string Name;
protected DateTime NameLastChangedOn;
public ChangeName(string newName)
{
// not the best of business rules, just an example...
if((DateTime.UtcNow - NameLastChangedOn).Days < 30)
{
throw new DomainException("Cannot change name more than once every 30 days");
}
this.Name = newName;
this.NameLastChangedOn = DateTime.UtcNow;
}
}
Infrastructure
You would have infrastructure which implements the code to fetch and retrieve entities from your backing store. For you this is Entity Framework and the DbContext (my example code above is not using EF but you can substitute).
Answer to your question - Which bounded context should the front end application call?
Not to make the answer complex or long, but I included the above code to set the background and hope to make it easier to understand as I think the terms you are using are getting a little mixed up.
With the above code as you started implementing more command and query handlers, which bounded context is called from your front end application depends on what specific user story the user wishes to perform.
User stories will generally be clustered across different bounded contexts, so you would just select the command or query for the bounded context that implements the required functionality - don't worry about making it anything more complicated than that.
Let the problem you are trying to solve dictate the mapping, and dont be afraid that this mapping will possibly change as insight in to the problem you are looking to solve improves.
Sidenote
As a side note to mention things I found useful (I started my DDD journey with EF)... with entity framework there are ORM concepts that are often required such as defining mapping relationships and navigation properties between entities, and what happens with cascade deletes and updates. For me, this started to influence how I designed my entities, rather than the problem dictating how the entities should be designed. You may find this interesting: http://mehdi.me/ambient-dbcontext-in-ef6/
You may also want to look at http://geteventstore.com and event sourcing which takes away any headaches of ORM mapping (but comes with added complexity and workarounds needed to get acceptable performance). What is best to use depends on the situation, but its always good to know all the options.
I also use SimpleInjector to wire up my classes and inject in to the MVC controller (as a prebuilt Command or Query handler), more info here: https://cuttingedge.it/blogs/steven/pivot/entry.php?id=91.
Using an IoC container is a personal preference only and not set in stone.
This book is also awesome: https://vaughnvernon.co/?page_id=168
I mention the above as I started my DDD journey with EF and the exact same question you had.
I always used Repository pattern but for my latest project I wanted to see if I could perfect the use of it and my implementation of “Unit Of Work”. The more I started digging I started asking myself the question: "Do I really need it?"
Now this all starts with a couple of comments on Stackoverflow with a trace to Ayende Rahien's post on his blog, with 2 specific,
repository-is-the-new-singleton
ask-ayende-life-without-repositories-are-they-worth-living
This could probably be talked about forever and ever and it depends on different applications. Whats I like to know,
would this approach be suited for a Entity Framework project?
using this approach is the business logic still going in a service layer, or extension methods (as explained below, I know, the extension method is using NHib session)?
That's easily done using extension methods. Clean, simple and reusable.
public static IEnumerable GetAll(
this ISession instance, Expression<Func<T, bool>> where) where T : class
{
return instance.QueryOver().Where(where).List();
}
Using this approach and Ninject as DI, do I need to make the Context a interface and inject that in my controllers?
I've gone down many paths and created many implementations of repositories on different projects and... I've thrown the towel in and given up on it, here's why.
Coding for the exception
Do you code for the 1% chance your database is going to change from one technology to another? If you're thinking about your business's future state and say yes that's a possibility then a) they must have a lot of money to afford to do a migration to another DB technology or b) you're choosing a DB technology for fun or c) something has gone horribly wrong with the first technology you decided to use.
Why throw away the rich LINQ syntax?
LINQ and EF were developed so you could do neat stuff with it to read and traverse object graphs. Creating and maintain a repository that can give you the same flexibility to do that is a monstrous task. In my experience any time I've created a repository I've ALWAYS had business logic leak into the repository layer to either make queries more performant and/or reduce the number of hits to the database.
I don't want to create a method for every single permutation of a query that I have to write. I might as well write stored procedures. I don't want GetOrder, GetOrderWithOrderItem, GetOrderWithOrderItemWithOrderActivity, GetOrderByUserId, and so on... I just want to get the main entity and traverse and include the object graph as I so please.
Most examples of repositories are bullshit
Unless you are developing something REALLY bare-bones like a blog or something your queries are never going to be as simple as 90% of the examples you find on the internet surrounding the repository pattern. I cannot stress this enough! This is something that one has to crawl through the mud to figure out. There will always be that one query that breaks your perfectly thought out repository/solution that you've created, and it's not until that point where you second guess yourself and the technical debt/erosion begins.
Don't unit test me bro
But what about unit testing if I don't have a repository? How will I mock? Simple, you don't. Lets look at it from both angles:
No repository - You can mock the DbContext using an IDbContext or some other tricks but then you're really unit testing LINQ to Objects and not LINQ to Entities because the query is determined at runtime... OK so that's not good! So now it's up to the integration test to cover this.
With repository - You can now mock your repositories and unit test the layer(s) in between. Great right? Well not really... In the cases above where you have to leak logic into the repository layer to make queries more performant and/or less hits to the database, how can your unit tests cover that? It's now in the repo layer and you don't want to test IQueryable<T> right? Also let's be honest, your unit tests aren't going to cover the queries that have a 20 line .Where() clause and .Include()'s a bunch of relationships and hits the database again to do all this other stuff, blah, blah, blah anyways because the query is generated at runtime. Also since you created a repository to keep the upper layers persistence ignorant, if you now you want to change your database technology, sorry your unit tests are definitely not going to guarantee the same results at runtime, back to integration tests. So the whole point of the repository seems weird..
2 cents
We already lose a lot of functionality and syntax when using EF over plain stored procedures (bulk inserts, bulk deletes, CTEs, etc.) but I also code in C# so I don't have to type binary. We use EF so we can have the possibility of using different providers and to work with object graphs in a nice related way amongst many things. Certain abstractions are useful and some are not.
The repository pattern is an abstraction. It's purpose is to reduce complexity and make the rest of the code persistant ignorant. As a bonus it allows you to write unit tests instead of integration tests.
The problem is that many developers fail to understand the patterns purpose and create repositories which leak persistance specific information up to the caller (typically by exposing IQueryable<T>). By doing so they get no benefit over using the OR/M directly.
Update to address another answer
Coding for the exception
Using repositories is not about being able to switch persistence technology (i.e. changing database or using a webservice etc instead). It's about separating business logic from persistence to reduce complexity and coupling.
Unit tests vs integration tests
You do not write unit tests for repositories. period.
But by introducing repositories (or any other abstraction layer between persistance and business) you are able to write unit tests for the business logic. i.e. you do not have to worry about your tests failing due to an incorrectly configured database.
As for the queries. If you use LINQ you also have to make sure that your queries work, just as you have to do with repositories. and that is done using integration tests.
The difference is that if you have not mixed your business with LINQ statements you can be 100% sure that it's your persistence code that are failing and not something else.
If you analyze your tests you will also see that they are much cleaner if you have not mixed concerns (i.e. LINQ + Business logic)
Repository examples
Most examples are bullshit. that is very true. However, if you google any design pattern you will find a lot of crappy examples. That is no reason to avoid using a pattern.
Building a correct repository implementation is very easy. In fact, you only have to follow a single rule:
Do not add anything into the repository class until the very moment that you need it
A lot of coders are lazy and tries to make a generic repository and use a base class with a lot of methods that they might need. YAGNI. You write the repository class once and keep it as long as the application lives (can be years). Why fuck it up by being lazy. Keep it clean without any base class inheritance. It will make it much easier to read and maintain.
(The above statement is a guideline and not a law. A base class can very well be motivated. Just think before you add it, so that you add it for the right reasons)
Old stuff
Conclusion:
If you don't mind having LINQ statements in your business code nor care about unit tests I see no reason to not use Entity Framework directly.
Update
I've blogged both about the repository pattern and what "abstraction" really means: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
Update 2
For single entity type with 20+ fields, how will you design query method to support any permutation combination? You dont want to limit search only by name, what about searching with navigation properties, list all orders with item with specific price code, 3 level of navigation property search. The whole reason IQueryable was invented was to be able to compose any combination of search against database. Everything looks great in theory, but user's need wins above theory.
Again: An entity with 20+ fields is incorrectly modeled. It's a GOD entity. Break it down.
I'm not arguing that IQueryable wasn't made for quering. I'm saying that it's not right for an abstraction layer like Repository pattern since it's leaky. There is no 100% complete LINQ To Sql provider (like EF).
They all have implementation specific things like how to use eager/lazy loading or how to do SQL "IN" statements. Exposing IQueryable in the repository forces the user to know all those things. Thus the whole attempt to abstract away the data source is a complete failure. You just add complexity without getting any benefit over using the OR/M directly.
Either implement Repository pattern correctly or just don't use it at all.
(If you really want to handle big entities you can combine the Repository pattern with the Specification pattern. That gives you a complete abstraction which also is testable.)
IMO both the Repository abstraction and the UnitOfWork abstraction have a very valuable place in any meaningful development. People will argue about implementation details, but just as there are many ways to skin a cat, there are many ways to implement an abstraction.
Your question is specifically to use or not to use and why.
As you have no doubt realised you already have both these patterns built into Entity Framework, DbContext is the UnitOfWork and DbSet is the Repository. You don’t generally need to unit test the UnitOfWork or Repository themselves as they are simply facilitating between your classes and the underlying data access implementations. What you will find yourself needing to do, again and again, is mock these two abstractions when unit testing the logic of your services.
You can mock, fake or whatever with external libraries adding layers of code dependencies (that you don’t control) between the logic doing the testing and the logic being tested.
So a minor point is that having your own abstraction for UnitOfWork and Repository gives you maximum control and flexibility when mocking your unit tests.
All very well, but for me, the real power of these abstractions is they provide a simple way to apply Aspect Oriented Programming techniques and adhere to the SOLID principles.
So you have your IRepository:
public interface IRepository<T>
where T : class
{
T Add(T entity);
void Delete(T entity);
IQueryable<T> AsQueryable();
}
And its implementation:
public class Repository<T> : IRepository<T>
where T : class
{
private readonly IDbSet<T> _dbSet;
public Repository(PPContext context)
{
_dbSet = context.Set<T>();
}
public T Add(T entity)
{
return _dbSet.Add(entity);
}
public void Delete(T entity)
{
_dbSet.Remove(entity);
}
public IQueryable<T> AsQueryable()
{
return _dbSet.AsQueryable();
}
}
Nothing out of the ordinary so far but now we want to add some logging - easy with a logging Decorator.
public class RepositoryLoggerDecorator<T> : IRepository<T>
where T : class
{
Logger logger = LogManager.GetCurrentClassLogger();
private readonly IRepository<T> _decorated;
public RepositoryLoggerDecorator(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Add(T entity)
{
logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString() );
T added = _decorated.Add(entity);
logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
return added;
}
public void Delete(T entity)
{
logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
_decorated.Delete(entity);
logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
}
public IQueryable<T> AsQueryable()
{
return _decorated.AsQueryable();
}
}
All done and with no change to our existing code. There are numerous other cross cutting concerns we can add, such as exception handling, data caching, data validation or whatever and throughout our design and build process the most valuable thing we have that enables us to add simple features without changing any of our existing code is our IRepository abstraction.
Now, many times I have seen this question on StackOverflow – “how do you make Entity Framework work in a multi tenant environment?”.
https://stackoverflow.com/search?q=%5Bentity-framework%5D+multi+tenant
If you have a Repository abstraction then the answer is “it’s easy add a decorator”
public class RepositoryTennantFilterDecorator<T> : IRepository<T>
where T : class
{
//public for Unit Test example
public readonly IRepository<T> _decorated;
public RepositoryTennantFilterDecorator(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Add(T entity)
{
return _decorated.Add(entity);
}
public void Delete(T entity)
{
_decorated.Delete(entity);
}
public IQueryable<T> AsQueryable()
{
return _decorated.AsQueryable().Where(o => true);
}
}
IMO you should always place a simple abstraction over any 3rd party component that will be referenced in more than a handful of places. From this perspective an ORM is the perfect candidate as it is referenced in so much of our code.
The answer that normally comes to mind when someone says “why should I have an abstraction (e.g. Repository) over this or that 3rd party library” is “why wouldn’t you?”
P.S. Decorators are extremely simple to apply using an IoC Container, such as SimpleInjector.
[TestFixture]
public class IRepositoryTesting
{
[Test]
public void IRepository_ContainerRegisteredWithTwoDecorators_ReturnsDecoratedRepository()
{
Container container = new Container();
container.RegisterLifetimeScope<PPContext>();
container.RegisterOpenGeneric(
typeof(IRepository<>),
typeof(Repository<>));
container.RegisterDecorator(
typeof(IRepository<>),
typeof(RepositoryLoggerDecorator<>));
container.RegisterDecorator(
typeof(IRepository<>),
typeof(RepositoryTennantFilterDecorator<>));
container.Verify();
using (container.BeginLifetimeScope())
{
var result = container.GetInstance<IRepository<Image>>();
Assert.That(
result,
Is.InstanceOf(typeof(RepositoryTennantFilterDecorator<Image>)));
Assert.That(
(result as RepositoryTennantFilterDecorator<Image>)._decorated,
Is.InstanceOf(typeof(RepositoryLoggerDecorator<Image>)));
}
}
}
First of all, as suggested by some answer, EF itself is a repository pattern, there is no need to create further abstraction just to name it as repository.
Mockable Repository for Unit Tests, do we really need it?
We let EF communicate to test DB in unit tests to test our business logic straight against SQL test DB. I don't see any benefit of having mock of any repository pattern at all. What is really wrong doing unit tests against test database? As it is bulk operations are not possible and we end up writing raw SQL. SQLite in memory is perfect candidate for doing unit tests against real database.
Unnecessary Abstraction
Do you want to create repository just so that in future you can easily replace EF with NHbibernate etc or anything else? Sounds great plan, but is it really cost effective?
Linq kills unit tests?
I will like to see any examples on how it can kill.
Dependency Injection, IoC
Wow these are great words, sure they look great in theory, but sometimes you have to choose trade off between great design and great solution. We did use all of that, and we ended up throwing all at trash and choosing different approach. Size vs Speed (Size of code and Speed of development) matters huge in real life. Users need flexibility, they don't care if your code is great in design in terms of DI or IoC.
Unless you are building Visual Studio
All these great design are needed if you are building a complex program like Visual Studio or Eclipse which will be developed by many people and it needs to be highly customizable. All great development pattern came into picture after years of development these IDEs has gone through, and they have evolved at place where all these great design patterns matter so much. But if you are doing simple web based payroll, or simple business app, it is better that you evolve in your development with time, instead of spending time to build it for million users where it will be only deployed for 100s of users.
Repository as Filtered View - ISecureRepository
On other side, repository should be a filtered view of EF which guards access to data by applying necessary filler based on current user/role.
But doing so complicates repository even more as it ends up in huge code base to maintain. People end up creating different repositories for different user types or combination of entity types. Not only this, we also end up with lots of DTOs.
Following answer is an example implementation of Filtered Repository without creating whole set of classes and methods. It may not answer question directly but it can be useful in deriving one.
Disclaimer: I am author of Entity REST SDK.
http://entityrestsdk.codeplex.com
Keeping above in mind, we developed a SDK which creates repository of filtered view based on SecurityContext which holds filters for CRUD operations. And only two kinds of rules simplify any complex operations. First is access to entity, and other is Read/Write rule for property.
The advantage is, that you do not rewrite business logic or repositories for different user types, you just simply block or grant them the access.
public class DefaultSecurityContext : BaseSecurityContext {
public static DefaultSecurityContext Instance = new DefaultSecurityContext();
// UserID for currently logged in User
public static long UserID{
get{
return long.Parse( HttpContext.Current.User.Identity.Name );
}
}
public DefaultSecurityContext(){
}
protected override void OnCreate(){
// User can access his own Account only
var acc = CreateRules<Account>();
acc.SetRead( y => x=> x.AccountID == UserID ) ;
acc.SetWrite( y => x=> x.AccountID == UserID );
// User can only modify AccountName and EmailAddress fields
acc.SetProperties( SecurityRules.ReadWrite,
x => x.AccountName,
x => x.EmailAddress);
// User can read AccountType field
acc.SetProperties<Account>( SecurityRules.Read,
x => x.AccountType);
// User can access his own Orders only
var order = CreateRules<Order>();
order.SetRead( y => x => x.CustomerID == UserID );
// User can modify Order only if OrderStatus is not complete
order.SetWrite( y => x => x.CustomerID == UserID
&& x.OrderStatus != "Complete" );
// User can only modify OrderNotes and OrderStatus
order.SetProperties( SecurityRules.ReadWrite,
x => x.OrderNotes,
x => x.OrderStatus );
// User can not delete orders
order.SetDelete(order.NotSupportedRule);
}
}
These LINQ Rules are evaluated against Database in SaveChanges method for every operation, and these Rules act as Firewall in front of Database.
There is a lot of debate over which method is correct, so I look at it as both are acceptable so I use ever which one I like the most (Which is no repository, UoW).
In EF UoW is implemented via DbContext and the DbSets are repositories.
As for how to work with the data layer I just directly work on the DbContext object, for complex queries I will make extension methods for the query that can be reused.
I believe Ayende also has some posts about how abstracting out CUD operations is bad.
I always make an interface and have my context inherit from it so I can use an IoC container for DI.
What most apply over EF is not a Repository Pattern. It is a Facade pattern (abstracting the calls to EF methods into simpler, easier to use versions).
EF is the one applying the Repository Pattern (and the Unit of Work pattern as well). That is, EF is the one abstracting the data access layer so that the user has no idea they are dealing with SQLServer.
And at that, most "repositories" over EF are not even good Facades as they merely map, quite straightforwardly, to single methods in EF, even to the point of having the same signatures.
The two reasons, then, for applying this so-called "Repository" pattern over EF is to allow easier testing and to establish a subset of "canned" calls to it. Not bad in themselves, but clearly not a Repository.
Linq is a nowadays 'Repository'.
ISession+Linq already is the repository, and you need neither GetXByY methods nor QueryData(Query q) generalization. Being a little paranoid to DAL usage, I still prefer repository interface. (From maintainability point of view we also still have to have some facade over specific data access interfaces).
Here is repository we use - it de-couples us from direct usage of nhibernate, but provides linq interface (as ISession access in exceptional cases, which are subject to refactor eventually).
class Repo
{
ISession _session; //via ioc
IQueryable<T> Query()
{
return _session.Query<T>();
}
}
The Repository (or however one chooses to call it) at this time for me is mostly about abstracting away the persistence layer.
I use it coupled with query objects so I do not have a coupling to any particular technology in my applications. And also it eases testing a lot.
So, I tend to have
public interface IRepository : IDisposable
{
void Save<TEntity>(TEntity entity);
void SaveList<TEntity>(IEnumerable<TEntity> entities);
void Delete<TEntity>(TEntity entity);
void DeleteList<TEntity>(IEnumerable<TEntity> entities);
IList<TEntity> GetAll<TEntity>() where TEntity : class;
int GetCount<TEntity>() where TEntity : class;
void StartConversation();
void EndConversation();
//if query objects can be self sustaining (i.e. not need additional configuration - think session), there is no need to include this method in the repository.
TResult ExecuteQuery<TResult>(IQueryObject<TResult> query);
}
Possibly add async methods with callbacks as delegates.
The repo is easy to implement generically, so I am able not to touch a line of the implementation from app to app. Well, this is true at least when using NH, I did it also with EF, but made me hate EF. 4. The conversation is the start of a transaction. Very cool if a few classes share the repository instance. Also, for NH, one repo in my implementation equals one session which is opened at the first request.
Then the Query Objects
public interface IQueryObject<TResult>
{
/// <summary>Provides configuration options.</summary>
/// <remarks>
/// If the query object is used through a repository this method might or might not be called depending on the particular implementation of a repository.
/// If not used through a repository, it can be useful as a configuration option.
/// </remarks>
void Configure(object parameter);
/// <summary>Implementation of the query.</summary>
TResult GetResult();
}
For the configure I use in NH only to pass in the ISession. In EF makes no sense more or less.
An example query would be.. (NH)
public class GetAll<TEntity> : AbstractQueryObject<IList<TEntity>>
where TEntity : class
{
public override IList<TEntity> GetResult()
{
return this.Session.CreateCriteria<TEntity>().List<TEntity>();
}
}
To do an EF query you would have to have the context in the Abstract base, not the session. But of course the ifc would be the same.
In this way the queries are themselves encapsulated, and easily testable. Best of all, my code relies only on interfaces. Everything is very clean. Domain (business) objects are just that, e.g. there is no mixing of responsibilities like when using the active record pattern which is hardly testable and mixes data access (query) code in the domain object and in doing so is mixing concerns (object which fetches itself??). Everybody is still free to create POCOs for data transfer.
All in all, much code reuse and simplicity is provided with this approach at the loss of not anything I can imagine. Any ideas?
And thanks a lot to Ayende for his great posts and continued dedication. Its his ideas here (query object), not mine.
For me, it's a simple decision, with relatively few factors. The factors are:
Repositories are for domain classes.
In some of my apps, domain classes are the same as my persistence (DAL) classes, in others they are not.
When they are the same, EF is providing me with Repositories already.
EF provides lazy loading and IQueryable. I like these.
Abstracting/'facading'/re-implementing repository over EF usually means loss of lazy and IQueryable
So, if my app can't justify #2, separate domain and data models, then I usually won't bother with #5.
I'm very familiar with UoW, Repository Pattern, etc. but in seeing various implementations of the pattern for Entity Framework, I'm curious why anyone would have a Save or Add method on their repository. If you use the repository to get you a new instance of an object that I would imagine someone would already
public Customer GetNewCustomer()
{
Customer customer = new Customer();
... any initialization code here ...
_context.Customers.AddObject(customer);
return customer;
}
I know in some designs, you can simply use
Customer customer = new Customer();
and its not attached anywhere to the context. However I'm a fan of private constructors so there is a single point of instantiation for a Customer object. With that in mind wouldn't it makes sense to never have an add/save method on the repository when using a UoW pattern and only have this functionality on the IUnitOfWork interface?
When I follow the Spring idiom in Java, units of work (and transactions) are associated with services. They use model and persistence objects to fulfill a request. Transactions are demarked using aspects.
I don't know whether .NET follows a similar idea, but it'd be worth exploring. Have interface-based POCO services and let them own transactions.
I don't think that your solution is correct. That will add empty customer to current unit of work. That means that later code will have a hard time if it decide not to save customer by the current unit of work.
It is quite common that repository have method to save entity. You are combining two patterns used in Domain driven design
Repository
Object factory
Repository's responsibility is to retrieve or store entities. Object factory's responsibility is to handle entity construction.
Btw. private constructor of your entity will not be accessible in your repository if repository is not the entity (which would be quite bad).
...wouldn't it makes sense to never have an add/save method on the
repository when using a UoW pattern and only have this functionality
on the IUnitOfWork interface?
Yes I think it makes sense to only have the Save method on the IUnitOfWork interface. However, I no longer use the repository pattern with EF. Instead, I now use these variations of the command & query patterns.
If you think about it, the EF DbContext is really doing 3 things: 1.) it functions as your repository for reading entity state, 2.) as your repository for mutating entity state, and 3.) as a UnitOfWork for tracking multiple changes and combining them into a single transaction to persist state mutations.
So, why not separate these 3 responsibilities into 3 different interfaces?
public interface IUnitOfWork
{
int SaveChanges();
}
public interface ICommandEntities : IQueryEntities
{
void Create(Entity entity);
void Update(Entity entity);
void Purge(Entity entity);
}
public interface IQueryEntities
{
IQueryable<AggregateRoot1> AggregateRoot1s { get; }
IQueryable<AggregateRoot2> AggregateRoot2s { get; }
IQUeryable<AggregateRootN> AggregateRootNs { get; }
IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query,
Expression<Func<TEntity, object>> expression)
where TEntity : Entity;
}
You can then implement these 3 interfaces on your DbContext class. This keeps the interfaces nice and segregated, and lets you dependency inject only those methods of the DbContext which you need.
For example, your domain should be persistence ignorant, right? In that case, don't give any of your domain classes dependencies on the IUnitOfWork interface. Instead, handle the IUnitOfWork in your IoC composition root (or in an MVC action filter). Then, your query and command handlers deal only with the ICommandEntities and IQueryEntities interfaces.
I'm having a difficult time finding straight forward examples of using EF in a DDD style pattern. This is also my first time employing DDD and have a few questions regarding solution layout and how to employ some of the DDD patterns.
1) Most of the examples I've seen regarding using the Repository pattern w/ EF just show specialized Model interfaces such as IContactRepository and then a concrete type implementing the interface. Ideally, I'd love to use something like IRepository that has a basic set of functionality for CRUD ops. I could then create specialized repositories if if necessary such as IContactRepository : IRepository when necesary as most of my models won't need to be extended. Am I barking up the wrong tree? Can someone provide me w/ examples of this style of implementation?
2) Right now I have my solutio broken up into the following three projects: Models (contains my EDM), Repositories, and Services. Is this fitting or is there another layout approach I'm not considering and should be?
3) I've seen examples of repositories having a Query(Func<T>)/Query() methods that return IQueryable. Is this smelly or something frowned upon?
I'd like to answer #3...
I think it's less "smelly" and more "lazy". Here's a typical "repository" that I've been seeing around the internets...
public interface IRepository {
// Query operations.
IQueryable<T> All<T>();
IQueryable<T> Find<T>(Expression<Func<T, bool>> expression);
T Single<T>(Expression<Func<T, bool>> expression);
// Save operations.
T Add<T>(T objectToAdd);
void Delete<T>(T objectToDelete);
T Update<T>(T objectToUpdate);
}
As far as I'm aware, this is less a repository and more a "session" or "unit of work". It's a handy way to abstract away whatever database technology you're using and just talk to an extremely generic interface instead. So let's rename it to an ISession, instead. This is the pattern I've been doing recently.
public class PeopleRepository {
private readonly ISession session;
public PeopleRepository(ISession session) {
this.session = session;
}
public virtual IEnumerable<Person> Active() {
return session.Find<Person>(p => p.Active).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
}
public virtual IEnumerable<Person> ByLastName(string name) {
return session.Find<Person>(p => p.Active && p.LastName.StartsWith(lastName)).OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
}
public virtual void DeletePerson(int personId) {
// We don't really delete people; we mark them as inactive.
var person = session.Single<Person>(p => p.Id == personId);
person.Active = false;
session.Update(person);
}
}
In this setup, the ISession is a generic link to the data store. The PersonRepository, however, is very specific to the types of queries and actions that are taken on a Person object.
Hope this helps.
We are currently using EF with DDD, but I would have to say that in its current implementation, EF isn't very suitable to this kind of architecture. The main problem is that the only way EF currently works is by having each 'Entity' derive from an EF-specific base class.
On the other hand, the whole point about Repositories is to abstract away the data access technology. The whole idea behind DDD is that the Domain Model should be unconstraind by implementation details such as the choice of data access technology. This means that domain objects should be defined so that they are Persistence-Ignorant.
In other words: You can't use the EF 'Entities' as domain objects, so in your DAL, you must manually write a lot of code that maps to and from the domain objects to the EF 'Entities'. That gets tired really fast.
I would definitely consider having IQueryable on a Repository to be a leaky abstraction, and it doesn't make a lot of sense in DDD parlance. If domain objects are cohesive units, it doesn't make a whole lot of sense selecting only certain 'columns' from them.
In EF for .NET 4.0 we will get Persistence Ignorance, so it should become better in the future...
Here is a sample:
http://dataguidance.codeplex.com/