Architecture of Business Layer working with Entity Framework (Core and v6) – revisited

I wrote an article a while ago called Architecture of Business Layer working with Entity Framework, which has been popular. I am now playing with Entity Framework (EF) Core and some sample code made me think – could I better isolate the EF part of my Business Logic? The answer is yes, and this article describes the new and improved approach, with a lot more examples.

Note: All the code in this article is using .NET Core and Entity Framework Core (EF Core). However, the code is easy to understand for anyone who has played with either flavour of EF, and the concepts work equally well with EF 6.x or EF Core.

UPDATE 2017: This article was a precursor to the book Entity Framework Core in Action that I am writing for Manning Publishing. Chapter 4 of the book covers business logic in detail.

The book also has a companion live site where the business logic in this article is used to provide an example checkout service. Have a go – no money needed:)

What is the Business Layer?

If you are new to idea of Business Logic, then I suggest you read the section near the top called ‘What is the Business Layer’ in my original article as it gives a good description. However, if you are in a hurry here is the short version.

Business Logic is what we call pieces of code that carry out operations that are specific to the job that the application is carrying out. For instance, on an e-commerce site like Amazon you would have Business Logic that handles a customer’s purchase: checking on availability and delivery, taking payments, sending an email confirmation etc. Business logic is definitely a step up on complexity over CRUD (Create, Read, Update and Delete) operations.

While Business Logic can be spread throughout an application and the database, it is accepted best practice to try and isolate the Business Logic into one place, which am calling the Business Layer.

Aside: While having all the business rules in the Business Layer is something we should always strive for I find that in practice some issues go outside the Business Layer for good reasons. For instance validation of data often flows up to the Presentation Layer so that the user gets early feedback. It may also flow down to the database, which checks data written to the database, to ensure database integrity.

Other business logic appears in the Presentation Layer, like not allowing users to buy unless they provide a credit card, but the status should be controlled by the Business Layer. Part of the skill is to decide whether what you are doing is justifiable or will come back and bite you later! I often get that wrong, but hopefully I learn from my mistakes.

The (improved) architecture of my Business Layer

Let me start with a diagram of the new, improved structure of the Business Logic within an application – in this case an ASP.NET web application but the same approach would work in many other application types.

BizLogic and BizDbAccess layer diagram - simplified

Next I will explain each of the main layers, with example code.

1. The DataLayer

The Data Layer is where the EF POCO (entity) classes are defined, along with the EF setup and DbContext. I am not going to describe how to create the EF entity classes or the setup of the DbContext as I will assume you already know about EF. For information on how to set up the database and EF entities see:

Note: I have shown the Data Layer as one assembly, but in bigger applications the EF entity classes are often in a different assembly to the EF setup code. In that case the BizLogic would only link to the EF entity classes.

2. The BizLogic Layer

I have written numerous applications, all of which has some quite complex Business Logic. Over the years I have tried different ways of organising these applications and I have come up with one key philosophy – that the “The Business Layer is King“, i.e. its design and needs drives everything else.

I am a big fan of Domain-Driven Design (DDD) and Eric Evans’ seminal book on DDD, Domain-Driven Design. Eric Evans’ book talks about how the business problem we are trying to solve, called the “Domain Model”, should be “the heart of the Software” (see Eric Evans book, page 4). Eric goes on to say “When the domain is complex, this is a difficult task, calling for the concentrated effort of talented ad skilled people”. Therefore, I try to make sure that the Business Logics data structures are defined by, and solely focused on, the business problem. How that data is stored and how that data is viewed are secondary issues.

Because of the way the EF works it is not sensible to combine the Business Logic with the actual EF POCO classes. Eric Evan’s recognises and discusses this problem in his book, see Eric Evans book, page 159. However, lots of people have tried to make EF more DDD-like.

NOTE: There is plenty of debate on how to apply DDD to EF. Personally I did try making the EF entity classes behave in a DDD way, but for me the amount of work for the gain in separation became too much (however, it is easier in EF Core though). In trying to go fully DDD with EF I felt I was losing the core tenant of Eric Evans book, which is that the business problem was the focus, not the technology. I recommend Jimmy Bogard comments near the end of this EF issue ‘The impedance mismatch between EF and domain models: what is Entity Framework’s answer?’, which I think are very helpful.

