I'm refactoring an existing MVC.Net application to include the unit of work pattern to make data management a bit more obvious and straight forward.
The application is currently split into
Presentation/UI (MVC Controllers delivering views OR JsonResults for AngularJS)
Business Logic (Containing well... business logic)
DAL (Repositories and EF)
I'm having a hard time trying to figure out how I need to be structuring dependency injection and UoW passing to keep things sensible and testable.
I'm anticipating something like the following to be an example:
public class SomeMVCController : Controller
{
private readonly IStoreFrontLogic _storeFrontLogic;
public SomeMVCController(IStoreFrontLogic storeFrontLogic)
{
_storeFrontLogic = storeFrontLogic;
var uow = new UnitOfWork(User);
_storeFrontLogic.UnitOfWork = uow;
}
public ActionResult SomeRequest()
{
var myViewModel = _storeFrontLogic.OffersForUser();
return View(myViewModel);
}
}
public class StoreFrontLogic : IStoreFrontLogic
{
public UnitOfWork unitOfWork;
public OffersModel OffersForUser()
{
//some logic taking into account the current user in the uow
var prevOrders = unitOfWork.OrdersRepo.GetUsersOrders();
// special offers logic
return specialOffers;
}
}
Does this seem sensible?
I'm not too keen on the requirement to manually push the uow into my logic classes whenever they're required. Is there a more sensible way?
As I said above, this is hard to answer without a specific question or specific domain model but I'll give it a shot.
My understanding of such things is focused pretty heavily through a Domain Driven Design lens.
First of, you should read this series of papers on effective aggregate design. The fact that you need units of work and to do queries from inside your domain classes implies that your model needs work.
Some other thoughts on UOW - having uow produce your repositories is good, but I think you will likely start hitting lots of difficulties with implementation. UoW is super useful in small targeted areas but is very difficult to implement across an entire application. What for example happens when you save? Can you never use EF directly? Is everything thread safe? You might want to simplify what you are trying to achieve.
In your example uow can be scoped to the HttpRequest. Many IoC containers (eg Structuremap) provide a simple way to configure this. You can then have a post-action filter (or even better an OWIN module) to attempt the commit (what happens if there are errors is yet another implementation difficulty to deal with). This will eliminate a lot of the property-assignment nonsense
I'm not sure what type of object is your StoreFrontLogic. It doesn't seem like a domain entity but it contains significant business logic. It could be something similar to a transaction script, but in that case the uow should be fully internal to it.
Is it a stateless service? In that case everything that method uses - orders for user included - should be passed in via a parameter.
If, on the other hand it's an entity then it shouldn't access the database at all, it should already have all orders for the user. Purposeful database denormalization can help quite a bit here.
At the very least pass uow as a parameter to OffersForUser rather than expecting for a property to be set.
Related
Im new in MVC pattern but im involved in a project which i am asked to implement repository pattern and unit of work,tons of examples online with 100 different implementations thats also a pain,because there is no clear way,any way,here is what i am doing and i would like you to give me a reason why should i use this damn pattern:
i have many controllers i instantiate the the model,and use it in my controller:
public CentralEntities DB = new CentralEntities();
i use it in my controller for example like this:
var turbineid = (from s in DB.MasterDatas
where s.name == turbinename
select new TrBineId
{
turbineID = s.m_turbine_id
}).Single();
TrBineId is my viewModel,any way the number of controllers are increasing and also in each controller i have many different LINQ,should i start with generic repository?
The damn reason to use repository pattern lies in implementing your solution with a clear separation of concerns and leverage domain I/O in a way that can be reused across your codebase.
You should start to revisit OOP and you'll need to double-check repository pattern.
At the end of the day, the need for certain patterns is already there, but it'll arise in your mind once you put the pieces in order.
I would start following some tutorial around the net about repository pattern to implement a proof-of-concept project and realize how it works.
Finally, Inversion of Control and Dependency Injection are concepts you'll need to manage to integrate your repositories and other patterns in your project to increase code composability and testability.
DISCLAMER: The following links are from my website about software architecture. You might want to check them as a possible reference implementation of repository pattern:
Repository
Agnostic repository
The repository pattern allows you to use the concept of Single responsibility principle, which mean (as an overview) one class = one role.
Your controler class is here for managing the request (Get, Post) and send back a response (FileResult, ActionResult...).
For the Data access (DAL, DAO) you will usually create a class per model entity (ClientRepository, CommandRepository), and you will create your methods for getting them (GetClients(), GetOneClientById(int id)...) within this class.
Edit for clarification after MatÃas comment:
This class will be called in your controller through his interface that you will also implement (with IOC or not).
You will then create a class instance of ClientRepository in your controller, but assigned to a reference of the interface type (IClientRepository).
**End Edit **
So we can imagin for Client Entity:
ClientController(All route for clients data)
IClientRepository (interface)
ClientRepository (Class which implement IClientRepository )
Then, in your controller you will call the repository like
IClientRepository clientRepo = new ClientRepository();
And then use the methods:
ICollection<Client> clients = clientRepo.YourMethod(int param1);
Advantages:
First of all, your code will be more clear and maintainable. Your DAO (DAL in .net) will keep the data access layer and you could use the GetAllClients method many time and you will not repeat yourself (DRY).
You can also apply easily some param on the method (like order, limit for pagination etc...)
It will be testable as well, I don't think that calling database in the controller can give you reasonable unit test results. You will also catch excption with a more "elegant way".
Small tip : When you will have more experience in the repo pattern, you could have a look at the Inversion of Control pattern
I am trying to figure out how to correctly implement UoW and Repository pattern with Entity Framework. I saw a lot of post against it but it still seems like the right way to go.
I am trying to do it according to this blog post. The last thing I am trying to figure out is how to inject the Repositories into the UoW but in a way that lets me do it on demand. The number of repositories may grow and so will the constructor then. Furthermore instantiating all of the repositories for an operation that may require only 1 or 2 seems like a waste of resources.
How do I do it in a way that lets me write unit tests fairly easily?
The only way I found out, that lets me inject repositories NOT in the constructor (so they are not all instantiated, even when they are not needed for a particular operation) is by doing it in the getter:
private IGenericRepository<Blog> _blogRepository;
private IGenericRepository<Post> _postRepository;
public UnitOfWork(BloggingContext bloggingContext)
{
_bloggingContext = bloggingContext;
}
public IGenericRepository<Blog> BlogRepository
{
get
{
return _blogRepository = _blogRepository ?? new GenericRepository<Blog>(_bloggingContext);
}
}
However, this approach generates a lot of noise in the code because when I will have 50 repositories I will need 50 props.
You might want to combine the described approach (which I like) with the generic repository approach described here https://cpratt.co/truly-generic-repository/
Given proper implementation of the UoW pattern from the blog post you reference, you won't need the anything but the IReadOnlyRepository from the article - it will provide everything you need for the repository to be.
Currently we have implemented a repository pattern at work. All our repositories sit behind their own interfaces and are mapped via Ninject. Our project is quite large and there are a couple quirks with this pattern I'm trying to solve.
First, there are some controllers where we need upwards of 10 to 15 repositories all in the same controller. The constructor gets rather ugly when asking for so many repositories. The second quirk reveals itself after you call methods on multiple repositories. After doing work with multiple repositories we need to call the SaveChanges method, but which repository should we call it on? Every repository has one. All repositories have the same instance of the Entity Framework data context injected so picking any random repository to call save on will work. It just seems so messy.
I looked up the "Unit Of Work" pattern and came up with a solution that I think solves both problems, but I'm not 100% confident in this solution. I created a class called DataBucket.
// Slimmed down for readability
public class DataBucket
{
private DataContext _dataContext;
public IReportsRepository ReportRepository { get; set; }
public IEmployeeRepository EmployeeRepository { get; set; }
public IDashboardRepository DashboardRepository { get; set; }
public DataBucket(DataContext dataContext,
IReportsRepository reportsRepository,
IEmployeeRepository employeeRepository,
IDashboardRepository dashboardRepository)
{
_dataContext = dataContext;
this.ReportRepository = reportsRepository;
this.EmployeeRepository = employeeRepository;
this.DashboardRepository = dashboardRepository;
}
public void SaveChanges()
{
_dataContext.SaveChanges();
}
}
This appears to solve both issues. There is now only one SaveChanges method on the data bucket itself and you only inject one object, the data bucket. You then access all the repositories as properties. The data bucket would be a little messy looking since it would be accepting ALL (easily 50 or more) of our repositories in its constructor.
The process of adding a new repository would now include: creating the interface, creating the repository, mapping the interface and repository in Ninject, and adding a property to the data bucket and populating it.
I did think of an alternative to this that would eliminate a step from above.
public class DataBucket
{
private DataContext _dataContext;
public IReportsRepository ReportRepository { get; set; }
public IEmployeeRepository EmployeeRepository { get; set; }
public IDashboardRepository DashboardRepository { get; set; }
public DataBucket(DataContext dataContext)
{
_dataContext = dataContext;
this.ReportRepository = new ReportsRepository(dataContext);
this.EmployeeRepository = new EmployeeRepository(dataContext);
this.DashboardRepository = new DashboardRepository(dataContext);
}
public void SaveChanges()
{
_dataContext.SaveChanges();
}
}
This one pretty much eliminates all the repository mappings in Ninject because they are all instantiated in the data bucket. So now the steps to adding a new repository include: Create interface, create repository, add property to data bucket and instantiate.
Can you see any flaws with this model? On the surface it seems much more convenient to consume our repositories in this way. Is this a problem that has been addressed before? If so, what is the most common and/or most efficient approach to this issue?
First, there are some controllers where we need upwards of 10 to 15 repositories all in the same controller.
Say hello to Abstract factory pattern. Instead of registering all repositories in Ninject and injecting them to controllers register just single implementation of the factory which will be able to provide any repository you need - you can even create them lazily only if the controller really needs them. Than inject the factory to controller.
Yes it also has some disadvantages - you are giving controller permission to get any repository. Is it problem for you? You can always create multiple factories for some sub systems if you need or simply expose multiple factory interfaces on single implementation. It still doesn't cover all cases but it is better than passing 15 parameters to constructor. Btw. are you sure those controllers should not be split?
Note: This is not Service provider anti-pattern.
After doing work with multiple repositories we need to call the SaveChanges method, but which repository should we call it on?
Say hello to Unit of Work pattern. Unit of Work is logical transaction in your application. It persists all changes from logical transaction together. Repository should not be responsible for persisting changes - the unit of work should be. Somebody mentioned that DbContext is implementation of Repository pattern. It is not. It is implementation of Unit of Work pattern and DbSet is implementation of Repository pattern.
What you need is central class holding the instance of the context. The context will be also passed to repositories because they need it to retrieve data but only the central class (unit of work) will offer saving changes. It can also handle database transaction if you for example need to change isolation level.
Where should be unit of work handled? That depends where your logical operation is orchestrated. If the operation is orchestrated directly in controller's actions you need to have unit of work in the action as well and call SaveChanges once all modifications are done.
If you don't care about separation of concerns too much you can even combine unit of work and factory into single class. That brings us to your DataBucket.
I think you are absolutely right to use the Unit of Work pattern in this case. Not only does this prevent you from needing a SaveChanges method on every repository, it provides you a nice way to handle transactions from within code rather than in your database itself. I included a Rollback method with my UOW so that if there was an exception I could undo any of the changes the operation had already made on my DataContext.
One thing you could do to prevent weird dependency issues would be to group related repositories on their own Unit of Work, rather than having one big DataBucket that holds every Repository you have (if that was your intent). Each UOW would only need to be accessible at the same level as the repositories it contained, and other repositories should probably not depend on other UOWs themselves (your repositories shouldn't need to use other repositories).
If wanted to be an even bigger purist of the pattern, you could also structure your UOWs to represent just that, a single Unit of Work. You define them to represent a specific operation in your domain, and provide it with the repositories required to complete that operation. Individual repositories could exist on more than one UOW, if it made sense to be used by more than one operation in your domain.
For example, a PlaceCustomerOrderUnitOfWork may need a CustomerRepository, OrderRepository, BillingRepository, and a ShippingRepository
An CreateCustomerUnitOfWork may need just a CustomerRepository. Either way, you can easily pass that dependency around to its consumers, more fine grained interfaces for your UOW can help target your testing and reduce the effort to create a mock.
The notion of every repository having a SaveChanges is flawed because calling it saves everything. It is not possible to modify part of a DataContext, you always save everything. So a central DataContext holder class is a good idea.
Alternatively, you could have a repository with generic methods that can operate on any entity type (GetTable<T>, Query<T>, ...). That would get rid of all those classes and merge them into one (basically, only DataBucket remains).
It might even be the case that you don't need repositories at all: You can inject the DataContext itself! The DataContext by itself is a repository and a full fledged data access layer. It doesn't lend itself to mocking though.
If you can do this depends on what you need the "repository" do provide.
The only issue with having that DataBucket class would be that this class needs to know about all entities and all repositories. So it sits very high in the software stack (at the top). At the same time it is being used by basically everything so it sits at the bottom, too. Wait! That is a dependency cycle over the whole codebase.
This means that everything using it and everything being used by it must sit in the same assembly.
What I have done in the past was to create child injection containers (I was using Unity) and register a data context with a ContainerControlledLifetime. So that when the repositories are instantiated, they always have the same data context injected into them. I then hang on to that data context and when my "Unit of Work" is complete, I call DataContext.SaveChanges() flushing all the changes out to the database.
This has some other advantages such as (with EF) some local caching, such that if more than one repository needs to get the same entity, only the first repository actually causes a database round trip.
It's also a nice way to "batch up" the changes and make sure they execute as a single atomic transaction.
I'm using NHibernate and exposed the Session in my front end. I have a controller action which retrieves tasks as follows:
public ActionResult Overview(DateTime date)
{
var allTasks = GetTasksUpUntilDate(date);
return PartialView("Tasks/Overview", allTasks);
}
private List<TaskOverviewModel> GetTasksUpUntilDate(DateTime date)
{
var allTasks = _session.Query<Task>().Where(t.BookedBy.UserName.Equals(CurrentUser.Name,
StringComparison.CurrentCultureIgnoreCase));
var tasks = allTasks.Where(t => t.DueDate <= date);
var taskVMs = new List<TaskOverviewModel>();
tasks.ForEach(t => taskVMs.Add(MapEntityToViewModel(t)));
return taskVMs;
}
Now I don't want to create an IRepository just for my views since ISession actually already is a repository. Mocking/stubbing this however is proving rather hard. So can anyone help me to have _session.Query return a list of objects I provide while testing?.
I'd also like to avoid setting up an in memory database and am using RhinoMocks for my tests.
Dont fake Nh/linq. Instead setup an in-memory sqlite db to query against. They are extremely fast and easy to use.
NHibernate Session might fit the repository pattern, but if you are building your controllers to talk to it directly, you are not truly abstracting it. Mocking it when you aren't abstracting it is not a reliable solution.
If you absolutely don't want to abstract it (which is pure lazy, IMO), then the sqllite db as mentioned by Jason is a good call. However, on a large project properly separating your concerns is very much a good idea.
My domain model contains the interfaces for both the data access objects (repos) and the services which consume them. This allows me to truly separate my data concerns from my business concerns, which should be entirely separated from the view/app concerns. This allows proper unit testing and the ability to easily swap out parts or do proper mocking.
Each layer ONLY talks to interfaces, NEVER to an implementation. Furthermore my application layer never talks directly to the data layer - only services. Allowing that to happen seems to encourage developers to be lazy and start putting business or data logic into the application.
I've commonly seen examples like this on business objects:
public void Save()
{
if(this.id > 0)
{
ThingyRepository.UpdateThingy(this);
}
else
{
int id = 0;
ThingyRepository.AddThingy(this, out id);
this.id = id;
}
}
So why here, on the business object? This seems like contextual or data related more so than business logic.
For example, a consumer of this object might go through something like this...
...Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
thingy.Save();
Or, something like this for an update...
... Get form values from a web app...
Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value));
Thingy.Name = Form["name"].Value;
Thingy.Save();
So why is this? Why not contain actual business logic such as calculations, business specific rules, etc., and avoid retrieval/persistence?
Using this approach, the code might look like this:
... Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
ThingyRepository.AddThingy(ref thingy, out id);
Or, something like this for an update...
... get form values from a web app ...
Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value));
thingy.Name = Form["Name"].Value;
ThingyRepository.UpdateThingy(ref thingy);
In both of these examples, the consumer, who knows best what is being done to the object, calls the repository and either requests an ADD or an UPDATE. The object remains DUMB in that context, but still provides it's core business logic as pertains to itself, not how it is retrieved or persisted.
In short, I am not seeing the benefit of consolidating the GET and SAVE methods within the business object itself.
Should I just stop complaining and conform, or am I missing something?
This leads into the Active Record pattern (see P of EAA p. 160).
Personally I am not a fan. Tightly coupling business objects and persistence mechanisms so that changing the persistence mechanism requires a change in the business object? Mixing data layer with domain layer? Violating the single responsibility principle? If my business object is Account then I have the instance method Account.Save but to find an account I have the static method Account.Find? Yucky.
That said, it has its uses. For small projects with objects that directly conform to the database schema and have simple domain logic and aren't concerned with ease of testing, refactoring, dependency injection, open/closed, separation of concerns, etc., it can be a fine choice.
Your domain objects should have no reference to persistance concerns.
Create a repository interface in the domain that will represent a persistance service, and implement it outside the domain (you can implement it in a separate assembly).
This way your aggregate root doesn't need to reference the repository (since it's an aggregate root, it should already have everyting it needs), and it will be free of any dependency or persistance concern. Hence easier to test, and domain focused.
While I have no understanding of DDD, it makes sense to have 1 method (which will do UPSERT. Insert if record doesn't exist, Update otherwise).
User of the class can act dumb and call Save on an existing record and Update on a new record.
Having one point of action is much clearer.
EDIT: The decision of whether to do an INSERT or UPDATE is better left to the repository. User can call Repository.Save(....), which can result in a new record (if record is not already in DB) or an update.
If you don't like their approach make your own. Personally Save() instance methods on business objects smell really good to me. One less class name I need to remember. However, I don't have a problem with a factory save but I don't see why it would be so difficult to have both. IE
class myObject
{
public Save()
{
myObjFactory.Save(this);
}
}
...
class myObjectFactory
{
public void Save(myObject obj)
{
// Upsert myObject
}
}