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?
The 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:
- Is the Repository pattern useful with Entity Framework?
- 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!
Sorry but i hardly disagree on the repository pattern. People get confused on its use over EF. While using Repo + uow + EF is of course non sense, using repo + EF is the way to go. Using Ef directly in the BLL goes against separation of concern as it induce tight coupling to a framework. Also, say you, one day, want to change your ORM (for performance concern, for example) using the repo pattern will alow you to do this easily without having to make lot of changes in your BLL.
Hi @Veillet Alexandre,
Thanks for your comment. While I understand where you are coming from my real-life experience has shown me that hiding all the EF inside a repository pattern is really hard to do well. That was what I was previously doing (see my two part article on that. The problem is that database accesses to get pretty complicated and the abstraction of a repository on top of the abstraction of EF I found really difficult to do well. It was so painful that taking the repositories away made my code so much better.
I realise I am locking myself into a specific ORM, EF, but again my experience is that once I start a project I rarely change the bigger libraries, which are in themselves an abstraction, I use as that is quite hard work. That means am fairly careful about choosing my key libraries at the start, but for a project taking less than say 1 year elapsed that I think is OK.
As for separation of concerns then, yep, I admit I sometimes I loose that. I try to use query objects as much as possible and I have a open-source library called GenericServices which hides the EF for many CRUD options. The other trick I use in my business logic is to place the EF access in a specific area of business code. That loads all the data and the rest of the business logic uses the classes directly as a in-memory set of classes (DDD style). This makes changing the EF code, say to improve performance, much easier as its all in one place.
I might sound a bit pragmatic but having used repositories a lot I know the pain there and using EF directly is, for me, a much better option. Clearly you do things differently and that’s fine. In the end a large part of programming today is picking the approach, libraries, patterns etc. that allow you to produce robust, well performing and adaptable applications in the most efficient way. We may differ in our approach but if we each achieve that goal then we are doing our job well.
That’s the thing people get confused the most about Repo + EF is not abstraction, it’s about isolation. UOW + REPO + EF would be an other layer of abstraction that would be unneeded of course. But from what you say you’re doing the isolation on the BLL layer which is exactly what i do thanks to REPO but i do it in the DAL layer where it should be since it “data” concern.
Yeah we don’t get to change ORM everyday so it’s not a big deal to not isolate it but to me the concern is to build different layer that are not tightly coupled which is, from my short experience, always overlooked by dev and architect which find themselve years later (in long term project) stuck on their architecture and previous choice and can’t upgrade their project at all.
For small project i have no problem going simple, but for professional development thinking about the future never hurts even if some principle (YAGNI) kinda go against thinking too beforehand, which i disagree with.
I never had much problem with Repositories in themselves, it’s merely a specialized Facade in the end. I know project can get messy over time but that’s the point to make your architecture as best as possible because not doing so will make the project even messier and faster … i had to deal with project where no structure was put in place and sql queries where directly made and mix with business code in the UI’s designer code so clearly that’s not great
Thanks for your comments. I think my attempts at Repos were an abstraction as well as Facade, as the repro hide how EF managed the data. The problem I had was its actually hard to hide EF as there are lots of little small things that get you. For instance updating a class requires for it to be tracked by EF and because EF is hidden you have to either check if it is tracked or use some EF magic to say its an update (which has problems). Believe me – it became hard work!
Good debate though!
mmm well that depends, I use POCO, and not DTO, which are my entities, so I can use them on every layer as they are also isolated in their own library. I have to agree that making DTOs in that data layer + POCOs in the other are quite the trouble and kind of unnecessary.
OK. I have a base project which every other project inherits that contains my POCO EF classes, but no DTOs. I mainly have DTOs in the service layer, where they may also use attributes/classes that are linked to my presentation layer, e.g. System.Web’s HtmlString. I also have DTOs in the Business Layer, but they are totally neutral of how that data is use and are not allowed to know anything about the layers above.
Hi Veillet,
I think I have finally come round to your view! I think my problem of understanding what you meant by the word ‘Repo’. ‘Repo’ to me is a big abstraction, but I see now that you see it only as a facade.
It took me building a whole e-commerce and then reviewing it to see your point of view! I have written a new article which uses a simple facade to isolate the EF code.
I like this new form a lot, and I think it is closer to what you were talking about.
Hi Jon Smith,
I have read the new article and indeed this go more on the same way that i do, although i still go a bit more further but mostly for the sake of it since it would probably fall in the YAGNI spirit. In that article, you said that EF entities are good enough for the bisuness layer, which is not false.
But, i think it doesn’t hurt to go beyond, why ? because it could come handy in some situation. What do i mean ? In DDD, it is adviced to separate your entities for each context, thus a User object in your business layer and a User in your Data layer aren’t/shouldn’t be the same. I give you that it’s a hassle to handle and i understand the need and choice to go the short way, especially if it’s possible (mostly on new project that have no legacy to support). But, in my short career again, i never saw one of those project where you didn’t have some old stuff to support which was poorly designed to begin with, and that is especially database … i have supported a database which model had been created more than 30 years ago now on principle that are, nowadays, outdated … and if i had been a bit more cultivated back when i had to do that. i would definetely have gone the way to have separate entities. Why is it good ? it is because you can design your business class purely on what they should look like. And then if the database you have to support already exist and has a strange model for a reason or an other, you can just use a mapper between the 2 layer, which is what i do, but the downside is that it is a big hassle to do so even with auto mappers anyway and you still have to handle EF behaviour for thing like update etc…. (since for example, you can’t just can’t create a new EF object and think it’ll update it, you have to load it from the db and update it the the information from the business object and then save it, which is heavy but bring more flexibility) but again it come in handy when your business object is represented by a single class and that for some reason, in the data layer your object is represented by 2 or more tables …
Anyway, i am glad i helped you change your view on some point, repositories are facade, and i see them as such.
Hi Veillet,
Thanks for your comments. I do take your point that when dealing with legacy systems the match between the database and the business logic may not be good. I have had the privilege on working new systems where this happens. However I have a new contract which involves access to an old database, albeit as a secondary source.
I will think about what you have said and see if I can update the new article to cover that.
Thanks again for you input.
Hi Veillet,
I have moved this conversation to the new article. see this comment.
Hi John,
I spent all my day to read your articles about Repository pattern vs. Generic service. As I was already in doubt using repository and UOW pattern in my project, your ideas make me convince a lot. Thank you.
There is something I couldn’t understand. Even you told about business layer here, I couldn’t see any code about it. The only code here is controller level and it calls directly service not business class. In addition, I checked your sample project “SampleMvcWebAppComplex”, but I couldn’t see business layer there as well. So I’m confused about relation between service and business layer and as if we can merge them into one layer.
Thanks in advance
Hi Serdar,
Sorry there isn’t much code there as I was trying to get over the concepts, which fit in with the idea of using EF directly. As I said I do have a library called GenericActions, but its not open-source for two reasons. Firstly it is a lot more complicated than GenericServices (see this article for some of the problems), which makes documentation and examples quite difficult. Secondly having it private means there is a good reason for clients to hire me, as it makes me faster!
You can read another article where I talk more about how to use EF’s DbContext in the business layer, which I think is a very important issue to resolve. My business methods are allowed full access to any and all EF methods apart from `.SaveChanges()` or `.SaveChangesAsync()`. Calling either of those methods is definitely done at the Service Layer level, in my case by GenericActions, which acts as a pseudo Service Layer.
I can say the GenericActions feels very similar to GenericServices to use. The big difference is that it calls a method rather than accessing the database, that is why in the example above you see `IActionService service`, with the IBizGraderSetup being an interface to a method.
Hi John,
Thanks for the article, really learning a lot from your articles. I am a newbie trying to decide Repository pattern vs EF. I was wondering if you have sample project for your GenericServices?
Thanks,
Felix.
Hi Felix,
Sure. I don’t think a library is any good without good documentations & samples so I produced two sample projects, both with live sites so you can see them in action. If you go to the GenericServices site on github and read the README file it has links to the live sites and the source of both. Do also got to the GenericService’s Wiki which has lots of information, including an overview of the architecture.
PS. If you haven’t found them yet there are two articles on my blog about this subject – see the first article. This first article covers my own research/deliberations on the subject. In the second article, which is linked at the top of the first article, I reflect on life after I had made the change to a non-repository pattern.
Hi Jon
Thanks for your insight on using EF directly vs repository pattern. You’re really added a new dimension on my study of MVC. I’m a newbie to MVC and am trying to design a robust and scalable backend architecture for a new project at work. I noticed that the examples given in your posts and in the sample codes are using Code-first EF (as are most examples online). I’m curious as to whether I can also apply the GenericServices architecture to DB-first EF as well, since this is the approach our team has chosen to adopt.
Thanks in advance.
Jasmine
Hi Jasmine,
Glad you liked the article on EF directly vs repository pattern. This was a big change for me, but my Data Layer coding is much cleaner because of it.
On your question on using Code First with an existing database then I have written two articles about this – see https://thereformedprogrammer.net/entity-framework-working-with-an-existing-database/ for part one which deals with importing an existing database schema. These articles are also available on Simple-Talk – see https://www.simple-talk.com/dotnet/.net-framework/using-entity-framework-with-an-existing-database-data-access/ (useful if you want a print-friendly version).
One thing on EF Code First that is worth pointing out is that Code First CAN work with existing databases. Some of the early EF code was called Database First, so they called the next version Code First. However that has caused confusion. Code First is the primary way to use EF now and has a Reverse Engineering feature built in that allows you to create Code First classes and DbContext from a existing database – see https://msdn.microsoft.com/en-us/data/jj200620
My articles mentioned above pull out some of subtle issues around Reverse Engineering that you and your team might find it useful. There is also an example application to go with the articles which can be found here https://github.com/JonPSmith/SampleMvcWebAppComplex with a live site at http://complex.samplemvcwebapp.net/ . This project uses GenericServices.
Jon
Thanks for the prompt reply.
Yes, I understand I can use “Code First” EF on an existing database via Reverse Engineering. But we already have some “stuff” built using “Database First” (i.e. EDMX). The reason why we prefer the “Database First” approach is that the database designer may not be part of the “coding” team, and we literally design the database (tables, views and stored procedures) first, before coding on top of the database. For us, stored procedures are a necessity, and we find it easier to “bring in” stored procedures into EF via “Database First” approach. I’m not sure if we’re able to do that via “Code First”.
My main concern right now is since the DbContext needs to inherit IGenericServicesDbContext, how should go about making use of GenericServices together with the DbContext that has been generated from the EDMX.
Thanks again!
Jasmine
Hi Jasmine
Ok, that makes sense. I haven’t used “Database First”/EDMX so I can’t give you a definitive answer. I see from the documentation that EDMX produces a DbContext. Obviously you don’t want to add the IGenericServicesDbContext to the generated code, but you could produce a partial class of the DbContext and add the interface to that. That is what I did in the SampleMvcWebAppComplex application.
The IGenericServicesDbContextis pretty basic, so I think it should work with any DbContext.
Jon
That sounds like a great idea! I’ll try it out and let you know if it works. 🙂
PS. Code First can use stored procedures now – it was added in EF 6. EF 6 adds lots of useful features which I mention my article.
I realise you don’t want to change, but I mention this for anyone else reading these comments.
Hi Jon.
Thank you some great articles. I completely agree with you on your point about the repository pattern and that it is better to use EF directly.
I have looked through the examples and documentation for GenericServices. I like your approach. I would really like to see the GenericActions library also. Any chance that you will make it public? Or is it possible to buy the source code?
As I understand you don’t mock the database but run unit tests against an actual database. That makes a lot of sense and it is also what Ayende and Jimmy Bogard recommends. Any tips on this approach? Do you use SQLLite?
Thanks in advance,
Anders
Hi Anders,
Thanks for your kind comments. Yes, contrasting my previous experience with using the repository pattern and now using EF directly it is much easier. However you do need to understand EF, but even with a repository pattern that was true anyway.
GenericActions isn’t public. I have a number of private libraries that make me more efficient on client projects – there needs to be some reason to make people want to pay for my services. Happy to collaborate with you on a paid project:)
GenericActions follows the same style as GenericServices, but is much more complex underneath because there are many more options when working with Business Logic. I am currently using GenericActions on a fairly complex web app which needs business logic to work. As always I am finding various ‘tweaks’ to make GenericActions more usable.
On the question of mocking the database I have made some progress since EF version 6 is out. There are a couple of EF articles (see https://msdn.microsoft.com/en-us/data/dn314429 and https://msdn.microsoft.com/en-us/data/dn314431). I have used this sometime when testing simple business logic, but not for anything complex. EF version 7 is said to have a fully implement memory database, which will be great for Unit Testing.
My approach is to use EF as the database, with the Unit Test App.Config pointing to a special Unit Test only database. I then either write my code so that it can work with a database that might have existing entries, or add a FixtureSetup method (I use NUnit) and wipe/reload the database when required. The main cost is the EF startup, which I haven’t found any way round.
Hi Jon.
Thanks for the thorough answer.
About commands/actions: I think I will try and implement them myself 🙂 I like Ayende’s approach where he has an ExecuteCommand method in the base controller: http://ayende.com/blog/154241/limit-your-abstractions-the-key-is-in-the-infrastructure. I also like his idea about property injection, which is explained here: http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/. What do you think about this approach?
About testing: I have also used testing against an external database before. And I might do that again. But I just read this blog post http://web-matters.blogspot.com/2014/09/unit-testing-entity-framework-with-effort.html?m=1 where the author recommends the tool called Effort (http://effort.codeplex.com/) “Effort is a powerful tool that enables a convenient way to create automated tests for Entity Framework based applications. It is basically an ADO.NET provider that executes all the data operations on a lightweight in-process main memory database instead of a traditional external database”. I think that it looks pretty interesting.
Thanks,
Anders
Hi Anders,
Thanks for your thoughts – they provoke me to think these things through more.
About commands/actions: I use an interface to set a common call method in my business logic. I need an interface anyway because I use contructor dependency injection (DI) very heavily in my business logic – that makes for great separation and easy testing. Ayendes specifically says he has removed any dependencies so his method works well for him.
On the property injection from Jeremy Skinner it is clear that you HAVE to use property injection on MVC filters because of there design. Otherwise I always try to use construction injection as it makes testing easier. My rule, read years ago, is: use DI in application, but never in Unit Tests.
On Effort – wow, what a find! Thanks for that. I haven’t tried it, but if it does relational fixup, i.e. keys are filled in
based on relationships, and vice versa, then it will be really helpful. When I have time I will look at it, but I have a few things stacked up at the moment. Note: EF 7 may change things here and have its own in-memory version, but Effort does look good as it is aimed at Unit Testing.
Jon
Yes, I agree that if you have many dependencies then Ayende’s design is less attractive. Do you inject the command interface in the controller action method like you do with your generic services? In that case how to decide what implementation of the interfaces that should be used in each case? Do you use the command handler pattern described here: https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91? The MediatR by Bogard also looks interesting: https://lostechies.com/jimmybogard/2014/12/17/mediatr-hits-1-0/. Or the Shortbus which MediatR is inspired by: https://github.com/mhinze/ShortBus
Yes, I inject the command interface into the controller action is the same way as GenericServices. I love this approach, which means only the instances needed for that specific action are created. See short explanation at the end of this page http://samplemvcwebapp.net/Posts/CodeView
The interface for the business logic is more complicated than GenericServices because
it has to include a reference to the Business Logic that must be run. For example a Controller action calling biz logic has the following pattern for the sync call:
public ActionResult SomeMvcAction(SomeInputDto dto, IActionService service)
The ISomeBizLogicInterface is linked to the specific business logic class that needs to be run. My GenericActions has a number of difference services interfaces, with options on whether there is an input and/or an output. The standard one takes and input class or Dto and returns a class look like this:
public interface ISomeBizLogicInterface: IGenericAction
{ }
If you read my other blog https://thereformedprogrammer.net/using-net-generics-with-a-type-derived-at-runtime/ I talk about ‘Getting rid of the ‘Ugly’ type definitions’. This means I do similar things to Generic services to decode the generic classes to make the signatures
as simple as possible for the developer. Having said that I don’t think the interface definition is that simple, but it’s the best I can get for dependency
injection to work properly.
I’ve read your articles about getting rid of repository pattern and I am very interested in this topic. I am a junior programmer trying to find my way of proper structuring backend of MVC app. Your approach (both with increasing criticism of using repository pattern with EF) seems the most interesting for me.
I’ve dug through SampleWebApp as well as the Complex version and from what I’ve learned I am about to use your GenericService in my app, but still have got one problem – actually I don’t see an easy way of linking business logic to your approach. Eventhough you have explained it in this post, it is still quite unclear form me how to use GenericService with business logic.
I understand that the library is a way to pass data from DataPersistance to Presentation. But how to deal with the business logic? In the layer picture of article linked above you mention a facade in the service layer. Am I right that the business layer (depending on specyfic usage) need to return DTOs compatible with GenericService as a result(of course if the call results in returning data). How to deal with business logic that returns no data but triggers some database operation – for example data processing thet results in adding new entities to the database, not necessarely posting anything to front ?
I would be grateful for brief description as there is not much about it over the Internet.
Hi Tomasz,
Your question is a good one and shows that I need to update this post to be a bit clearer. However I will give you a quick answer now as I am in a project and a full update will have to wait.
You have clearly grasped that I use a Service Layer to control access. Using a Service Layer is a common approach and I have found it, plus DTOs very useful. You might like to read my Simple Talk article that explains the structure a bit more – see https://www.simple-talk.com/dotnet/asp.net/using-entity-framework-with-an-existing-database–user-interface/
In my applications if the Presentation Layer needs a simple data access, often called CRUD actions, then it talks to my GenericServices library, with optional DTOs held in the Service Layer. If the Presentation Layer needs to do more complex actions, like say changing the status of an order based on some business logic, then it talks to my GenericActions library, again with optional DTOs held in the Service Layer. Both of these library are aimed at making the Service Layer much simpler to write.
The GenericActions library is private so I can’t show you how it works in detail. However it has a very similar interface to GenericServices, with DTOs etc, but it calls a business method, not a data access method. This means that the Presentation Layer uses identical logic for accessing the data directly (via GenericServices) or the Business Logic (via GenericActions). The only difference is the interface signature. That makes my life a lot simpler when developing applications.
Your last question shows you have thought this through, which is good. Yes, some Business Logic, say changing a status in the database, just returns a success/fail response. On the other hand some of my Business Logic might just be a ‘clever’ data access method which includes business logic that the Data Layer does not know about, which means it then returns data for the Presentation Layer to show.
Finally I would recommend a book which I found really useful on getting my head around the best architectural style for applications. It is a bit old and some of the libraries it uses are no longer the latest, but I think it gives a good overview of how to approach things. The free Ebook by Andrea Saltarello and Dino Esposito can be found here http://www.battleit.ee/public/Books/MSFT/Microsoft%20dotNET%20-%20Architecting%20Applications%20for%20the%20Enterprise.pdf
Thank you for your response. You confirmed my thgoughts about how it can be done. I am going to implement your approach in my app 😉