My rules for the Business Logic are:

a. The Business Logic data classes should not be affected by other higher layers

Business Logic can be hard to write. Therefore, I want to stay focused on business issue and not worry about how other layers above might need to reformat/adapt it. So, all data in or out of the Business Logic is either defined inside the BizLogic layer, or it is a Data Layer class. It is Service Layer’s job to act as an Adapter, i.e. Service Layer converts any data to/from what the Business Logic needs.

In new/modern databases the EF POCO (entity) classes should be a very good fit to the Business Logic needs, with a few extra properties needed to set up the database relationships, e.g. Foreign Keys. Therefore, the Business Logic can use the EF POCO (entity) classes directly without any adaption.

However, one of my reader, , pointed out that for for old/legacy databases the fit between what the database and what the Business Logic may not be a good match.

b. The Business Logic works on a set of in-memory data

I don’t want the Business Logic worrying about how to load and save data in the database. It is much simpler to design the Business Logic code to work on simple in-memory set of data. The changes described in this article improve this significantly over the previous article.

In the previous approach I used to have a specific part of the Business Logic, normally at the start, which loaded all of the data. However, the new approach has what I call a DbAccess class which handles all the reading and writing (see later for why this is better). The DbAccess is class is a Facade pattern.

Example Code

UPDATE: This article was a precursor to the book Entity Framework Core in Action that I am writing for Manning Publishing. There is a Git repo to go with the book, with the Chapter04 branch containing the code you see here. Chapter 4 of the book covers the whole area of business logic in detail.

Here is an example of Business Logic which is creating the first part of the order, which consists of an Order class instance with a number of LineItems. It is handed the customer’s Id, and list of LineItems which contain an entry for each BookId, followed by how many copies of that book the customer wants.

namespace BizLogic.Orders.Concrete
{
    public interface IPlaceOrderAction : IBizActionAsync<PlaceOrderInDto, Order> { }

    public class PlaceOrderAction : IPlaceOrderAction
    {
        private readonly IPlaceOrderDbAccess _dbAccess;
        private readonly List<string> _errors = new List<string>();

        public IImmutableList<string> Errors => _errors.ToImmutableList();

        public bool HasErrors => _errors.Any();

        public PlaceOrderAction(IPlaceOrderDbAccess dbAccess)
        {
            _dbAccess = dbAccess;
        }

        /// <summary>
        /// This validates the input and if OK creates an order 
        /// and calls the _dbAccess to add to orders
        /// </summary>
        /// <returns>returns an Order. Can be null if there are errors</return>;
        public async Task<Order> ActionAsync(PlaceOrderInDto dto)
        {
            if (!dto.TsAndCsAccepted)
            {
                _errors.Add("You must accept the T and Cs to place an order.");
                return null;
            }
            if (!dto.LineItems.Any())
            {
                _errors.Add("No items in your basket.");
                return null;
            }

            var booksDict = await 
                _dbAccess.FindBooksByIdsAsync(
                    dto.LineItems.Select(x => x.BookId))
                .ConfigureAwait(false);
            var order = new Order
            {
                CustomerName = dto.UserId,
                LineItems = FormLineItemsWithErrorChecking(
                     dto.LineItems, booksDict)
            };    

            _dbAccess.Add(order);

            return order;
        }

