Having decided that the Repository/Unit of Work pattern does not add anything to Entity Framework (EF) the question was how to tame EF to work with Domain-Driven Design principals. This post details my new approach to using EF and why it is better.
This is a series:
- Part 1: Analysing whether Repository pattern useful with Entity Framework
- Part 2: Four months on – my solution to replacing the Repository pattern (this article).
- UPDATE (2018): Big re-write to take into account Entity Framework Core, and further learning.
Four months ago I was reviewing the design of Spatial Modeller™ , version one and I come across people who said that the Repository/Unit of Work pattern was not useful with Microsoft’s main data access technology, Entity Framework (shortened to EF from now on).
See items marked with ‘UPDATED 2015‘ for new comments added eight month on from first article.
And ‘UPDATED 2017′ for new comments added from my book Entity Framework Core in Action, which I am writing for Manning Publishing.
At that time I wrote a the blog post called ‘Is the Repository pattern useful with Entity Framework? – part 1‘ where I looked critically about what people said. At the time I was fairly convinced, but I needed to write some real code to see how I would do things without a repository.
Well, four months on the answer is – I’m convinced. The Repository/Unit or Work pattern does NOT add anything to EF. In fact it hides some useful features that a repository has trouble using. (UPDATE 2015: eight months on I am even more convinced as I have now built some more representative applications).
However the issue is – what replaces the good bits of the repository, like handling Domain-Driven Design (DDD) which tries to treat the data persistence library as a simple in-memory collection. This means we want to hide some of EFs code, but still be able to use all of its features. It has taken me a little while to refine my approach, but here are my thoughts so far.
One size does not fit all
- The User Interface (UI) which needs to display data in lots of different ways and often needs help when editing data, i.e. it might have to provide the user with a list of options using a dropdown list.
- The WebApi or Web Service, which is similar to the User Interface but has less need for user selection from a list.
- The Business Layer which needs to hide some of the EF code and make the database feel like a searchable collection.
Design 1: CRUD data access for User Interface layer and WebApi
The front-end of any application needs to do CRUD operations: that is Create, Read, Update and Delete of entries. Create and Update can be particularly difficult as it might need other data to guide the user. For instance on my example site the create/update of a Post needs the user to select the right Tags and, in my example, the Author (try http://samplemvcwebapp.net/Posts and then edit an entry). That needs extra data, which is where Data Transfer Objects (DTOs) come in.
I am a strong proponent of DTOs I have used them heavily and I find they really help decouple the data and business layer from the UI or WebApi. DTOs are also good at dealing with the issue of Aggregates, that is a class that has subclasses under it. For instance you might have a class called Order, which has collection of LineItems under it, and most likely a link to a Customer. DTOs can extract all the various parts and either ‘flatten’ them into one class, or for collections extract only the parts of the data that the user wants/is allowed to see.
The important point is to design the transfer for reads from the database so that they turn into efficient SQL requests. This needs a bit of thought, but isn’t that hard to do. By using LINQ and IQueryable<T> requests then this allows paging and filtering to be added at the last minute in the UI/WebApi end. Also adding the .Select function allows only the columns/properties you need to be read in. The benefit of all this is that the SQL request only asks for those rows and properties that the request needs, which makes the request as efficient as possible.
So an approach that uses DTO is good. The only down side is that writing the data access code for DTOs is repetitive and boring. I therefore looked at how to automate this. As I said in part 1 of this post I thought I might use T4 code generation. However in the end I pursued a route using .NET Generics. The result is an Open Source library called GenericServices which provides List, Detail, Create, Update and Delete functions on either the EF data classes themselves or more interestingly via DTOs linked to EF data classes.
Design 1: Implementation (UPDATED 2015)
Rather than describe how this all works here I have build two example web sites.
1. SampleMvcWebApp.net, which is simple application to show GenericServices in action.
2. (UPDATE 2015) Complex.SampleMvcWebApp, which is a much more realistic example of a real application. The interesting thing for me is that it only took me two weeks to write the whole application (well, plus a few days for adding supporting comments and a few tweaks to improve it). That is way faster than my previous applications and proved to me the power of GenericServices.
I have written two articles that describe the design of the Complex.SampleMvcWebApp site. They are:
- Part 1: Using Entity Framework with an Existing Database: Data Access describes handling existing SQL databases using Entity Framework.
- Part 2: Using Entity Framework with an Existing Database: User Interface describes the overall architecture of the system.
(UPDATE 2015) The GenericServices Wiki now contains lots of information and GenericService is now available on Nuget – see GenericServices on NuGet. This means you can try GenericServices yourself.
Design 2: The Business Layer (UPDATED 2015)
UPDATE: I now have a improved approach to handling business logic which you can find in the article Architecture of Business Layer working with Entity Framework (Core and v6) – revisited and in Chapter 4 of the book I am writing for Manning Publishing, Entity Framework Core in Action.
For the business layer I have taken a different approach. From a design/architecture point of view I do three things.
- I allow the business layer to directly access the data via Entity Framework (EF). No repository, not unit of work, just good old EF. This means that I have access to all of EFs commands and nothing is hidden from me.
- Problem is that EF on its own can be a bit of a handful so I tame it with ‘Query Objects’. Mainly I want to make repetitive, or complicated EF code appear as simple methods with intention revealing names. See implementation section for an example of this.
- In the business layer I try to treat the database as an in-memory collection which some search procedures, i.e. Query Objects. I try to not use the data access methods other than for loading or inserting new entries. Any other commands are hidden in Query Objects or other methods.
Let me explain how this works by talking about the implementation.
Design 2: Implementation
So the implementation of using EF in the business layers consists of four parts:
1. Building ‘Query Objects’ to hide some of the complex filtering/loading
UPDATE 2017: In chapter 2 of the book Entity Framework Core in Action I describe building a book listing with sorting, filtering and paging using a series query objects. You can see a live example site showing you those query objects in action.
In the first post I mentioned that people were taking about Query Objects, which is an encapsulation of particular database queries or updates. In C# Extension methods are a great tool for building Query Objects. If you have seen LINQ fluent commands then that is how extension methods work. Below is an example from Spatial Modeller™ where it loads all the schemes who’s key is in the array parameter, with the schemes layers, members, attributes and services.
public static IQueryable<SmScheme> GetSchemesByIdIncludingAllChildClasses ( this SpatialModellerDb db, ICollection<int> schemeIdsToLoad) { return db.SmSchemes .Include(x => x.Grades) .Include( x => x.Layers.Select(y => y.Members .Select(z => z.Attributes))) .Include( x => x.Layers.Select(y => y.Members .Select(z => z.ServicesHandled))) .Where( x => schemeIdsToLoad.Contains(x.SmSchemeId)); }
This code hides the EF code needed to perform the database action inside a nicely named method. This code would be in the data/infrastructure layer, which means the EF code is more centralised in one place. I would recommend Edward Charbeneau‘s article ‘Giving Clarity to LINQ Queries by Extending Expressions‘ which has some excellent ideas and source code for building ‘query objects’.
2. Using Domain-Driven Design (DDD) principals
I really like the thinking behind DDD. It has made me a better programmer. While DDD accepts that the way data is stored/persisted will have an affect on the design (see Eric Evans book, page 159) the aim is to allow Business Layer code treat the database as an in-memory collection which some search procedures, with as little interaction as possible with the data access code.
This isn’t done just to hide the database, but mainly to ensure that the developers working in the business layer are thinking about the business problem first, not how the database works. DDD recognises that there might need to be some implementation compromises to work with the database, but the overall aim is to keep the focus on the business problems.
The other issue that effects the approach used is that the actual data saved in the database will be designed for the business layer. Therefore the business layer will use the data classes directly, as they are a good fit to the business problem.
Update after a lot more business layer work
I still use a DDD approach, but I have found that EF doesn’t really support a pure DDD design for a number of reasons. Firstly the EF database classes need to be at the data layer level, so these classes aren’t really the right place to have business logic (I have a separate layer/assembly for that). Also EF sets certain restrictions on the way collections are handled, which means you can’t use a IReadonlyCollection, which can make building a DDD root/aggregates approach where the sub classes of a DDD root can only be changed via the root hard to enforce. Because of this I still follow a DDD design approach, but some of the more stringent access rules have to be implemented simply by setting standards, not by programatically enforces rules.
Even so my business layer is able use the DDD principal of treating the database as just classes, which make the business logic much simpler. To do this a typical business pattern has three phases:
- Read in any data it needs for the business logic.
- Some pure business logic working on the data classes – the bulk of the code.
- An optional add/remove phase if any new data needs to be added to the database (note: updates happen automatically if you just change the database classes read in in phase 1).
3. The Business Layer never calls EF’s .SaveChanges() to persist data
The business layer should not know about persisting/updating data. I therefore design the business layer call .add() or .remove() on the EF collections, but the final update is triggered by the Service Layer after the business process returns.
This sounds subtle, but it has proved to be really useful. I go into this in more detail in my new article Architecture of Business Layer working with Entity Framework but here are three good reasons why it helps.
- The single big commit meant that the modelled data was either there or not – no cleaning up if the business layer had done part of the job and committed it but a later part failed.
- The Business Layer does not have to handle database validation errors, which can occur when ‘SaveChanges’ is called. The Service Layer does that, which is better placed to deal with any errors.
- The business layer was easier to test as it added data to the EF collections, but didn’t change the database.
Conclusion (UPDATED 2015)
Doing all this is hard work, especially building the GenericServices library, but I really do think this will speed up future development. I built the SampleMvcWebApp fairly quickly, but that was because I was developing GenericServices.
However when I built Complex.SampleMvcWebApp, which is much more representative application, it only took two weeks, which I though was fantastic. Have a look at the site – it’s fairly complex in terms of data manipulation even if I didn’t spend time on the visual design. NOTE: I have not implemented any business logic at all in the sample. If I had it would have taken a lot longer because business logic is by its very nature specific to a project.
The things I immediately noticed when swapping to the new approach are:
- The separation of concerns is much better, with the EF code more focused to where it is needed.
- Creating a good repository pattern is hard and I used to find myself fiddling with the repository implementation during the project as I hit new issues. That is all gone.
- Using EF directly allows me to use the full range of commands, like load to load relationships that are not currently loaded. I now realise when I used a repository pattern I was having to tweak the code to get round things that EF had commands to solve.
The primary helper is GenericService, which as of 2015 is now released on Nuget – see GenericServices on NuGet. Without GenericService it would be a hard slog to build the Service Layer. What I noticed GenericServices did was:
- Writing the DTOs is all about getting the right names/properties. Everything else is handled by GenericServices. So much quicker to write and more robust.
- If there was a special case then it was easy to override one of GenericServiceDTOs virtual methods. As part of the exercise of building Complex.SampleMvcWebApp I made the method names more obvious to stop me having to look them up every time.
- The MVC Controller code is now the same for all but the most complex situation, with just the data classes changing. This makes writing the MVC side much easier, and less error prone. I plan to create some scaffolding but currently waiting for MVC 6 (vNext) which has new scaffolding options.
I have also written a private library called GenericActions to help with calling business methods, but that is a subject of another article.
I hope that is helpful to people. Happy coding!
Great Article… I love DTOs as well. What I do is create a T4 Template that uses reflection to scour my EF entity classes and get only the properties I care about (scalar data properties) and leave out the properties that aren’t needed (navigational properties). The template generates all DTOs for my entities with the same classname just “DTO” appended to the end. I then implement Automapper for my DTO mapping from entities. I created one more t4 template to generate the Automapper config class in App Start to scour my entities (again using reflection) and generate the mapping for each entity / dto relationship. Then create an interface to perform crud operations and retrieve data. All methods take a dto or scalar property as a parameter and all methods are either void or return a scalar value or a dto class. This has been working very well for me… Also injecting these “services” I’m calling them into controller via Ninject. Our shop hasn’t adopted .net core yet but I can’t wait to use that and ditch NInject for a di container as well. Cheers
You T4 template sounds good. I tend to hand-build DTOs by copy/paste of the properties I need. The less properties I load the quicker its going to be. AutoMapper ProjectTo produces LINQ that EF Core can turn into an efficient SELECT command.
I used to use AutoFac, but the EF Core DI is really fast – have a look at my article https://www.thereformedprogrammer.net/asp-net-core-fast-and-automatic-dependency-injection-setup/
I totally agree and have been using Stephen van Deursen/Jimmy Bogard’s ideas around Queries/Commands and mediator pipelines for a while now. I’m still confused as to why every Pluralsight course has repositories in it??? It’s so 2012.
It was a bit hard to get a feel for what your GenericServices package does. I use Automapper to create DTOs from domain models and have found that to be a priceless tool. Anyhow, glad to have found another Repository naysayer out there 🙂
Hi Dave,
Yep, I think putting a repository on top of EF just doesn’t make sense for CRUD accesses. While writing the book on EF Core I covered Domain-Driven Design (DDD) in chapter 10 and built a repository, because that’s what the original DDD book by Eric Evans recommends. My analysis was the repository constrained queries and could cause issues on performance for updates.
I do use repositories in very specific areas around business logic – see my article Architecture of Business Layer working with Entity Framework (Core and v6) – revisited, but no where else.
AutoMapper is great – and its now a lot faster on setup from when I wrote GenericServices. GenericServices is like a EF focused version of Jimmy Bogards mediator. I build GenericServices in 2014 and and have used it time and time again on projects. I’m planning a rewrite for EF Core, but after I have finished the book (working on the last chapter now!)
Thanks for the link to your article. Will have a read. Good to hear GenericServices is serving you well. I might take a look at it if I can find the time. Cheers!
Hi Jon
Thanks for your thorough coverage of an important subject. I Still use the repository pattern for a number of reason. Some of them you touch upon, and you even mentions the DDD side of it.
I Use only use a repository implementation in Write scenarios.
Often I can just get aggregate root by Id,
I Sometimes use query specifications So I don’t need to write specific implementation for my repositories.
Repository pattern and also EF tends to break down if its used to perform complex queries involving alot of joins.
For Dedicated queries I sometimes replace EF with Dapper.
In pure read scenarios I tend to use dedicated queries, often passing in a specification like query specification. Often Queries are projections of you business entities.
I definitly se advantages in having a clear speration of REad and Write models. DDD is focused on the Write scenarios, updating aggregates and controlling invariants.
I Like a domain model that has no reference to database assemblies at all.
From a Test first perspective. Not having to setup a database even if its sql lite eases testing alot.
Often DDD Practitioners recommend using domain specific naming for your queries. Here An abstraction on top of EF makes that possible.
I haven’t used EF core alot yet, so i still have to see what changes it has brought. I Know I can mock my Repositories, and that makes setting a test context up easier for me.
Hi Christian,
I can see from your comments that you are a expert practitioner of DDD. I agree with all you comments. Eric Evans original DDD book talked about repositories, but a few of us, including Jimmy Borgart, think Eric was using that turn in a general way – as you say DDD is focused on the write model, and reads are different.
Your comment “I Like a domain model that has no reference to database assemblies at all” is one I have heard before. There are various opinions on this – I recently recorded a PodCast with Bryan Hogan and he goes much further than I do. I only handle CRUD in the entity class but he puts full-blown business logic in the EF entity classes. I have started writing an article to compare the different approaches – I think they are all valid, but have different tradeoffs. It will be interested to write as I feel I still have a lot to learn about DDD.
I have been using EF Core for over two years, most of that while writing my book, and I think EF Core is a very good improvement over EF6 – its so clean. In case you haven’t see it EF Core allows you to “lock down” your collection relationships, which you couldn’t do in EF6 – see https://blog.oneunicorn.com/2016/10/28/collection-navigation-properties-and-fields-in-ef-core-1-1/
Yes I also put the domain logic in the EF domain entities. I do consider to move the persistent state to a dedicated EF entity, an let repository Map between EF entity and Domain entity.
Hi Jon, First, thanks for the article and the great job done with generic services. I was looking for alternatives to the use of the repository pattern and I find out your articles and generic services, and I’m want to know if it works with EF Core and ASP.NET Core, or if it is plans to port it.
Hi Joalcava,
Good question. I do plan to produce a version of GenericService for EF Core, but it does need quite bit of work. The problem is I am super busy at the moment, as I have been commissioned by Manning publications to write a book on EF Core, called Entity Framework Core in Action, AND I am working a paid contract. So GenericServices.EFCore won’t be around for many months ( > 6 months based on my current workload).
PS. Manning do an early release of the book and the first three chapters should be going out in the next week or so. You do need to pay to access the book electronically, but you do get the new chapters as I write them – about one a month. I’ll add a link once its out.
First, thanks for the article.
I have a doubt, when you use EF in the business layer, I guess that if in the future you want to use another way to interact with the database, I have to modify the business layer.
For example, if I want to use EF7 instead of EF6, I have to modify the code in the business layer to work with EF7. So if I want to have the two versions, one using EF6 and other using EF7, I have to have two business layers, one that uses EF6 and other that uses EF7, is this right?
However for me it is not a big problem because the logic can be refactored in methods and each version of the business layer use this methods, so all the code is the same in both business layers and I only have to change how to get and save the data from database.
Is this correct?
Hi Alvaro,
Someone else asked a question about this (see https://thereformedprogrammer.net/architecture-of-business-layer-working-with-entity-framework/#comment-2476415735) and my answer was a bit pragmatic.
Read the link for the full details, but I try to ‘localise’ my access to EF within the business logic. In the business code I use a Domain Driven Design approach, i.e. the data is preloaded and the business logic uses the data an in-memory set of classes. An outside library that I have developed, similar to GenericServices but for the Business Layer, looks after saving/updating the database. In 90% of the cases the business logic doesn’t know anything about the database (the exception is adding a new class/row, which I try to segregate). This means that changing the EF part of the code is normally very separate to the business logic.
As Veillet Alexandre points out my approach isn’t totally clean. I am still formulating the best way to structure/isolate the database while still allowing a fast development style.
I hope that helps you in your thinking. If you come up with a better answer then let us all know.
Thank you for this article also Jon. I’m just getting started writing my first “complex” EF based project (I’ve done simple MVC/EF tightly coupled apps before but this time they’ll be an MVC app and also a Windows Service which needs to access the EF objects), I’ve spent today going around in circles reading article upon article about implementing repositories in EF while at the same time thinking to myself “Hmm but doesn’t this just put an abstraction over an abstraction, so why do it?!” before finally arriving at this and the other articles you mentioned in the first article and realising that my initial hesitation was well founded! So you’ve saved me a great deal of pain down the line!
Hi Andrew,
I’m glad you found this and the other articles useful. A year on from this article (March 2016) I am near the end of a small, but fairly complex e-commerce site using this approach and the “no repository” pattern has proved itself again, especially in the business logic.
Best of luck with you new project. Maybe you should write up your own experiences of what worked/didn’t work. Be interesting to hear.
PS. If you are starting a brand new project then you should keep one eye on EF core (formally known as EF7), as you may want to swap to it later. I recently found a very useful description of the EF core roadmap – see https://github.com/aspnet/EntityFramework/wiki/Roadmap
Good article. I just hate this repository pattern 90% off the code in the repository is just to shuffle data between EF Entity and your domain entity that in 9 out of 10 cases are equal.
Yes, I agree. I remember having to constantly tweak my repository pattern as I found another problem. Now that is a all gone. About the only down side is your design is inextricably linked to EF, but it works for me.
PS. Worth keeping up with where Entity Framework Core (was called EF7) is going as that is the future. Some things aren’t being included in the first release, link virtual for lazy loading. I haven’t found a really great list of what is in/out but have a look at https://www.pluralsight.com/blog/software-development/entity-framework-7-update or https://github.com/aspnet/EntityFramework/wiki/Roadmap .
Hi Jon,
How can we accommodate a business layer with the Generic services ? Do you have any sample where you used business layer with Genericservices.
Thanks Girish
Hi Girish,
GenericServices isn’t designed to work with the business layer – its about linking the database to the presentation layer. You need another approach for presentation to business layer interactions.
I have developed a library called GenericActions that does just that, but it is private. However I have written a few articles on the topic: see Architecture of Business Layer working with Entity Framework and a more complex one about the problem of calling multiple business methods in one HTTP request.
Hi Jon,
Thanks for sharing the article. It seems pretty sound advice all in all.
One thing I’m curious about (and I agree that this is a bit off-topic) is when you’re discussing the MemberLocation class. You say:
“Note that in this simple case you could add a new attribute to the collection, but in more complex cases this might have side effects. A good the developer would need to check if adding to the collection is OK, which takes him away from what he/she is trying to acheive. By providing a clearly named method, AddAttribute, it is obvious that this is the right way to do it.”.
Isn’t having two ways to add an Attribute to a collection confusing? As a client using that class, it would probably appear as though using the AddAttribute method would be the correct way to add it (otherwise, why was it created?), but the developer could perceivably miss(/not notice) that method, and try adding to the collection directly via Add. I wonder if changing the Attributes collection to an IReadonlyCollection could be in order here…? Or perhaps Entity Framework doesn’t like IReadonlyCollections for navigation properties? In which case you could make the Attributes collection private and create another public Attributes property of type IReadonlyCollection that just returns the private ICollection property. My main gripe is the potential ambiguity over the correct way to add a MemberAttribute, but keen to hear what you think.
Hi Nick,
As a result of your comment I reviewed and have rewritten the section on DDD and the business layer!
Since I wrote this article in 2014 I have worked on a fairly complex e-commerce system which had a lot of business logic. This has changed how I approach the business layer/data layer interface. As I now say in the article EF doesn’t lend itself to a pure DDD approach so I had to adapt the way I worked. I now describe the new way I work and I have removed the part you referred to in your comment which I think doesn’t work in practice, which is what you so rightly pointed out.
As you will see in the updated article I still really like the ideas/approach of DDD but I have had to adapt to what works in the real world. I still benefit from the DDD idea of treating the database as a set of in-memory classes, which I believe is a great approach. My business logic is much simpler for it.
A very well written article. I am about to do away with repository pattern, but was just set in my old ways. You taught me a new approach today. Thank you.
Hi JY,
I had the same story. I was used to using the repository pattern and thought the problems I had were normal. Now I have changed I wouldn’t go back, but it did take me a while to develop the standard patterns to work the new way. All the best on your journey.
Hi Jon, thanks for a great post. It sure seems like it’s way more smooth to use the entity framework directly in business logic classes.
One thing I am curious about is: how do you instantiate the context/entities in your business logic classes? I.e., if you have, say, a OrderBusiness class, how exactly do you use the context here? Per method in a using block or do you inject it via the constructor? Injecting it via constructor makes it harder to know when to dispose it, it seems?
Thanks in advance 🙂
Hi uconsult,
It’s a good question, as managing the DbContext is an important issue. I have grappled with that question a lot when building GenericServices CRUD library and the private GenericActions library which all my calls to Business Logic goes through. Here is what I finally decided on:
1. I do inject DbContext through the constructor of the business logic (and GenericServices). I find that works really well.
2. I use use Autofac Dependency Injection to create the DbContext and it has an .InstancePerLifetimeScope() on it, i.e. it lasts throughout a specific period, in my case being a single HTTP request in MVC.
3. I am very careful about who calls .SaveChanges(). That is ONLY called by my libraries, and only when the method they called has said everything is OK.
4. In the rare case where I have a chain of two or more business methods that need to write to the database between each business method is called I use transactions – see reference to an article on that below.
I have produced a couple articles on the Architecture of Business Layer working with Entity Framework. The second article deals with the 4th point and has a long section at the end about handling the DbContext. I give a reference to a very good article by Mehdi El Gueddari called ‘Managing DbContext the right way with Entity Framework 6: an in-depth guide’ that covers the options really well. You might like to read that.
This is a great solution. I do have a silly question. Can we use this DataLayer and Service Layer in a WPF desktop application with unity DI?
Hi Dan222,
There are two things I talk about in this article: a) the overall architecture and b) GenericServices. I assume you are talking about GenericServices so I will direct my comments that way.
I think GenericServices would work with WPF, and it will certainly work with Unity DI. On WPF I’m not an expert, but as I understand it that is about the front-end Pesentation Layer. GenericServices is focused on making the writing of the the Service Layer easier, so if should be fine with WPF.
On Unity DI then GenericServices doesn’t know anything about DI, but is designed to work well in a application that uses DI. My MVC examples use Autofac’s DI to inject the appropriate GenericService into the MVC Presentation Layer. Therefore you can use Unity DI to do the same in your WPF Presentation Layer.
I hope that helps you.
PS. I wrote a longer article around the architecture side for Simple-Talk that you might find useful – see https://www.simple-talk.com/dotnet/asp.net/using-entity-framework-with-an-existing-database–user-interface/
Thanks for quick reply. Yes that is helpful.
Hi Jon,
Great article and great sample implementation. Couple of questions,
1) in complex web app, are lasses such as “Customer (Specifically the attribure TotalAllOrders)” in Data Layer, so called “Query Objects”?
(Forgive me if I understood query objects completely wrong)
2) I am looking at the tests, are these more of integration test? I am sure the service layer can be easily moq(ed) (or MS Fake) to write true unit tests.
Thanks again for writing/developing such a comprehensive app.
Hi Aar_Aar, Good questions. Let me see if I can answer them.
1) Technically properties like TotalAllOrders are not Query Objects, as query objects normally encapsulate a whole query. However in SampleMvcWebAppComplex (SMWAC) I am using GenericServices (see https://github.com/JonPSmith/GenericServices) which does the query. I use properties like ‘TotalAllOrders’ to hide some of the calculations, which is moving towards what a Query Object is doing.
If you read my post on how I build business layers (see https://thereformedprogrammer.net/architecture-of-business-layer-working-with-entity-framework/) then it is inside here that I use Query Objects.
2) You are right about the Unit Tests. Because GenericServices has its own Unit Tests, and SMWAC was a ‘stress test’ if GenericServices if I found a problem I added a test to GenericServices, not SMWAC. The tests that are in SMWAC are just about testing the things that only SMWAC has. I admit that the Unit Tests aren’t as comprehensive as they should be. I normally have a separate database for the unit test, but in this case I was working with an existing database, which meant I was careful what I did to the database.
One further point I would make on Unit Tests. I have found that mocking out Entity Framework (EF) has been a bad idea. Every time I did it I found a nasty bug got me because my mock didn’t mock EF well enough (I can’t wait for EF v7 with in-memory based databases!). Overall I don’t mind this and some (many?) of my Unit Tests are really integration tests as they go all the way down the structure. I tend to number/group my unit tests, with lower numbers being Unit Tests and higher number becoming Integration tests. It works for me, but many would frown in this approach.
Amazing job Jon , i’m starting a new project with SOA orientation, i’m working on the DAL i wanted to use the Repository abstraction in order to suppress the dependency beetwen the diffrent layer of my application.
is there any other way to make this successful without using the repository/unitOfWork patterns?
is there a possibility you could give me access to the code of http://complex.samplemvcwebapp…
thank you
Hi Khalili, Your post seemed to turn up in two places! I answered it below.
This is a really great article. Thanks for sharing. I’ve read all of Conery and Bogard’s stuff and agree with most of it but their examples are always too limited in scope to be useful. The links to your code and examples flesh out a lot of the questions I’m left with after reading their articles. Good Stuff!
Thanks Nathan. Glad you liked the examples. For me an concept/pattern isn’t right until it proves itself in real applications. The initial example was great at getting the idea across, but getting the more complex example going so quickly sealed it for me.
Amazing job Jon , i’m starting a new project with SOA orientation, i’m working on the DAL i wanted to use the Repository abstraction in order to suppress the dependency beetwen the diffrent layer of my application.
is there any other way to make this successful without using the repository/unitOfWork patterns?
is there a possibility you could give me access to the code of http://complex.samplemvcwebapp.net/Orders
thank you
Hi khalili, I understand your desire to separate the layers, but if you are using Entity Framework (and NHibernate I think) there is likely to be some overlap if your use the classes in your DAL. As I explain in this article I use https://github.com/JonPSmith/GenericServices in the Service Layer to (mostly) separate the DAL from the Presentation Layer, or in your case the RESTful API, or whatever you are using at the service end of your SOA.
On the code for http://complex.samplemvcwebapp.net/Orders you find all the code at https://github.com/JonPSmith/SampleMvcWebAppComplex , but be aware that it is NOT an open-source project as it contains some proprietary code of both my own and KendoUi from Telerik. This is there to provide examples of how GenericServices works, but please don’t go copying large chunks of it into your project.
Check out another of my articles https://thereformedprogrammer.net/architecture-of-business-layer-working-with-entity-framework/ for how I handle the Business Layer to Presentation Layer in a similar way to what GenericServices does for DAL to Presentation Layer.
Hi Jon,
Thank you for the quick reponse and for the links , as for the code at you github i will just be reading in order to understand the way you thought about the architecture and i wont be copying anything 🙂
by the way can you give this article http://mehdi.me/ambient-dbcontext-in-ef6/ a minute, as this was the first approach i was goint to use for my new project.
Hi khalil, I read your article on DbContext and its great! I share many of your views but you have taken it further than I have, which is really helpful. There is much there that I would like to think about more. I’ll drop you message via your site as it would be good to keep in touch. Great work.
Hi Jon.
In fact it’s not my article at all 🙂 , i just asked you to take a look on what was said by the writer. As i was interessted in getting the best of what abstraction can give me , i looked over many and many article but realized that the one i sent you is absolutely good.
I’m sorry if there was any misunderstunding, i’m just a junior software engineer and to write such an article will be quite imcomplete at my current experience.
Hi khalil. Oh, sorry. That guys is really good and thanks for pointing him out- great find. He is pretty deep so don’t be put off if you don’t understand it all, but there are gems in there. I use Dependency Injection for DbContext using AutoFac with InstancePerLifetimeScope().
i think using that framework of his for the DAL would be just perfect , but not using GenericRepository at all as it might get leaky, as for the Dependency Injection , i have been reeading a lot of article about ’em and Simple Injector & Unity seems to be the best choice (BENCHMARKING MADE) , can you please tell me , if i use this artchitecture : DAL – Business – Services – Presentation (MVC) , when will the DI be needed ? Presentation ? or Services ?
Big questions on Dependency Injection and hard to answer in your situation. For me the key is the Service Layer. Maybe have a look at this article I wrote for Simple-Talk which describes my standard architecture: https://www.simple-talk.com/dotnet/asp.net/using-entity-framework-with-an-existing-database–user-interface/
i read your article and as usual it’s precious, thank you , i loved reading about DTO , a lot of developpers hate ’em but i just love em for the security it can give me passing my model to presentation ends. for the architecture you written i ve been using the same for many project now , and it’s quite simple and elegant to maintain.
this the article i used to get based on to accomplish the architecture : http://serena-yeoh.blogspot.com/2013/06/layered-architecture-for-net.html
Ps : Sorry for the grammar errors i made english is my 3th language! 🙂 still trying to perfectionate it.
Hi khalili, I understand your desire to separate the layers,
but if you are using Entity Framework (and NHibernate I think) there is likely
to be some overlap if your use the classes in your DAL. As I explain in this article
I use https://github.com/JonPSmith/GenericServices
in the Service Layer to (mostly)
separate the DAL from the Presentation Layer, or in your case the RESTful API,
or whatever you are using at the service end of your SOA.
On the code for http://complex.samplemvcwebapp.net/Orders
you find all the code at https://github.com/JonPSmith/SampleMvcWebAppComplex
, but be aware that it is NOT an open-source project as it contains some
proprietary code of both my own and KendoUi from Telerik. This is there to
provide examples of how GenericServices works, but please don’t go copying
large chunks of it into your project.
Check out another of my articles https://thereformedprogrammer.net/architecture-of-business-layer-working-with-entity-framework/
for how I handle the Business Layer to Presentation Layer in a similar way to
what GenericServices does for DAL to Presentation Layer.
Hi Jon, Thanks for sharing this article. There is too much data out there advocating use of repository pattern but no one tells why they are using it. It becomes very difficult as a beginner to understand how to select a proper solution /architecture while implementing the business requirements.