I have an MVC project that I exclusively employ a custom "Unit Of Work" pattern that uses NHibernate on the back end, which I expose to my application as IUnitOfWork and IUnitOfWorkFactory interfaces; These interfaces are injected as my NHibernate implementations via Ninject.
I use my UOW in a modified "session per request" style... I explicitly generate my IUnitOfWork from my injected IUnitOfWorkFactory when I need to perform database operations; it seems much easier to keep the CRUD where it belongs (out of my views and controllers) and effectively prevents accidental N+1 coding issues. Of course, it's a little harder to implement, but to date, I've been pretty happy with it.
Now I want to implement a WebAPI presenting IQueryable<Entity>-style REST calls, and my UOW pattern isn't digging it. The Queryables invariably blow up, attempting to invoke a disposed NHibernate session.
I've read some stuff online about how to implement a DelegatingHandler to manage the session for a WebAPI call... but I see several problems:
It seems that all the examples are assuming a "Session per Request" pattern... which is by far the most popular pattern, but not exactly one which I am using, so I'm not sure that is even the proper direction to go.
It's not clear how I can implement this handler exclusively for these Web API calls.
I've seen a lot of suggestions to use a "Session per Conversation" pattern which is potentially even longer-lived than the "Session per Request" pattern... it sounds like it might be appropriate for this endeavor, but the documentation on how to implement it is a little sparse.
All the sample implementations I've seen pretty much tightly couple the NHibernate ISession to the web application, using a built-in NHibernate mechanism (CurrentSessionContext.Bind(ISession)); I'd much rather reference my IUnitOfWork interface, and trust it to maintain the session it needs to.
So my question is, how can I implement a IQueryable<Entity> RESTful API using my own IUnitOfWork interface going against loosely-coupled NHibernate back-end?
You would face the same problem with a straightforward session-per-request implementation. For example:
// GET api/companies
public IQueryable<Company> GetCompanies()
{
return _session.Query<Company>();
}
I usually wrap all database operations, including selects, in a transaction but because query execution is deferred I can't do it in this method. It is possible to do so by creating an ActionFilter and overriding OnActionExecuted but the difficulty is gaining a reference to the ISession or your IUnitOfWork implementation in the filter. There are examples of how to accomplish this using Ninject and other dependency injection frameworks on the web.
Personally I don't see the value of abstracting the ISession, especially in Web API where it would be very rare to have a resource that did not perform a database operation. Session-per-conversation is definitely not a good pattern for this; it generally refers to keeping a session open over multiple server round trips.
My preferred architecture is to use Ninject to manage ISessionFactory and ISession lifetime (singleton and per-request, respectively) and to inject the ISession into the Api controllers. But you could also inject it into a repository or unit of work implementation.
Related
I'm working on my first Blazor Server project and I am slowly fixing a lot of initial design errors that I made when I started out. I've been using C# for a while, but I'm new to web development, new to ASP.Net, new to Blazor, and new to web architecture standards, hence why I made so many mistakes early on when I didn't have a strong understanding of how best to implement my project in a way that promotes clean code and long term maintainability.
I've recently restructured my solution so that it follows the "Clean Architecture" outlined in this Microsoft documentation. I now have the following projects, which aim to mirror those described in the document:
CoreWebApp: A Blazor project, pages and components live here.
Core: A Class Library project, the domain model, interfaces, business logic, etc, live here.
Infrastructure: Anything to do with having EF Core access the underlying database lives here, ie ApplicationDbContext, any implementations of Repositories, etc.
I am at a point where I want to move existing implementations of the repository pattern into the Infrastructure project. This will allow me to decouple the Core project from the Infrastructure project by utilising the Dependency Injection system so that any business logic that uses the repositories depends only on the interfaces to those repositories (as defined in Core) and not the actual implementations themselves (to be defined in Infrastructure).
Both the Microsoft documentation linked above, and this video by CodeWrinkles on YouTube make the following two suggestions on how to correctly use DbContext in a Blazor Server project (I'll talk specifically about using DbContext in the context of a repository):
Scope usage of a repository to each individual database request. Basically every time you need the repository you instantiate a new instance, do what needs to be done, and as soon as the use of the repo goes out of scope it is automatically disposed. This is the shortest lived scope for the underlying DbContext and helps to prevent concurrency issues, but also forgoes the benefits of change tracking.
Scope the usage of a repository to the lifecycle of a component. Basically you create an instance of a repository in OnInitialisedAsync, and destroy the repository in the Dispose() method of the component. This allows usage of EF Cores change tracking.
The problem with these two approaches is that they don't allow for use of the DI system, in both cases the repository must be new'd and thus the coupling between Core and Infrastructure remains unbroken.
The one thing that I can't seem to understand is why case 2 can't be achieved by declaring the repository as a Transient service in Program.cs. (I suppose case 1 could also be achieved, you'd just hide spinning up a new DbContext on every access to the repository within the methods it exposes). In both the Microsoft documentation and the CodeWrinkles video they seem to lean pretty heavily on this wording for why the Transient scope isn't well aligned with DbContext:
Transient results in a new instance per request; but as components can be long-lived, this results in a longer-lived context than may be intended.
It seems counterintuitive to make this statement, and then provide a solution to the DbContext lifetime problem that will enable a lifetime that will align with the stated problem.
Scoping a repository to the lifetime of a component seems, to me, to be exactly the same as injecting a Transient instance of a repository as a service. When the component is created a new instance of the service is created, when the user navigates away from the page this instance is destroyed. If the user comes back to the page another instance is created and it will be different to the previous instance due to the nature of Transient services.
What I'd like to know is if there is any reason why I shouldn't create my repositories as Transient services? Is there some deeper aspect to the problem that I've missed? Or is the information that has been provided trying to lead me into not being able to take advantage of the DI system for no apparent reason? Any discussion on this is greatly appreciated!
It's a complex issue. With no silver bullet solution. Basically, you can't have you cake and eat it.
You either use EF as an [ORM] Object Request Mapper or you let EF manage your complex objects and in the process surrender your "Clean Design" architecture.
In a Clean Design solution, you map data classes to tables or views. Each transaction uses a "unit of work" Db Context obtained from a DBContextFactory. You only enable tracking on Create/Update/Delete transactions.
An order is a good example.
A Clean Design solution has data classes for the order and order items. A composite order object in the Core domain is built by make two queries into the data pipeline. One item query to get the order and one list query to get the order items associated with that order.
EF lets you build a data class which includes both the order data and a list of order items. You can open that data class in a DbContext, "process" that order by making changes and then call "SaveAsync" to save it back to the database. EF does all the complex stuff in building the queries and tracking the changes. It also holds the DbContext open for a long period.
Using EF to manage your complex objects closely couples your application domain with your infrastructure domain. Your application is welded to EF and the data stores it supports. It's why you will see some authors asserting that implementing the Repository Pattern with EF is an anti-pattern.
Taking the Order example above, you normally use a Scoped DI View Service to hold and manage the Order data. Your Order Form (Component) injects the service, calls an async get method to populate the service with the current data and displays it. You will almost certainly only ever have one Order open in an SPA. The data lives in the view service not the UI front end.
You can use transient services, but you must ensure they:
Don't use DBContexts
Don't implement IDisposable
Why? The DI container retains a reference to any Transient service it creates that implements IDisposable - it needs to make sure the service is disposed. However, it only disposes that service when the container itself is disposed. You build up redundant instances until the SPA closes down.
There are some situations where the Scoped service is too broad, but the Transient option isn't applicable such as a service that implements IDisposable. Using OwningComponentBase can help you solve that problem, but it can introduce a new set of problems.
If you want to see a working Clean Design Repository pattern example there's an article here - https://www.codeproject.com/Articles/5350000/A-Different-Repository-Pattern-Implementation - with a repo.
Maybe this question has some explanation around but could not find the best solution to this:
I was reading this blog post from Mark Seemann about the captive dependencies and as far as I understand at the end of the post he comes to conclusion never use or at least try to avoid the captive dependencies otherwise there will be troubles (so far is OK). Here is another post from Autofac documentation.
They suggest using captive dependencies only by purpose (when you know what you are doing!). This made me think about a situation I have on my website. I have like 10 services, all of them rely on DbContext for database operations. I think they could easily be registered as InstancePerLifetimeScope if I fix the problem for DbContext not to hold it forever in memory attached to my services. (I am using Autofac in my case). So, I thought a good starting point would be to create all of these as per lifetime instances and the DbContext as instance per request. Then in my services, I would use something like that:
public class MyService
{
private readonly IDbContext _dbContext = DependencyResolver.Current.GetService<IDbContext>();
private MyModel GetMyModel() => Mapper.Map<MyModel>(_dbContext.MyTable.FirstOrDefault());
}
And then in my startup class I have:
builder.RegisterType<ApplicationDbContext>().As<IDbContext>().InstancePerRequest();
builder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
Does this pattern work correctly, I mean not keeping the dbContext forever attached to any service, so it will be disposed at the end of the request and if it works, is there any performance issue from this line:
private readonly IDbContext _dbContext = DependencyResolver.Current.GetService<IDbContext>();
compared to constructor injection(There are many invocations from dbContext to database so I am afraid to get IDbContext every time I want to use it because it might be resource consuming) ?
The reason I want dbContext to be instance per request and not instance per dependency is that I have implemented the unit of work pattern on top of the dbContext object.
A normal method in my controller would look like:
public ActionResult DoSth()
{
using(var unitOfWork = UnitOfWorkManager.NewUnitOfWork())
{
//do stuff
try
{
unitOfWork.Commit();
return View();
}
catch(Exception e)
{
unitOfWork.RollBack();
LoggerService.Log(e);
return View();
}
}
}
If this works fine then there is another issue I am concerned of. So, if I can make my services as instances per lifetime (except DbContext), is there any issue to apply async-await on every method inside of the services to make them non-blocking methods. I am asking this if there is any issue using async-await for the dbContext instance, so, for example, I would have something like this:
public async MyModel GetMyModel()
{
var result = //await on a new task which will use dbcontext instance here
return Mapper.Map<MyModel>(result);
}
Any advice or suggestion is much appreciated!
I'd approach the issue from a distance.
There are some architectural choices which can make your life easier. In web development it's practical to design your application to have stateless service layer (all the state is persisted in DB) and to fit the one HTTP request, one business operation principle (in other words one service method for one controller action).
I don't know how your architecture looks (there's not enough info in your post to determine) but chances are it meets the criteria I described above.
In this case it's easy to decide which component lifetime to choose: DbContext and service classes can be transient (InstancePerDependency in terminology of Autofac) or per request (InstancePerRequest) - it doesn't really matter. The point is that they have the same lifetime so the problem of captive dependencies doesn't arise at all.
Further implications of the above:
You can just use ctor injection in your service classes without worries. (Anyway, service locator pattern would be the last option after investigating lifetime control possibilities like lifetime scopes and IOwned<T>.)
EF itself implements the unit of work pattern via SaveChanges which is suitable most of the cases. Practically, you only need to implement an UoW over EF if its transaction handling doesn't meet your needs for some reason. These are rather special cases.
[...] is there any issue to apply async-await on every method inside of the
services to make them non-blocking methods.
If you apply the async-await pattern consistently (I mean all async operations are awaited) straight up to your controller actions (returning Task<ActionResult> instead of ActionResult), there'll be no issues. (However, keep in mind that in ASP.NET MVC 5 async support is not complete - async child actions are not supported.)
The answer, as always, is it depends... This configuration can work if:
Your scopes are created within the request boundary. Is your unit of work creating a scope?
You don't resolve any of your InstancePerLifetimeScope services before creating your scope. Otherwise they potentially live longer than they should if you create multiple scopes within the request.
I personally would just recommend making anything that depends on DbContext (either directly or indirectly) InstancePerRequest. Transient would work as well. You definitely want everything within one unit of work to be using the same DbContext. Otherwise, with Entity Framework's first level cache, you may have different services retrieving the same database record, but operating on different in-memory copies if they're not using the same DbContext. Last update would win in that case.
I would not reference your container in MyService, just constructor inject it. Container references in your domain or business logic should be used sparingly and only as a last resort.
Every example of the Repository Pattern I have seen deals with a very simple use case - one object type and the most basic CRUD operations. The Repository is then very often plugged straight into an MVC controller.
Real-world data access just isn't like this. Real-world data access scenarios can involve complex graphs of objects and some form of transactional wrapper. For example, suppose I want to save a new Order. This involves writing to the Order, OrderDetails, Invoice, User, History and ItemStock tables. All of this must be transacted, committed or rolled back. Normally I'd pass around something like an IDbTransaction and an IDbConnection and bundles the whole operation in a service layer.
Where does the Repository Pattern fit with this? Am I missing something (Unit Of Work perhaps)? Are there any more realistic examples of Repositories in use than the usual canned blog snippets?
Appreciate any light.
This is a very controversial subject but here is my catch from my own experience.
Repository works at the aggregate root. For example if an OrderItem is always retrieved as part of Order and does not have a life of its own outside order, then it will be loaded by the OrderRepository, otherwise it will have its own repository.
UnitOfWork is an important concept. Let's say OrderItem is an aggregate root and has its own repository. So at the time of creating an order, OrderManager will create a UnitOfWork of work in a using block, initialise OrderItemRepository and OrderRepository and then commit.
UPDATE
Yes, exactly. Imagine - in our case order - an order is being inserted. This needs to be in control of the transaction and enter order and order items separately inside the same transaction. This cannot be managed at the repository level. This is the sole reason for existence of UnitOfWork concept which is passed to the repository so that it does not own or initialise it. UnitOfWork usually is created at the business layer.
O/R-Mappers like Hibernate basically implement the Repository pattern for object graphs while fully supporting transactions. It's often a leaky abstraction, but it certainly can be made to work in complex real-world scenarios.
If you need a good full blown, widely used expample of the repository pattern look at Cocoa's Core Data I realize it is not in the realm of programming languages that you note. But note that it is NOT an O/R mapper. It is a complete abstraction of an object store. No Sql statements to execute, and while you may pick the format of the external storage that is used, you never interact with it directly.
I like to think of a repository as another layer of abstraction. You should only add layers of abstraction when the cost of their implementation is less than the cost of NOT doing the implementation (code maintenance, support, enhancements, etc).
Remember that the purpose of the repository pattern is to separate the logic that retrieves the data (CRUD) and maps it to the entity model from the business logic that acts on the model. What this often ends up doing/looking like in the real world is some form of business entities, that abstract the underlying physical data model.
As far as your transaction question, yes, this relates more to the Unit of Work pattern. Since you mentioned services, I would encourage you to NOT pass around your connection to your various data access classes/methods, but to instead allow WCF to manage the transaction for you using auto enlistment. Here is an extract of Juval Lowy's WCF book (highly recommended) that explains the how and why of this method of transaction management.
So to answer your question, the repository pattern fits in as a way to abstract the physical data model and to separate the CRUD/mapping from the business logic.
This is more of a question where I am looking for opinions. I am working on a project that uses both NHibernate and EntityFramework (this is by design, wanted flexibility). So, I went ahead and started working on a Repository pattern, but came across a slight dilemma.
Basically, I wanted to know what you guys think about the following areas:
Should the Repository be a singleton? - This will allow me to keep the sessions opened, but at the same time, I think it's going to keep connections opened to the database. For NHibernate, the ORM can only gurantee an objet is the same within the same session. This is ideal for easy coding, but there are definatly ways to overcome this using keys and overriding the GetHashCode and Equals methods.
If it's not a singleton (or even if it is), should I be closing the connections as soon as they are used? For NHibernate, that means closing the session each time the Repository is "Disposed", which is after every use.
Have you implemented a Repository pattern for either NHibernate or EF 4.0 and found any useful ideas?
Don't code the creation of singletons yourself (ie the singleton pattern itself), use an IOC framework like StructureMap to handle the Lifecycle management of objects.
This we can't answer. If it's singleton it must be thread safe in regards to the resources it manages internally (like a connection pool of DB live connections). Threadsafe code isn't trivial.
This we can't answer. It depends on how you act with your model. It also depends whether you want people to be able to read through a DataReader which requires an active connection to the database. This also affects things like lazy loading which requires active sessions which becomes a nightmare with databinding.
Here's everything I've come up with in regards to creating a repository pattern for NH: Creating a common generic and extensible NHiberate Repository version 2
First question, does it have to be NHibernate? Why not take a look at using EF4 with an IoC, my favorite is StructureMap, then you non longer have to worry about making your repository singleton as StructureMap gives options to keep the scope open by request, by HttpContext, by Hybrid. You of course have the option to use the Singleton pattern with your Repository I'm just not sold on it being a viable option in a case like this.
Hope that helps more than it confuses you.
I'm implementing a DAL using entity framework. On our application, we have three layers (DAL, business layer and presentation). This is a web app. When we began implementing the DAL, our team thought that DAL should have classes whose methods receive a ObjectContext given by services on the business layer and operate over it. The rationale behind this decision is that different ObjectContexts see diferent DB states, so some operations can be rejected due to problems with foreign keys match and other inconsistencies.
We noticed that generating and propagating an object context from the services layer generates high coupling between layers. Therefore we decided to use DTOs mapped by Automapper (not unmanaged entities or self-tracking entities arguing high coupling, exposing entities to upper layers and low efficiency) and UnitOfWork. So, here are my questions:
Is this the correct approach to design a web application's DAL? Why?
If you answered "yes" to 1., how is this to be reconciled the concept of DTO with the UnitOfWork patterns?
If you answered "no" to 1., which could be a correct approach to design a DAL for a Web application?
Please, if possible give bibliography supporting your answer.
About the current design:
The application has been planned to be developed on three layers: Presentation, business and DAL. Business layer has both facades and services
There is an interface called ITransaction (with only two methods to dispose and save changes) only visible at services. To manage a transaction, there is a class Transaction extending a ObjectContext and ITransaction. We've designed this having in mind that at business layer we do not want other ObjectContext methods to be accessible.
On the DAL, we created an abstract repository using two generic types (one for the entity and the other for its associated DTO). This repository has CRUD methods implemented in a generic way and two generic methods to map the DTOs and entities of the generic repository with AutoMapper. The abstract repository constructor takes an ITransaction as argument and it expects the ITransaction to be an ObjectContext in order to assign it to its proctected ObjectContext property.
The concrete repositories should only receive and return .net types and DTOs.
We now are facing this problem: the generic method to create does not generate a temporal or a persistent id for the attached entities (until we use SaveChanges(), therefore breaking the transactionality we want); this implies that service methods cannot use it to associate DTOs in the BL)
There are a number of things going on here...The assumption I'll make is that you're using a 3-Tier architecture. That said, I'm unclear on a few design decisions you've made and what the motivations were behind making them. In general, I would say that your ObjectContext should not be passed around in your classes. There should be some sort of manager or repository class which handles the connection management. This solves your DB state management issue. I find that a Repository pattern works really well here. From there, you should be able to implement the unit of work pattern fairly easily since your connection management will be handled in one place. Given what I know about your architecture, I would say that you should be using a POCO strategy. Using POCOs does not tightly couple you to any ORM provider. The advantage is that your POCOs will be able to interact with your ObjectContext (probably via Repository of some sort) and this will give you visibility into change tracking. Again, from there you will be able to implement the Unit of Work (transaction) pattern to give you full control over how your business transaction should behave. I find this is an incredibly useful article for explaining how all this fits together. The code is buggy but accurately illustrates best practices for the type of architecture you're describing: Repository, Specification and Unit of Work Implementation
The short version of my answer to question number 1 is "no". The above link provides what I believe to be a better approach for you.
I always believed that code can explain things better than worlds for programmers. And this is especially true for this topic. Thats why I suggest you to look at the great sample application in witch all consepts you expecting are implemented.
Project is called Sharp Architecture, it is centered around MVC and NHibernate, but you can use the same approaches just replacing NHibernate parts with EF ones when you need them. The purpose of this project is to provide an application template with all community best practices for building web applications.
It covers all common and most of the uncommon topics when using ORM's, managing transactions, managing dependencies with IoC containers, use of DTOs, etc.
And here is a sample application.
I insist on reading and trying this, it will be a real trasure for you like it was for me.
You should take a look what dependency injection and inversion of control in general means. That would provide ability to control life cycle of ObjectContext "from outside". You could ensure that only 1 instance of object context is used for every http request. To avoid managing dependencies manually, I would recommend using StructureMap as a container.
Another useful (but quite tricky and hard to do it right) technique is abstraction of persistence. Instead of using ObjectContext directly, You would use so called Repository which is responsible to provide collection like API for Your data store. This provides useful seam which You can use to switch underlying data storing mechanism or to mock out persistence completely for tests.
As Jason suggested already - You should also use POCO`s (plain old clr objects). Despite that there would still be implicit coupling with entity framework You should be aware of, it's much better than using generated classes.
Things You might not find elsewhere fast enough:
Try to avoid usage of unit of work. Your model should define transactional boundaries.
Try to avoid usage of generic repositories (do note point about IQueryable too).
It's not mandatory to spam Your code with repository pattern name.
Also, You might enjoy reading about domain driven design. It helps to deal with complex business logic and gives great guidelines to makes code less procedural, more object oriented.
I'll focus on your current issues: To be honest, I don't think you should be passing around your ObjectContext. I think that is going to lead to problems. I'm assuming that a controller or a business service will be passing the ObjectContext/ITransaction to the Repository. How will you ensure that your ObjectContext is disposed of properly down stream? What happens when you use nested transactions? What manages the rollbacks, for transactions down stream?
I think your best bet lies in putting some more definition around how you expect to manage transactions in your architecture. Using TransactionScope in your controller/service is a good start since the ObjectContext respects it. Of course you may need to take into account that controllers/services may make calls to other controllers/services which have transactions in them. In order to allow for scenarios where you want full control over your business transactions and the subsequent database calls, you'll need to create some sort of TransactionManager class which enlists, and generally manages transactions up and down your stack. I've found that NCommon does an extraordinary job at both abstracting and managing transactions. Take a look at UnitOfWorkScope and TransactionManager classes in there. Although I disagree with NCommon's approach of forcing the Repository to rely on the UnitOfWork, that could easily be refactored out if you wanted.
As far as your persistantID issue goes, check this out