        private List<LineItem> FormLineItemsWithErrorChecking(
             IEnumerable<OrderLineItem> lineItems, 
             IDictionary<int,Book> booksDict)
        {
           // rest of the code left out…

A few things to point out about the above.

  1. We have created a generic IBizAction<Tin, Tout> interface that the PlaceOrderAction class has to implement. This is important as we use a generic BizRunner to run all the actions (described later in the Service Layer section). The IBizActionAsync interface ensures we have the Errors and HasErrors properties as well as the ActionAsync
  2. It uses the IPlaceOrderDbAccess provided via the constructor to a) find the books that were referred to in the order and b) to add the order to the EF db.Orders set.

NOTE: I also setup an interface, IPlaceOrderAction. I need this to get Dependency Injection (DI) to work. But I won’t be describing DI in this article. However, I really recommend the use of DI on any non-trivial application.

2. The BizDbAccess Layer (new)

The BizDbAccess layer contains a corresponding class for each BizLogic class that accesses the database. It is a very thin Facade over the EF calls. I should stress, I am not trying to hide the EF calls, or make a repository. I am just trying to Isolate the calls. Let me explain.

The problem with my previous approach, where the Business Logic called EF directly, wasn’t that it didn’t work, but that it was hard to remember where all the EF calls were. When it came to refactoring, especially when doing performance improvements, then I had to hunt around to check I had got every EF call. By simply moving all the EF calls into another class I have all of the EF commands in one place.

The main approach I will describe assumes that the database is of a new/modern design and there is a good fit between the data held in the database and the Business Logic requirements. The code below is a PlaceOrderDbAccess class, which goes with the PlaceOrderAction Business Logic described above:

public class PlaceOrderDbAccess : IPlaceOrderDbAccess
{
    private readonly EfCoreContext _db;

    public PlaceOrderDbAccess(EfCoreContext db)
    {
        _db = db;
    }

    /// <summary>
    /// This finds any books that fits the BookIds given to it
    /// </summary>
    /// <returns>A dictionary with the BookId as the key, and the Book as the value</returns>
    public async TaskIDictionary<int, Book>> FindBooksByIdsAsync(IEnumerable<int>; bookIds)
    {
        return await _db.Books.Where(x => bookIds.Contains(x.BookId))
            .ToDictionaryAsync(key => key.BookId)
            .ConfigureAwait(false);
    }

    public void Add(Order newOrder)
    {
        _db.Orders.Add(newOrder);
    }
}

Please note that I use a method called Add, to add the order to the EF Orders DbSet. As I said, I am not trying to hide what is going on, but just isolate the commands, so using the same terminology is helpful.

solution-view-bizlayer-bizdbaccessNOTE: To help with finding the relevant DbAccess I call the Business Logic class <name>Action and the DbAccess calls <name>DbAccess. They also have the same top-level directory name. See the attached picture of the solution directories on the right.

A secondary, but very powerful improvement, is that I could test my Business Logic without using an EF database. Because I provide an Interface then I can replace the DbAccess class with a Mock. Here is my Mock for PlaceOrderDbAccess.

public class MockPlaceOrderDbAccess : IPlaceOrderDbAccess
{
    public ImmutableList<Book> Books { get; private set; }

    public Order AddedOrder { get; private set; }
    public MockPlaceOrderDbAccess()
    {
        Books = CreateTestData.CreateBooks().ToImmutableList();
    }

    /// <summary>
    /// This finds any books that fits the BookIds given to it
    /// </summary>
    /// <param name="bookIds"></param>
    /// <returns>A dictionary with the BookId as the key, and the Book as the value</returns>
    public async Task<IDictionary<int, Book>> FindBooksByIdsAsync(
        IEnumerable<int> bookIds)
    {
        return Books.AsQueryable()
            .Where(x => bookIds.Contains(x.BookId))
            .ToDictionary(key => key.BookId);
    }

    public void Add(Order newOrder)
    {
        AddedOrder = newOrder;
    }
}

Being able to test all your Business Logic that way is very useful.

Handling old/legacy databases

One of my readers, , has been using a similar approach to the one describe in this article for some time. He pointed out in one of his comments that he finds this approach useful when the database tables are not a good fit for the Business Logic.

At that point, in addition to isolating the EF commands, the BizDbAccess class can carry out any adapting/ reformatting of the data between the database and the Business Logic.

For example I have come across database which does not mark its relationship keys and Foreign Keys. This stops EF from doing relational fixup, i.e. linking the various entities loaded. In that case you would add code to the DbAccess class to link the loaded entities so that the Business Logic can work on a linked, in-memory set of classes.

The Service Layer

As I said earlier in my applications the Service Layer is very important layer that links everything together. The Service Layer uses both the Command pattern and the Adapter pattern between the presentation layer and all the layers below.

Let me start by showing you one of what I call the BizRunner classes, which is the Command part of the code. This class contains the code to runs the PlaceOrderAction method above, which has a signature of taking data in and producing data out. It also needs data to be written to the database, hence the format/content of this BizRuner:

public class RunnerWriteDbAsync<TIn, TOut>
{
    private readonly IBizActionAsync<TIn, TOut> _actionClass;
    private readonly DbContext _db;

