In this article I describe six different approaches to building applications that use Microsoft’s database access framework, Entity Framework (EF). All six approaches are based on software principles and patterns that many of you will be familiar with. This article shows how I applied these principles and patterns in real-world applications that use EF. The six principles and patterns are:
- Separation of concerns – building the right architecture.
- The Service Layer – separating data actions from presentation action.
- Repositories – picking the right sort of database access pattern.
- Dependency injection – turning your database code into services.
- Building business logic – using Domain-Driven Design with EF.
- Performance tuning EF – get it working, but be ready to make it faster if you need to.
I have an interesting perspective when it comes to software principles and patterns. I started out as a programmer, but then moved into technical management 1988. I came back to programming in 2009, a 21-year gap, and the whole software world had changed. Thankfully over those years some seriously clever people had been thinking about the science of programming, and I avidly read their articles and books.
While it was great to learn things from these software giants, I found it took some time to find the right ways to apply their ideas in the applications I developed. This article brings together the combination of ideas from some of the great software thinkers with my years of learning as I have applied and refined their approaches in building applications that used EF for database access.
All the software and figures in this article come from a book I am writing for Manning Publication called Entity Framework Core in Action that is now on early-access release i.e. if you buy now you will get the chapters as I write them, and the full book when it’s finished. The code is therefore based on the new .NET Core frameworks: EF Core and ASP.NET Core. However, these software principles and patterns apply equally well to the older Entity Framework, version 6 (EF6.x) framework and ASP.NET MVC5.
Note: I’m going to assume you know about Entity Framework already. If you don’t then I recommend you read the first chapter of my book, which is free, or look at Microsoft’s EF Core documentation which includes a number of example applications.
Before I start I need to say that the descriptions I show are my way of implementing the principles and patterns I talk about. There are plenty of other ways to implement each of six topics, mine are just one of them. Have fun yourself developing your own techniques and libraries that will improve and accelerate your development.
1. Principle: Separation of concerns – building on the right architecture
There is a software principal called Separation of Concerns (SoC), which says that you should:
- Put code that has a similar, or strongly-related functions should be grouped together – in .NET terms put in separate projects. This called cohesion.
- Make each group/project as self-contained as possible. Each piece of code should have a clear interface and scope of work that is unlikely to change to because of other callers changing what they do. This is called low coupling.
NOTE: Here is a more in-depth article on Separation of Concerns if you want to look into SoC some more.
For simplicity most examples of EF code on the web tend to show EF Core database commands being called directly from whatever application type they are using. This doesn’t follow SoC and nor does it really represent how real applications are written. I took the decision in my book to use a more representative software architecture for my example code, and I used a layered architecture. Using this does make it a little more difficult for the reader, but I build up the application structure over a number of chapter. Here is the final architecture of my example book selling site.
I could have used a number of different architectures, see this link for a good list, but the layered approach works well for small to medium applications. A layered architecture is also a good fit for cloud hosting, where cloud providers can spin up more instances of the web application if it is under a heavy load, that is, it will run multiple copies of a web application and place a load balancer to spread the load over all the copies. This known as scale out on Microsoft’s Azure and auto scaling on Amazon’s AWS.
The figure below shows how I apply SoC to my database access code. It shows the same software architecture, but with all my EF database access code highlighted in bubbles. The size of the bubbles relates to the amount of EF code you will find in each layer. Notice that the ASP.NET Core project and the pure business logic (BizLogic) project have no EF Core query/update code in them at all.
As I go through this article I will refer back to SoC, as it is an integral part of how I approach database applications.
2. Pattern: The Service Layer – separating data actions from presentation actions
One of the influential books I read when I came back to programming was Dino Esposito and Andrea Saltarello’s book Microsoft .NET: Architecting Applications for the Enterprise, published in 2009. Some of the technology he covered then is now superseded, but the patterns are still relevant today (Dino has written a number of newer books, see this link). This book introduced me to the use of Service Layer, which Martin Fowler previously described in his classic book in 2002.
Dino Esposito says in his book that the Service Layer “sets a boundary between two interfacing layers” and Martin Fowler’s site link says the Service Layer “Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation”. That all sounds great, but how does that help my applications? Quite a bit actually.
I’m going to describe how the Service Layer acts as an adapter in this section. Later, in the section of business logic, I will cover the second way the Service Layer can serve me, by being in command of running my business code.
The Service Layer as an adapter
In a layered architecture there is often a data mismatch between the database/business logic and the presentation layer. The Domain-Driven Design (DDD) approach, which I describe later, says that the database and the business logic should be focused on the business rules, while the Presentation Layer is about giving the user a great user experience, or in the case of a web service, providing a standard and simple API.
For this reason, the Service Layer becomes a crucial layer, as it can be the layer that understands both sides and can transform the data between the two worlds. This keeps the business logic and the database uncluttered by the presentation needs, like drop down list and json AJAX calls. Similarly, by having the Service Layer deliver pre-formatted data in exactly the form the presentation layer needs then it makes it much simpler for the presentation layer to show that data.
When dealing with database accesses via EF the Service Layers uses an adapter pattern to transform from the data layer/business logic layers to/from the presentation layer. Databases tend to minimise duplication of data and maximises the relational links between data, while the presentation layer is about showing the data in a form that the user finds useful.
The figure below shows an example of this difference in approach. The image comes from the list of books produced by the example book selling site that I create in my book. You can see how I have to pick data from lots of different tables in the database, and do some calculations, to form a summary of a book in my book list display.
Note: You can see this book list in action on the live site that hosts the example book selling site, at http://efcoreinaction.com/
EF provides a way of building queries, called select loading, that can ‘pick out’ the relevant columns from each table and combine them into a DTO/ViewModel class that exactly fits the user view. I apply this transform in the Service Layer, alone with other sorting, filtering and paging features. The listing below is the select query using EF Core to build the book summary you just saw in the figure above.
public static IQueryable<BookListDto> MapBookToDto(this IQueryable<Book> books) { return books.Select(p => new BookListDto { BookId = p.BookId, Title = p.Title, Price = p.Price, PublishedOn = p.PublishedOn, ActualPrice = p.Promotion == null ? p.Price : p.Promotion.NewPrice, PromotionPromotionalText = p.Promotion == null ? null : p.Promotion.PromotionalText, AuthorsOrdered = string.Join(", ", p.AuthorsLink .OrderBy(q => q.Order) .Select(q => q.Author.Name)), ReviewsCount = p.Reviews.Count, ReviewsAverageVotes = p.Reviews.Select(y => (double?)y.NumStars).Average() }); }
Note: The code above wouldn’t work with EF6.x because it includes the command string.Join that cannot be converted into SQL but EF6.x. EF Core has a called Client vs. Server Evaluation, which allows methods that cannot be translated to SQL to be included. They are run after the data has been returned from the database.
Yes, this code is complex, but to build the summary we need to pull data from lots of different places and do some calculations at the same time, so that’s what you get. I have built a library called EfCore.GenericServices which automates the building of EF select loading commands like this by using a LINQ Mapper called AutoMapper. This significantly improves the speed of development of these complex queries. UPDATE: See the article “GenericServices: A library to provide CRUD front-end services from a EF Core database” for more on the EfCore.GenericServices library.
3. Pattern: Picking the right sort of database access pattern
There are a number of different ways we can form your EF database access inside an application, with different levels of hiding the EF access code from the rest of the application. In the figure below I show four different data access patterns.
UPDATE: If you are interested in this topic I have written a new article called “Is the repository pattern useful with Entity Framework Core?” which cover this in more detail.
The four types of database access patterns are:
- Repository + Unit of Work (Repo+UOW). This hides all the EF Core behind code that provides a different interface to EF. The idea being you could replace EF with another database access framework with no change to the methods that call the Repo+UOW.
- EF repository. This is a repository patterns that doesn’t try and hide the EF code like the Repo+UOW pattern does. EF repositories assume that you as developer know the rules of EF, such as using tracked entities and calling SaveChanges for updates, and you will abide by them.
- Query Object. Query objects encapsulate the code for a database query, that is a database read. They hold the whole code for a query or for complex queries it might hold part of a query. Query objects are normally built as extension methods with IQueryable<T> inputs and outputs so that they can be chained together to build more complex queries.
- Direct calls to EF. This represents the case where you simply place the EF code you need in the method that needs it. For instance, all the EF code to build a list of books would be in the ASP.NET action method that shows that list.
NOTE: AS I said earlier I have created a library called GenericServices for EF6.x (and EF Core in the future). This is a form of EF repository.
I used the Repo+UOW pattern, which was the recommended approach at the time, in a big project in 2014 – and I found it was really hard work. I and many others realised Repo+UOW wasn’t the way to go – see my article ‘Is the Repository pattern useful with Entity Framework Core?’. The Repo+UOW can be a valid pattern in some cases where hiding of the certain part of the data is needed, but I think there are better ways to do this with some of the new EF Core features, such as backing fields.
At the other end of the spectrum is the direct calls to EF in the method that needs it. This fails the separation of concerns principal because the database code is mixed in with other code not directly involved in database issues.
So, having ruled out the two extremes I would recommend:
- Query Objects for building queries, often breaking down large queries into a series of query objects. The previous listing in this article of the method called MapBookToDto, which is a query object. I cover query objects in chapter 2 of my book.
- For Create, Update and Delete (and business logic which I cover later) I use DDD-style access methods, that is, I create a method in the entity class to update the property or relationship. This isolates the EF code and makes it easier to refactor or performance tune that code.
The listing below shows a class with two EF repository methods for changing the publication date of a book in my example book selling site. I cover this in chapter 3 of my book.
public class ChangePubDateService : IChangePubDateService { private readonly EfCoreContext _context; public ChangePubDateService(EfCoreContext context) { _context = context; } public ChangePubDateDto GetOriginal(int id) { return _context.Books .Select(p => new ChangePubDateDto { BookId = p.BookId, Title = p.Title, PublishedOn = p.PublishedOn }) .Single(k => k.BookId == id); } public Book UpdateBook(ChangePubDateDto dto) { var book = _context.Books.Find(dto.BookId); book.PublishedOn = dto.PublishedOn; _context.SaveChanges(); return book; } }
4. Pattern: Turning your database code into services
I have used dependency injection (DI) for years and I think it’s really useful approach. I want to show you a way you can inject your database access code into an ASP.NET Core application.
Note: If you haven’t used DI before have a look at this article for an introduction, or this longer article from another of the great thinker, Martin Fowler.
The benefits of doing this are twofold. Firstly, DI will dynamically link together your database access to into the parts of the presentation/web API code that need it. Secondly, because I am using interfaces, it is very easy to replace the calls to the database access code with mocks for unit testing.
I haven’t got the space in this article to give you all the details (I takes five pages in chapter 5 of my book to cover this), but here are the main steps, with links to online documentation if you want to follow it up. Here are the steps:
- You need to make each of your database access code into thin repositories. That is a class containing a method, or methods, that the front-end code needs to call. See the ChangePubDateService class listed above.
- You need to add an interface to each EF repository class. You can see the IChangePubDateService interface applied to the ChangePubDateService class listed above.
- You need to register your EF repository class against its interface in the DI provider. This will depend on your application. For ASP.NET Core see this article.
- Then you need to inject it into the front-end method that needs it. In ASP.NET Core you can inject into an action method using the [FromServices] Note: I use this DI parameter injection rather than the more normal constructor injection because it means I only create the class when I really need it, i.e. it is more efficient this way.
Note: I realise that is a lot to take in. If you need more information can look at the GitHub repo associated with my book. Here are some useful links:
- Steps 1 and 2: The ChangePubDateService
- Steps 3:
- The normal way using ASP.NET DI
- The more elegant way using AutoFac.
- Step 4: The AdminController action method.
At the end of this you have a method you can call to access the database. The listing below shows an ASP.NET Core action method that calls the UpdateBook method of the ChangePubDateService class that I listed previously. Line 4 has the [FromServices] attribute that tells the DI provider to inject the ChangePubDateService class into the parameter called service.
[HttpPost] [ValidateAntiForgeryToken] public IActionResult ChangePubDate(ChangePubDateDto dto, [FromServices]IChangePubDateService service) { service.UpdateBook(dto); return View("BookUpdated", "Successfully changed publication date"); }
NOTE: There is a way to do parameter injecting into an ASP.NET MVC action method, but it involves you having to override the default Binder. See The section “How DI is used in SampleMvcWebApp” at the bottom of this page, and my DiModelBinder in the associated GitHub repo.
The result of all this is that database code is nicely separated into its own class/method and your front-end code just has to call the method, not knowing what it contains. And unit testing is easy, as you can check the database access code on its own, and replace the same code in your front-end call with a mocking class that implements the interface.
5. Pattern: Building business logic – using Domain-Driven Design
Real-world applications are built to supply some sort of service, ranging from holding a simple list of things on your computer through to managing a nuclear reactor. Every different real-world problem has a set of rules, often referred to as business rules, or by the more generic name, domain rules.
Another book that I read some time ago that had a big impact on me was “Domain-Driven Design” by Eric Evans. The Domain-Driven Design (DDD) approach says that the business problem you are trying to solve must drive the whole of the development. Eric then goes on to explain how the business logic should be isolated from everything else other that the database classes so that you can give all your attention to what Eric Evans calls the “difficult task” of writing business logic.
There are lots of debates about whether EF Core is suitable for a DDD approach, because the business logic code is normally separate from the EF entity classes which it maps to the database. However, Eric Evans is pragmatic on this point and says in the section entitled “Working within your (database access) Frameworks” that, and I quote:
“In general, don’t fight your framework. Seek ways to keep the fundamentals of domain-driven design and let go of the specifics when your framework is antagonistic”
Page 157, Domain-Driven Design, by Eric Evans, 2004.
Note: I had to look up the word antagonistic: it means “showing or feeling active opposition or hostility towards someone or something”.
Over the years I have developed a DDD approach that works with EF and I have dedicated the whole of chapter 4 of my book to the topic of business logic because it is so important to get right. Here is a summary of the guidelines in that chapter:
- The business logic has first call on how the database structure is defined
Because the problem I am trying to solve, called the “Domain Model” by Eric Evans, is the heart of the problem then it should define the way the whole application is designed. Therefore, I try to make the database structure, and the entity classes, match my business logic data needs as much as I can.
- The business logic should have no distractions
Writing the business logic is difficult enough in itself, so I isolate it from all the other application layers, other than the entity classes. That means when I write the business logic I only have to think about the business problem I am trying to fix. I leave the task of adapting the data for presentation to the Service Layer in my application.
- Business logic should think it is working on in-memory data
This is something Eric Evans taught me – write your business logic as if the data was in-memory. Of course there needs to be some a ‘load’ and ‘save’ parts, but for the core of my business logic I treat, as much as is practical, the data as if it is a normal, in-memory class or collection.
- Isolate the database access code into a separate project
This fairly new rule came out of writing an e-commerce application with some complex pricing and deliver rules. Before this I used EF directly in my business logic, but I found that it was hard to maintain, and difficult to performance tune. Now I have another project, which is a companion to the business logic, and holds all the database access code.
- The business logic should not call EF Core’s SaveChanges directly
The business logic does not call EF Core’s SaveChanges method directly. I have a class in the Service Layer whose job it is to run the business logic – this is a case of the Service Layer implementing the command pattern. and, if there are no errors, it calls SaveChanges. The main reason is to have control of whether to write the data out, but there are other benefits that I describe in the book.
The figure below shows the original software architecture, but with the focus on how the business logic is handled. The five numbers, with comments, match the numbered guidelines above.
In my book I use the processing of an order for books as an example of a piece of business logic. You can see this business logic in action by going to the companion live site, http://efcoreinaction.com/, where you can ‘buy’ a book. The site uses an HTTP cookie to hold your basket and your identity (saves you having to log in). No money needed – as the terms and conditions says, you aren’t actually going to buy a book.
The code is too long to add to this article, but I have written another article called Architecture of Business Layer working with Entity Framework (Core and v6) which covers the same area in more detail and contains plenty of code examples.
6. Principle: Get your EF code working, but be ready make it faster if you need to.
The recommended approach to developing software is to get it to work, and then worry about making it faster. Another more nuanced approach, attributed to Kent Beck, is Make it Work. Make it Right. Make it Fast. Either way, these principle says we should leave performance tuning to the end. I would add a second part: you should only performance tune if you need to.
In this article I am talking about database accesses via EF. I can develop pretty complex database accesses in EF really quickly – at least five times faster than using ADO.NET or Dapper. That covers the “get it working part”. The down side is that EF doesn’t always produce the best performing SQL commands: sometimes it’s because EF didn’t come up with a good SQL translation, and sometimes it’s because the LINQ code I wrote isn’t as efficient as I thought it was. The question is: does it matter?
For example, I developed a small e-commerce site (the code took me 10 months) which had a little over a 100 difference database accesses and about 20 tables. More than 60% of the database accessed were on the admin side, with maybe 10% of accesses that really mattered to the paying user.
To show this graphically I have picked out three features from my example book selling site and then graded them by two scales:
- vertically, what the user expects in terms of performance.
- Horizontally, how difficult is the database access.
This gives you the figure below, with top right highlighted as area where we really need to think about performance tuning.
My analysis says that only the book search query needs work to improve it. The user is used to fast searches thanks to Google etc. and will get frustrated if my application is too slow. Looking at the complexity of the book search, which includes filtering on things like average user votes, I can see that it produces some rather complex database access commands.
It turns out that the EF Core code for my book search performs badly, but there is plenty I can do about it. In fact, I have mapped out a whole section towards the end of my book where I show how I can improve the book search in a series stages, each getting more complex and taking more development time. They are:
- Can I improve the basic EF commands by rearranging or refining my EF code?
- Can I convert some or all of the EF code into direct SQL commands, calculated columns, store procedures etc.?
- Can I change the database structure, such as de-normalising the database, to improve the search performance?
Improving the book search will take quite a bit of time, but it’s worth it in this application. Quite honestly the other features aren’t worth the effort, as they are fast enough using standard EF Core commands.
Planning for possible performance tuning
While I totally agree with the idea that you shouldn’t try to performance tune too early, it is sensible to plan that you might have to performance tune. All the other approaches I have described, especially the encapsulation of the databases accesses, means that my database code is a) clearly isolated, and b) open for performance tuning.
So, my practice is to develop database accesses quickly with EF, but organise the code so that I encapsulate the database code cleanly. Then, if I have a performance problem then I can tune the database access code with minimal impact on other parts of your application.
Conclusion
When I came back to programming in 2009 some of my early code ended up with long methods which were intertwined with each other – they worked, but the code was hard to understand, debug and maintain. Since then I have taken the principles and practices from the software giants and worked out how to apply them real applications. With these I can write code that is robust, easy to test and easy to improve – and I write code much faster too.
However, for me, there is a gap between seeing a great idea and working out how it could help me. Some books I instantly loved, like Eric Evans “Domain-Driven Design” but it has still taken two or three projects before I had an implementation that works really well for me. I don’t think I’m unusual in this, as learning any new technique takes some time for it to become smooth and natural.
There are many great software thinkers out there and some great principles and practices. So the next time you think “there must be a better way of doing this” then go and have a look for other people’s thoughts. It’s a journey, but the reward is becoming a better developer.
Happy coding!
Further reading:
Hi Jon, thanks for your great article ! I’d like to know your opinion about using stored procs. They can incredibly improve the performances, and personally I find it difficult not to put a part of business logic there. How would you balance between layering, ER, and using the power of stored procedure ? Best regards !
Hi Olivier,
There are lots of different opinions on using SQL stored procedures with an ORM like EF (here is one take on the topic. I will give you my opinion.
Overall I think writing business logic in your software outside of the database works well, but there can be cases for stored procs. The main one is if there are multiple applications that need to do some business logic. In that case the DRY principal says you should have one version of your business logic, and stored procs are a good way of doing that. The second one is the one you state – performance. If your business logic does something complex, maybe causing locking of tables, then a stored proc can be faster. (Personally I haven’t come across business logic like this, other than ingest of lots of data).
Personally I write my business logic in software, as described in this (and other) articles. I’m quicker in C# than in SQL, and I have better unit testing options. In the times I when I had multiple applications accessing the database the business logic was fairly simple, so stored procs wasn’t necessary/appropriate. Also performance hasn’t been an issue because I write EF code that performs well (as you would expect from me!).
In the end it comes down you the business needs and the specific skills the development team has.
NOTE: I don’t think EF Core supports stored procs that well (here the Microsoft documentation on calling stored procs) – you can do it, but it isn’t that friendly (EF 6 has slighly better features). I would use Dapper if I wanted to call stored procs.
Great article, I will be buying your book from amazon. Thank you.
Hi Mo,
Glad you like it. I hope you like the book too. Make sure to look at chapters 4,5, and 10, which cover the same parts in this article, but in more detail.
Hi, thanks I will be sure to read it. Ordered now, should be here tomorrow just in time for Christmas! This was so well written I just had to buy your book. Bravo. Thank you.
thanks, first of all and appreciation for the work you do.
question, not related to the topic, just nit-picking 🙂 : at point 3. in the very last code snippet (right before point 4), in the method ChangePubDateDto GetOriginal(int id) , you create a new DTO for each of the book even though you only need one (the one with the id match).Wouldn’t be better to switch order for the Single() and Select() ?
Hi claudia,
Actually putting the select first makes for a (slightly) better performance – let me explain why as it helps in writing high performing code.
Certain methods, like ToList, ToArray, are referred to in EF Core as “execute commands”, i.e. they cause the LINQ commands to be translated into database commands, which are then run on the database. The Single method is an “execute command”, alone with First, Count, Any etc. So, looking at the two options:
1. Select( x, y , z).Single(id) = this will return only the three columns, x, y, z, and then return one instance of that.
2. Single(id).Select( x, y , z) = this will return one book from the database and then (in software) it picks out the properties x, y, z.
I agree the cases above aren’t as obvious as something like context.Books.ToList().Single(x => x.BookId == 123), which would have very bad performance, as it would load ALL the books into memory and then pick one out. But I always try to show the best performing way to access a database using EF Core.
Having read your book I’m still a little confused over why DbContext is per-request, and what advantages this provides. The controller is instantiated for every request so why not just make DbContext transient?
Eg if I have an edit form, its controller would have a “get” method to retrieve the entity from the db, and a “post” method to update the db (which involves retrieving the entity again, updating its values, then SaveChanges). Each is a separate request, each with a new DbContext instance.
What an I missing?! In what scenarios is a per-request DbContext useful?
The main reason is you might have multiple services, each created via DI, involved in one HTTP request. For instance if serviceA has IServiceB injected into it via its constructor, and both ServiceA and Service B pick up App DbContext, then you want both services to use the same instance of the DbContext so they are both working on the same data.
This happens with my EfCore.GenericBizRunner library which manages the running of business logic. The business logic it calls may create/update/delete data in the database (and gets the App DbContext via DI), but its the job of the EfCore.GenericBizRunner library to call the SaveChanges to save that data. This only works if the GenericBizRunner instance and the business logic instance have the same instance of the App DbContext.
There are other scenarios, but that’s the main one (I think!)
I see this over and over, make it work, make it right, make it fast. That’s great if you have super budget and you can allocate resources to write code three times or more. I made a switch to a much simpler approach that gives me the best of both worlds. High performance, high productivity and I only have to write code once. I don’t understand the love affair with Entity Framework, it’s sluggish, limited, cumbersome, and Microsoft is more than happy to give it away because as long as they can slow down your data access, they can sell you larger instances of their software. It’s a trojan horse that people should avoid at all costs.
Hey Jon, awesome article!! I loved the way that you split the access to basic crud actions to go directly from the controllers to the data access layers avoiding having what I call “proxy’ methods on the business layers doing nothing except redirecting CRUD actions to the data access. I was looking at your code and the DDD is something that I never quite completely understand. There are some instantiations of objects such as the snippet bellow that seems to violate the dependency injection principle, since those classes are hidden inside of the constructor.
_runner =
new RunnerWriteDb(//#F
new PlaceOrderAction( //#F
new PlaceOrderDbAccess(context)), //#F
context);
I guess this is probably something natural for the DDD approach, but some people, including me, tend to see every “new” instantiation inside of methods or constructors as something wrong that should be avoided. Can you explain a little bit about that, or point me to some resource where I can get a better understanding of how that works and when new object is good or bad.
Thanks and keep up with your good work!
Hi Vinicius,
The code you are looking at comes from the Git reports associated with the book I am writing for Manning, Entity Framework in Action in chapter 4, and I don’t introduce dependency injection (DI) until the next chapter, 5. The rules is not to use a feature I haven’t explained, so I didn’t use DI in that code. I also I find its easier to explain something if I don’t mix in too many different feature/patterns, but it does mean the code may not be totally ‘real life’. So, so your not wrong on DI – you were just reading something before I introduced DI.
In real projects I use DI extensively. In this case I would inject the PlaceOrderAction via the constructor into the class that is going to run that code. In turn the PlaceOrderAction class itself has an IPlaceOrderDbAccess constructor parameter so that DI will inject the PlaceOrderDbAccess class.
On the RunnerWriteDb I have a library that handles that creation and running of the RunnerWriteDb via DI for EF6.x. This library has turned out to be quite complex (too complex I think) so I never made it open-source as explaining it would be a nightmare, but I have used it in projects I contracted on. I have an idea to make a simpler BizRunner library for EF Core sometime and make that open-source, but I have to finish this book first! I have just finishied writing chapter 12, on performance tuning and am now going through the code & book updating everything to EF Core version 2.