    public RunnerWriteDbAsync(IBizActionAsync<TIn, TOut> actionClass, DbContext db)
    {
        _db = db;
        _actionClass = actionClass;
    }

    public async Task<TOut> RunActionAsync(TIn dataIn)
    {
        var result = await _actionClass.ActionAsync(dataIn).ConfigureAwait(false);
        if (!_actionClass.HasErrors)
            await _db.SaveChangesAsync();

        return result;
    }
}

The RunnerWriteDbAsync BizRunner is a simple, but powerful class which, through the use of interfaces and generics can run different Business Logic.

One thing to note in this arrangement is that only the BizRunner’s RunActionAsync method should call the EF command SaveChangesAsync. That is important for a number of reasons:

  1. If any of the BizLogic/BizDbAccess methods called SaveChanges arbitrarily then you could get problems, with part of the data being saved while another part wasn’t. By having only the BizRunner calling SaveChanges it means that you know that all the Business Logic has finished.
  2. A subtler (and more advanced) reason is it allows us to chain together multiple Business Logic calls within a transaction (I describe this in the article ‘Architecture of Business Layer – Calling multiple business methods in one HTTP request’).
  3. The handling of errors is important, and you can see that the BizRunner will only call EF’s SaveChanges if there are no errors.
  4. EF6.x and EF Core differ on what happens when you call SaveChanges.
    1. In EF6.x it validates the data against any validation attributes, such as [MaxLength(20)], and against IValidatableObject if present. This means you will get a DbEntityValidationException exception if any validation error is found. The exception containing validation errors for every incorrect property or class that was new or updated.
    2. EF Core uses a lighter touch and does not validate the data, because in many cases the data has been already validated on input. Clearly that isn’t the case in business logic and you may want to add this feature back to EF Core by overriding SaveChanges and add validation – see this article for how to do that.

Note: The discarding of data by not calling ‘SaveChanges’ only works in situation where each call has its own DbContext. This is the case in a web application as each HTTP request gets a new DbContext. However, in Windows Applications etc. where the DbContext can be kept alive for longer you need to be careful about the lifetime/disposal of the DbContext.

Here is the code inside the Service Layer that uses the BizRunner to call PlaceOrderAction. You can see this acts as an Adapter pattern to the input and output of the Business Logic. The method:

  1. Gets current basket from a cookie and converts it into the format that the Business Logic needs.
  2. Calls the RunActionAction method from the PlaceOrderAction class.
  3. If RunActionAction method was successful it clears the basket, as the order now holds them.
  4. It extracts and returns the OrderId from the Order instance, as that is what the Presentation Layer needs.

The code is:

{
public class PlaceOrderService
{
    private readonly CheckoutCookie _checkoutCookie;
    private readonly EfCoreContext _db;

    public IImmutableList<string> Errors { get; private set; }

    public PlaceOrderService(IRequestCookieCollection cookiesIn, IResponseCookies cookiesOut, EfCoreContext db)
    {
        _db = db;
        _checkoutCookie = new CheckoutCookie(cookiesIn, cookiesOut);
    }

    /// <summary>
    /// This creates the order and, if successful clears the cookie
    /// </summary>
    /// <returns>Returns the OrderId, or zero if errors</returns>
    public async Task<int> PlaceOrderAsync(bool tsAndCsAccepted)
    {
        var checkoutService = new CheckoutCookieService(_checkoutCookie.GetValue());

        var action = new PlaceOrderAction(new PlaceOrderDbAccess(_db));
        var runner = new RunnerWriteDbAsync<PlaceOrderInDto, Order>(action, _db);

        var order = await runner.RunActionAsync(
            new PlaceOrderInDto(tsAndCsAccepted, 
            checkoutService.UserId, checkoutService.LineItems));
        Errors = action.Errors;

        if (action.HasErrors) return 0;

        //successful so clear the cookie line items
        checkoutService.ClearAllLineItems();
        _checkoutCookie.AddOrUpdateCookie(
             checkoutService.EncodeForCookie());

        return order.OrderId;
    }
}

You can see the PlaceOrderAction instance being created, along with its linked PlaceOrderDbAccess class. This would normally be done by Dependency Injection, but to make the example simpler to understand I have created it by hand.

You can see the adapter pattern in progress. On input the information is contained in a cookie, but the business layer shouldn’t have to deal with that. Therefore, the Service Layer method PlaceOrderAsync converts the cookie content into the form that the PlaceOrderAction wants.

Similarly, for the output of the PlaceOrderAction Business Logic, which returns an Order instance, but the presentation layer actually wants the OrderId, Again the PlaceOrderAsync method extracts the OrderId from the Order and returns that to the MVC Action.

Interestingly the pattern of returning a database class instance is quite typical, as the Business Logic won’t know what the entity’s key is, as it isn’t generated until the BizRunner in the Service Layer calls EF’s SaveChanges. It then becomes the job of the Service Layer to extract/adapt the parts that are needed by the Presentation Layer.

NOTE: The BizRunner and the code above works fine, but is simpler than what I use in practice. I have a private library called GenericActions, which has the same sort of features as my GenericServices library. This can identify the right signature of BizRunner to call by unpacking the Interface parts. GenericActions also uses the same ISuccessOrErrors<T> class as GenericServices, which returns both the status/errors and the class being returned. It also has the AutoMapper mapping built in to do any needed adapting.

Presentation layer

For completeness I have included the presentation layer, which in this case is an ASP.NET Core MVC page. If the order is successful it redirects to the confirmation page, otherwise it copies the errors into the ModelState and shows the basket again, with the error message(s).

public async Task<IActionResult> PlaceOrder(bool iAcceptTAndCs)
{
    var service = new PlaceOrderService(
        HttpContext.Request.Cookies, 
        HttpContext.Response.Cookies, _db);
    var orderId = await service.PlaceOrderAsync(iAcceptTAndCs);

    if (!service.Errors.Any())
        return RedirectToAction("ConfirmOrder", "Orders", 
             new { orderId});

    //Otherwise errors, so copy over and redisplay
    foreach (var error in service.Errors)
    {
        ModelState.AddModelError("", error);
    }
    var listService = new CheckoutListService(_db, 
        HttpContext.Request.Cookies);
    return View(listService.GetCheckoutList());
}

I try to keep my Controller Actions small and simple by putting as much logic as possible into the Service Layer or lower layers. I do this because it is hard to test Controller actions, but much easier to Unit Test the Service Layer or lower layers.

Quick aside – handling errors needs thought.

This article is already quite long, so I won’t dwell on this subject, but providing good error feedback to the user is not trivial. Many libraries use Exceptions to report errors – some of these errors are user friendly, like Validation Errors. However, many Exceptions, such as EF’s DbUpdateException, are very unfriendly and sometimes produce messages that relate to the inner working for the application, and hence should not be shown for security reasons.

In this article I have implemented a very simple error feedback mechanism. In practice you would need to implement a much more comprehensive approach. I suggest you look at my open-source library, GenericServices, with uses ISuccessOrErrors<T> to return a result with possible error messages.

Conclusion

Writing CRUD (Create, Read, Update and Delete) methods used to take a lot of (boring) development writing boiler-plate code. I solved that by writing a library called GenericServices, which has radically improves the speed of development (see this site CRUD-only site, which I wrote in about 10 days).

I now find I spend most of my development effort on a) the Business Logic and b) building responsive user-interfaces. Therefore, continuing to improve my approach to Business Logic writing is well worth the effort, which is what this article is all about. (See a different article on how I am improving my building responsive user-interfaces too).

I recently reviewed an e-commerce application I developed which used the older approach to writing Business Logic, i.e. EF called in the Business Logic. The Business Logic was quite complex, especially around pricing and delivery. My conclusion was that the Business Logic work fine, but it was sometimes difficult to find and understand the database accesses when refactoring and performance tuning the Business Logic.

I tried out the new approach described in this article by refactoring some of the Business Logic in this e-commerce application over to the new approach. Overall it did make a difference by bring all the EF access code into one clear group per Business Logic case.

In additions I wrote an example application using ASP.NET Core and EF Core with this new approach, again with good results (this is where the example code comes from in this article). Couple this with the other positive feature of being able to test the Business Logic with a Mock DbAccess class rather than accessing EF directly and it is clearly a good step forward.

The only down side to this new approach is that does need one more class than the previous approach. However, that class does provide a much better separation of concerns. Therefore, I think this new approach is a positive improvement to my previous approach to building Business Logic and is worth the effort extra effort of another class.

I hope this article gives you some ideas on how to better design and build complex Business Logic in your applications.

Architecture of Business Layer working with Entity Framework

Jonathan Crosby asked a question on one of my GenericServices  GitHub projects about how to handle a Business Layer. I thought it was a good question so I have written an article to detail my approach to building business layers that use Entity Framework.

UPDATE 2016: See new, improved approach here

I have revisited this topic and refined my approach to Business Logic using EF. I suggest you read the new article called Architecture of Business Layer working with Entity Framework (Core and v6) – revisited.

UPDATE 2017: Book Entity Framework Core in Action

I have been commissioned my Manning Publishing to write the book Entity Framework Core in Action, in which chapter 4 is all about Business Logic in an Entity Framework Core environment (but the ideas are applicable to EF 6 too). 

This original article is old, but I have kept it because of all the comments.

What is the Business Layer?

GenericServices four layer designThe diagram on the left shows the type of layered application I normally build. This article is talking about the Business Layer (orange in diagram), which is called the “Domain Model” in Martin Fowler’s Service Layer diagram above.

The Business Layer is the place where all the business/domain logic, i.e. rules that are particular to the problem that the application has been built to handle, lives. This might be salary calculations, data analysis modelling, or workflow such as passing a order through different stages.

You can get a more in-depth coverage of the overall architecture in this  Simple-Talk article.

Aside: While having all the business rules in the Business Layer is something we should always strive for I find that in practice some issues go outside the Business Layer for good reasons. For instance validation of date often flows up to the Presentation Layer so that the user gets early feedback. It may also flow down to the database, which checks data written to the database, to ensure database integrity.Other business logic appears in the Presentation Layer, like not allowing users to buy unless they provide a credit card, but the status should be controlled by the Business Layer. Part of the skill is to decide whether what you are doing is justifiable or will come back and bite you later! I often get that wrong, but hopefully I learn from my mistakes.

My philosophy on the Business Layer

I have written numerous applications for predictive modelling of various healthcare issues, all of which have some quite complex business logic. Over the years I have tried different ways of organising these applications and I have come with one key philosophy – that the “The Business Layer is King“, i.e. its design and needs drives everything else.

I am a big fan of Domain-Driven Design (DDD) which has the same philosophy and provides some approaches to help keep the business logic at the forefront of any design. Here are some of the approaches from DDD that drive my designs.

1. The Business Layer defines the data structures

The problem we are trying to solve, often called the “Domain Model”, is the heart of the problem. These can be complex so the core data structures should be defined by, and solely focused on the business problem. How it is stored and how it is viewed are secondary issues.

2. The Business Layer should find persistence of data simple

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 almost an in-memory collection. Entity Framework really helps with this.

The architecture of my Business Layer

Based on the philosophy listed above the implementation I use has the following characteristics.

1. I use Adapters widely

As I said above the Business Layer is in control of the data structures – what makes the most sense for the Business Layer is what it does. This means it normally deals in data classes and/or entity keys (DDD term for the primary keys of data/entity classes).

This means the data needed/produced by the business logic is often not in the right format for communicating to the user and/or other external APIs. I therefore use Adapters, i.e. something that transforms the data to/from what the business logic. The Service Layer does this for the Business to Presentation layer communication while external services are adapted inside the Data Layer.

Further reading:

  • See Alistair Cockburn’s Hexagonal/Adapter-Port architecture . My applications are mainly in this style. I use Dependency Injection to link layers.
  • DDD call these anti-corruption layer – See Eric Evans’ talk on DDD in which he talks about different ways to adapt across Bounded Contexts (whole talk is great. Skip to 20mins in for part on linking bounded contexts).

2. The Business Layer uses EF directly

My early applications used the repository pattern and UnitOfWork pattern. However as EF has improved, and I have learnt more I have moved over to using EF directly in the Business Layer.

I found that the repository pattern in the end got in the way and made life much harder. Going for direct EF access allows the developer to access all the features of EF and stops some of the ranger tortuous approaches I used to use with repositories.

You can read more about this in my two blog posts:

  1. Is the Repository pattern useful with Entity Framework?
  2. Is the Repository pattern useful with Entity Framework? – part 2

3. The Business Layer does not do the final data save.

This is subtle, but I have found this very helpful. I don’t want the Business Layer to really know about saving data. I can’t totally ignore the data access code, in my case Entity Framework (EF), in the Business Layer, but I do minimise it.

Therefore Business Layer methods adds/inserts new data into the in-memory data classes or simply changes any loaded data from the database. However the Business Layer never calls EF’s SaveChanges. That is done in the Service Layer that called it.

Why do I find this useful? There are a number of reasons:

  • The Business Layer does not have to handle database validation errors, which can occur when ‘SaveChanges’ is called. The Service Layer does that, which has more information available to it on what is going on.
  • I know that all the data will be saved in one transaction. It is either there or its not.
  • If I need to chain multiple business methods I can use a transaction scope to rollback changes if one of the later methods fails.
  • The Service Layer can check other things to decide whether the data should be saved. I use this to allow users to save/not save on warnings.
  • It makes the Unit Testing of the Business Logic much easier as the database has not been changed. Most of my Business Logic has a property holding the data structures about to be written, so I can just check that.

Note: The discarding of data by not calling ‘SaveChanges’ only works in situation where each call has its own DbContext. This is the state in a web application as each HTTP request gets a new DbContext.

My implementation: GenericActions library

I have a library called GenericActions which has a very similar interface to the GenericServices library. Note: This isn’t an open-source library, but is part of my proprietary Rapid-Build™ library set that I use when building applications for clients.

Like GenericServices GenericActions can either work directly with the business class or more usually via a Data Transfer Object (DTO) – See Why DTO? in the GenericServices documentation for more on DTOs. It uses DI to pull in a Business Layer class, hence making sure the Business Class can pick up any services it needs through constructor injection.

A typical call of a business method at the MVC controller level looks very much like a GenericServices call.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SetupGrader(GraderDto dto,
            IActionService<IBizGraderSetup> service)
{
    if (!ModelState.IsValid)
        //model errors so return immediately
        return View(dto);

    var response = service.RunAction(dto);
    if (response.IsValid)
    {
        TempData["message"] = response.SuccessMessage;
        return RedirectToAction("Index");
    }

    //else errors, so copy the errors over to the ModelState and return to view
    response.CopyErrorsToModelState(ModelState, customerAddress);
    return View(customerAddress);
}

The main difference is the definition of the service (see line 4 above). The service contains the interface of the Business Layer class that contains the method it needs to call. DI is used to inject the right class into the service.

In the case above the action only returned a status to say if it was successful or not. However other Business Layer methods may need to return data, so there is another type of call that returns a class. This class can either be the class result produced by the business class or another DTO to do the conversion.

You can read about the way I implemented the GenericActions (and GenericServices) library in my new post, Using .NET Generics with a type derived at runtime.

Conclusions

Because GenericServices is focused on the database to/from Presentation Layer communication I have not described my view of the Business Layer. Hopefully this article fills in that gap by describing the ways and wherefores of the Business Layer in my  architectural view of applications.

Happy coding!

Is the Repository pattern useful with Entity Framework? – part 2

Quick Summary of Part 2
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:

  1. Part 1: Analysing whether Repository pattern useful with Entity Framework
  2. Part 2: Four months on – my solution to replacing the Repository pattern (this article).

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

After some trials it became clear that three parts of the application needed to interact with the database:
  1. 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.
  2. The WebApi or Web Service, which is similar to the User Interface but has less need for user selection from a list.
  3. The Business Layer which needs to hide some of the EF code and make the database feel like a searchable collection.
Realising that there were different parts was a breakthrough as I could now design different ways to interface to EF to meet the different requirements. I combined the UI and the WebApi as they are very similar and then provided a different approach for the business layer.

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:

(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 2017: 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.

  1. 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.
  2. 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.
  3. 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 ‘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:

  1. Read in any data it needs for the business logic.
  2. Some pure business logic working on the data classes – the bulk of the code.
  3. 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!