Just wanted some feedback/help with the way I'm architecturing my application. My current solution structure looks something like this:
UI (Actual MVC application)
Core (only Controllers & ViewModels)
Services
BLL
Data (Entity framework DbContext, mapped to Domain objects)
Domain (Simple POCO objects)
Interfaces
Other stuff
Ninject to inject DbContext into Controller (per request)
AutoMapper to map Domain objects to ViewModel
All assemblies have a reference to the Interfaces project, which, as the name suggests, is nothing more than simple interfaces (i.e. IDbContext, IRepository, etc).
The Services project "ties" together everything else. It is the only assembly which has a direct reference to the Data access layer (Entity Framework).
I've provided some code below:
An example of a Controller looks like this:
namespace Core.Controllers
{
public class HomeController : Controller
{
private IDbContext dbContext;
public HomeController(IDbContext dbContext)
{
this.dbContext = dbContext;
}
public ActionResult Users()
{
UserService userService = new UserService(dbContext);
var users = userService.GetAllUsers();
return View(Mapper.Map<IEnumerable<UserListViewModel>>(users));
}
...
The UserService class:
namespace Services
{
public class UserService
{
private readonly IDbContext dbContext;
public UserService(IDbContext dbContext)
{
this.dbContext = dbContext;
}
public IEnumerable<User> GetAllUsers()
{
IRepository<User> userRepository = new Repository<User>(dbContext);
UserBLL userBLL = new UserBLL(userRepository);
return userBLL.GetAllUsers();
}
...
Finally, the business layer class:
namespace BLL
{
public class UserBLL
{
private readonly IRepository<User> userRepository;
public UserBLL(IRepository<User> userRepository)
{
this.userRepository = userRepository;
}
public IEnumerable<User> GetAllUsers()
{
return userRepository.Get();
}
...
I'm looking for some feedback/ways to improve. I notice that for basic tasks, my service layer methods will be exactly the same as the business layer methods (i.e. "pass through" functions). What I'm hoping is that this abstraction will be helpful for more complex tasks which may require calls to multiple business layer methods. Would it just be better to include business logic in the service layer?
From a quick glance, I don't think your service and controller/core layer should have the db context injected into them in this manner. They don't actually directly depend on it and doing it in this manner causes some coupling that is not ideal. The core layer should have the user service injected and the user service and BLL should have the repository injected. The repository should have the dbcontext injected by your DI framework and not passed in as a dependency.
Why are you using dependency injection when you are creating dependencies directly in the service?
public IEnumerable<User> GetAllUsers()
{
IRepository<User> userRepository = new Repository<User>(dbContext);
UserBLL userBLL = new UserBLL(userRepository);
return userBLL.GetAllUsers();
}
Btw. why are you using so many layers when they actually do nothing? Your example code just shows that using context in controller directly would produce the same result without three wrapper useless layers. It may be just problem of your example but each layer should bring some added logic. If you just use it to call something on lower layer you are most probably overarchitecting your code. This is called onion architecture. That is also a reason why it is not a bad practice to add layer once you need it - not upfront.
Please check this out: http://www.primaryobjects.com/CMS/Article122.aspx EF Repository pattern + Unit Of Work pattern. As for your other layers, it really depends on the application and what it needs to accomplish. Please provide more details on what you're trying to do.
Some of the improvements in organizing projects and design of the layers can be done by focusing on getting the Domain objects correct.
You said you have simple POCO objects as Domain, but the Domain objects should be the one having all the "State and behaviour" of the business. That means you do not need to have BLL and Domain assemblies separate.
Once the Domain objects are defined, EF can be used to create the context and entity classes (which are not Domain classes unless there is no additional behaviour compared to your domain object, but still having them different might be good for future requirements).
Other minor point is, I think having interfaces distributed within the Domain and Services layer is better in terms of anyone understanding each layer in isolation.
Related
Building a app with EF 6 and Ninject 3.2.2 I'm having some trouble wrapping my head around how to access the DbContext in a intelligent way.
As I understand in the newer versions of Ninject only constructor injection is encouraged. As EF 6, itself is repo and unit of work I'm not doing any abstractions on top of EF.
If would like to be able to use multiple small units of works so injecting the DbContext (uow) into every class that needs it is not going to work.
In a non IoC way I would do like this:
Using(var db = new DbContext){}
How do achieve this using Ninject as I no longer can do kernel.get in my using block...
I'd consider two approaches:
Create general DbContext, which can be hidden behind an interface:
public interface IPortalContext : IDisposable
{
DbSet<User> Users { get; }
DbContext Context { get; }
}
public class PortalContext : DbContext, IPortalContext
{
public PortalContext()
: base("PortalConnectionString")
{
}
public virtual DbSet<User> Users { get; set; }
}
then you can inject your context to the constructor without problem.
Create many small contexts which can be used in different scenarios and classes.
I don't think that first approach is bad since it only encapsulates your DbSets and DbContext making it easier to inject and test. You don't make any unnecessary layers above EF and whole interface seems quite transparent.
Anyway this approach is better than making whole IRepository<T> stuff to access another repository...
I'm not sure what you mean by "multiple small unit of works", but just for exposure, this is what I've done in a recent application:
Divided the domain in small bounded contexts (this is more of a conceptual step)
Each bounded context has: a context, a repository, a repository factory
Each context implements an IContext and a BaseContext that gives basic methods and common properties (IContext will be useful for mocking)
Each repository takes the relative context as a constructor paramenter
This is an example of a repository factory
public class CartRepositoryFactory : IRepositoryFactory
{
public IRepository Generate(CartContext ctx)
{
return new CartRepository(ctx);
}
}
At the application service layer, I inject a UoW and the repository factory that I need
If I want to work with several different context in one service, I simply create another service and combine the services that I need, injecting them
You might be asking, but why?!? This is madness!!
Well, because if the Repository manages the DbContext, then I can only do one operation per class instantiation. This allows me to open a DbContext and make several calls to the Repository.
Of course now you have the same problem at application service level, you can only call one method per instantiation, but it's far easier to manage.
Ultimately it all comes down to your taste: would you rather have a thin service or a thin repository?
I have scoured the web looking for a good implementation of the Repository/Unit of Work pattern using Entity Framework. Everything I've come across is either tightly coupled at some point in the abstraction or assumes that the DbContext used by the Unit of Work and Repositories is shared and should live for the entire HTTP request (instance per request via dependency injection).
For example, assuming you are consuming repositories from the service layer, a service constructor might look like this:
public DirectoryService(IUnitOfWork unitOfWork, ICountryRepository countryRepo, IProvinceRepository provinceRepo)
{
/* set member variables... */
}
The unit of work constructor might look like:
public UnitOfWork(IDbContext context)
{
_context = context;
}
And a repository constructor might look like:
CountryRepository(IDbContext context)
{
_context = context;
}
This solution makes the blind assumption that the Dependency injection is setting up the Unit of Work and Repositories to share the same IDbContext using instance per request. Is that really a safe assumption to make?
If you are using dependency injection with instance per request, the same IDbContext will be injected into multiple units of work. The unit of work is no longer atomic, is it? I might have pending changes in one service that are then committed in another service because the context is shared across multiple units of work.
To me it seems to make more sense to set up a IDbContextFactory and get a fresh database context with each unit of work.
public interface IDbContextFactory
{
IDbContext OpenContext();
}
public class UnitOfWork
{
private IDbContextFactory _factory;
private IDbContext _context;
UnitOfWork(IDbContextFactory factory)
{
_factory = factory;
}
internal IDbContext Context
{
get { return _context ?? (_context = _factory.OpenContext()); }
}
}
The problem then becomes, how do I make my Unit of Work implementation available to the injected repositories? I don't want to assume instance per request because then I'm right back in the same boat I started in.
The only thing I can think of is to follow Entity Framework's lead and make the repositories (IDbSet<T>) part of the unit of work (DbContext).
So then I might have units of work that look like this:
public class DirectoryUnitOfWork : IDirectoryUnitOfWork
{
private IDbContextFactory _factory;
private IDbContext _context;
public DirectoryUnitOfWork(IDbContextFactory factory)
{
_factory = factory;
}
protected IDbContext Context
{
get { return _context ?? (_context = _factory.OpenContext()); }
}
public ICountryRepository CountryRepository
{
get { return _countryRepo ?? (_countryRepo = new CountryRepository(Context)); }
}
public IProvinceRepository ProvinceRepository
{
get { return _provinceRepo ?? (_provinceRepo = new ProvinceRepository(Context)); }
}
void Commit()
{
Context.SaveChanges();
}
}
Then my Directory service starts to look like this
public class DirectoryService : IDirectoryService
{
private IDirectoryUnitOfWork _unitOfWork;
public DirectoryService(IDirectoryUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public GetCountry(int id)
{
return _unitOfWork.CountryRepository.GetById(id);
}
public GetProvince(int id)
{
return _unitOfWork.ProvinceRepository.GetById(id);
}
public void AddProvince(Province province)
{
_unitOfWork.ProvinceRepository.Create(province);
Country country = GetCountry(province.CountryId);
country.NumberOfProvinces++; // Update aggregate count
_unitOfWork.Commit();
}
/* ... and so on ... */
}
It seems like a lot of work, but using this method leaves everything loosely coupled and unit testable. Am I missing an easier way, or is this a good way to do it if I am going to abstract away Entity Framework?
You should never abstract an ORM (itself an abstraction), but you should abstract the Persistence. The only UoW I'm using is a db transaction and that's a persistence detail. You don't need to use UoW and Repository together. You should think if you really need all this stuff.
Personally, I'm using the repository by default because Persistence is the last thing I do in an app. I don't care about patterns per se , I do care about decoupling my BL or the UI from DAL. Your upper layers (everything except DAL, which is the lowest layer from a dependency point of view) should always know about an abstraction, so that you can go as wild as you want in the DAL implementation.
One trick a lot of devs don't know is that design patterns (especially architectural ones) should be treated as a high level principle first and as a technical know-how second. Simply put, the thing that matters the most is the benefit a pattern is trying to achieve (the principle, the bigger picture), not its actual implementation (the "low level" details).
Ask yourself why should the BL know about a UoW in the first place. The BL only knows about an abstraction dealing with business objects. And you never work with the whole BL as once, you're always in a specific BL context. Your DirectoryService seems to be doing way to much for its own good. Updating stats doesn't look like it belongs to the same context as adding a new Province. Also why do you need UoW for queries?
One mistake I see a lot is devs rushing to write whatever code (with a design pattern attached) when they aren't doing the most important part: the design itself. When you have the improper design, problems appear and you start looking for workarounds. One of them is this UoW with Repository properties, which require a high layer like BL to know more than business concerns. Now the BL needs to know that you're using a UoW, a lower level pattern which is great for the DAL, not so great for the BL.
Btw, UoW never makes sense for quering as you're dealing with a 'read' situation, UoW is only for 'writes'. I don't mention EF or any ORM because they don't really matter, your BL service (Directory Service) is already corrupted by an infrastructural detail required by improper design. Note that sometimes you do need to compromise in order to implement a solution, but this is not the case.
Proper design means you know about your bounded context (yeah, DDD concept you can apply it regardless how much DDD you want to do) and don't put everything that might use the same data in one place. You have specific contexts for use cases and counting provinces (a presentation/reporting detail) is really a different use case than adding Province.
Adding the province and then publishing an event which signals to a handler to update stats is a more elegant, maintainable solution. No UoW required either.
Your code would look like this
public class DirectoryService : IDirectoryService
{
public DirectoryService(IProvinceRepository repo, IDispatchMessage bus)
{
//assign fields
}
/* other stuff */
//maybe province is an input model which is used by the service to create a business Province?
public void AddProvince(Province province)
{
_repo.Save(province);
_bus.Publish( new ProvinceCreated(province));
}
}
public class StatsUpdater:ISubscribeTo<ProvinceCreated> /* and other stat trigger events */
{
public void Handle(ProvinceCreated evnt)
{
//update stats here
}
}
In a way it simplifies things, in other way you might thing it complicates stuff. Actually, this is a maintainable approach, because the stats updater can subscribe to many events but the logic stays in one class only. And the DirectoryService does only the things that are assumed it does (what part of the name AddProvince hints you that the method also updates stats?).
In conclusion, you need to design the BL better before rushing to complicate your life with UoW, DbContext, Repositories as properties etc
or assumes that the DbContext used by the Unit of Work and Repositories is shared and should live for the entire HTTP request
This is clearly wrong. Assuming that the context is shared between the UoW and Repositories doesn't mean that the context lifetime should depend on the HTTP request. Rather - you can create new instances of the context and the UoW that use it whenever you want. This is only a convenience to have a default UoW that lives for the HTTP request but creating new, local units of work could be handy.
On the other hand, if repositories are exposed from the UoW:
public class UnitOfWork
{
...
public IUserRepository UserRepo
{
get { ... }
}
public IAccountRepository AccountRepo
{
get { ... }
}
then not sharing the same context between repos could have unexpected results:
UoW uow = ....
var u1 = uow.User.FirstOrDefault( u => u.ID == 5 );
var u2 = uow.Account.FirstOrDefault( a => a.ID_USER == 5 ).User;
You would definitely expect these two to return the same instance of the user of the id 5 and what's more, sharing the same context would mean that the second query could retrieve the user from the 1st level cache. On the other hand, two different contexts for two repos means that you get two different instances.
This also means that this would not be possible
var u1 = uow.User.FirstOrDefault( u => u.ID == 5 );
var a1 = uow.Account.FirstOrDefault( a => a.ID == 177 );
a1.User = u1; // oops!
as mixing entites from different contexts would just raise an exception. But the above scenario is a common one!
The conclusion from these observations is that you should share the context between repos. But, if you need a fresh instance, you just create a local, fresh instance of the context, inject it into the UoW, from where it gets injected into repos, and dispose it at will.
I would like that in my MVC layer there will be no Repositories at all.
I've generic EFRepository, IRepository and PASContext (which inherits from DbContext) in my DAL project layer .
I've installed Simple Injector with quick start under my MVC project and thats allows me to get in the constructor of each controller the repository i want .
But in my solution i have also BLL project and i want MVC layer to talk only with the BLL layer, as this is the project architecture and in the future i would like to add logic in the classes within the BLL layer .
Also i don't want to create a context in my BLL layer, but the Repository has no constructor which takes 0 arguments, this is my ProductBLL class :
public class BLLProducts
{
IRepository<Product> ProductRepository;
public BLLProducts(EFRepository<Product> Repository)
{
ProductRepository = Repository;
}
public ICollection<Product> getAll()
{
return ProductRepository.All().ToList();
}
}
How can i initiate the BLLProduct class from a controller or from a unitTest without creating a repository/context ? so i can keep my abstraction here.
I know i need to use somehow the Simple injector here, i just dont know how .
From perspective of the controller, it's just a matter of injecting the BLLProducts into it, like this:
// constructor
public HomeController(BLLProducts products) {
this.products = products;
}
From a unit testing perspective, letting the controllers depend on concrete classes is suboptimal (it violates the Dependency Inversion Principle). This is sub optimal, since you now need to create a BLLProducts instance and instantiate it with a DbContext, but this DbContext is specific to Entity Framework, which depends on a database. This makes testing harder and slower. You want your unit tests to run without a database.
So the solution to this is to hide this BLLProducts class behind an abstraction. A simple way to do this is extract an interface out of this class:
public interface IBLLProducts {
ICollection<Product> getAll();
}
This makes unit testing the controllers much easier. The only thing you have to do is let it depend on this new interface:
public HomeController(IBLLProducts products) {
this.products = products;
}
You will need to register this IBLLProducts interface in Simple Injector:
container.Register<IBBLProducts, BLLProducts>();
This whole model still has some downsides to it. For instance, although Simple Injector can create and dispose a DbContext for you, where do you call SubmitChanges? Doing this when the web requests ends is a pretty bad idea. The only convenient solution I found for this is to move to a more SOLID architecture. For instance, take a look at this question.
I just have a quick question. Im trying to use Unity with my asp.net MVC project. Im coming across a problem when using the Unit of Work pattern with an EF context.
Say i inject the uow in the constructor, but have 4 or 5 actions in the controller that need to use the UnitOfWork in a using statement. This isnt going to work! Because Id have to do a
new UnitOfWork() in each action method.
should i be injecting a UnitOfWork into each action method? or into just the constructor? or should I even be injecting this at all!! The problem im facing is that i want to be able to unit test my controller with Mock data, and i can only do this if I inject the UnitOfWork or the DBContext.
Inject factory instead. This way you still achieve separation of concerns and loose coupling, yet you won't face any issues with using statements:
private IUnitOfWorkFactory factory;
public MyController(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public ActionResult MyAction()
{
using (var uow = factory.CreateUnitOfWork())
{
// ...
}
}
Edit:
Natural advantage of such approach is its configurability - you can register whichever factory you like to serve different controllers and wire it up at composition root:
// Note: this isn't unity syntax, but I hope my point is clear
container.Register<ISessionFactory, ReusableSessionFactory>("Reusable");
container.Register<ISessionFactory, FreshSessionFactory>("Fresh");
container.Register<IController, LoginController>().With("Fresh");
container.Register<IController, HomeController>().With("Reusable");
Now,
LoginController will use factory that under the hood serves new session upon each request
HomeController on the other hand will reuse the same session for all its lifespan
It's worth noting that from the controller point of view, it's irrelevant which factory serves the session as it's a mere implementation detail. That's why we hide session factory dependency behind abstraction (interface in this example) and perform all the object-to-dependency binding at application's root.
If I understand correctly you simply want to be able to test the UOW with something like Moq?
In that case for good design principles and proper separation of concerns you should create a base context for your database that each repository class uses.
Then you should create a repository interface for each domain model entity. Then you can implement the interface in a seperate repository library (this way you can implement a POCO model)
Finally you either create a service layer between your domain objects and your action methods or just use the required repository interfaces within the action methods.
I answer it like this because it depends on your application infrastructure. If you have no service layer then the best practice is to do the following:
public class AccountController : Controller
{
private readonly IAccountRepository _accountrepository;
public AccountController(IAccountRepository repository)
{
_accountrepository = repository;
}
}
I hope this helps.
I've been playing around with asp.net MVC3 a bit and have been struggling to decide where to place my business logic. I've settled on using a service layer for now:
public class AnimalsService : IAnimalsService
{
private readonly IAnimalsRepository _animalsRepository;
public AnimalsService(IAnimalsRepository animalsRepository)
{
_animalsRepository = animalsRepository;
}
public IQueryable<Animal> GetFiveLeggedAnimals()
{
...
}
}
The controller would look something like this:
public class AnimalsController : Controller
{
private readonly IAnimalsService _animalsService;
public AnimalsController(IAnimalsService animalsService)
{
_animalsService = animalsService;
}
public ViewResult ListFiveLeggedAnimals()
{
var animals = _animalsService.GetFiveLeggedAnimals();
return View(animals);
}
}
I have basic CRUD logic in the repository (All, Find, UpdateOrInsert, Delete). If I want to use these CRUD methods in my controller:
1) Do I have to create wrapper methods in the service for these respository calls?
2) Would it not make more sense for me to just include the GetFiveLeggedAnimals method and other business logic in the repository?
3) Could I implement the IAnimalsRepository interface in the AnimalsService and then call the base methods (I realise this is possible but I assume its bad practice)?
1) Do I have to create wrapper methods in the service for these respository calls?
Mostly, yes. Typically, you want to offer CRUD for your domain models in the service layer. This way, the controller does not need to work with the repository directly (in fact, it never should). You can add more more sophisticated logic later without having to change external code. For example, consider you wanted to implement a newsfeed. Now every time a five-legged animal is inserted, you want to create a news item and push it to five-legged-animal-fans. Another common example is email notifications.
2) Would it not make more sense for me to just include the GetFiveLeggedAnimals method and other business logic in the repository?
Business logic should be in the Service Layer or in the Domain Model objects themselves, and only there. In fact (see 3), I wouldn't specifically offer an IAnimalRepository at all, if possible.
For instance, in a NoSQL-Environment, the database driver pretty much is a repository. On the other hand, when using a complex ORM mapping and stored procedures (where part of the biz logic is in the DB), you don't really have a choice but offer explicit interfaces that know the stored procedures.
I'd go for a IRepository<T> and use the Query Object pattern, if possible. I think LINQ can also be considered a Query Object / Repository based pattern.
3) Could I implement the IAnimalsRepository interface in the AnimalsService and then call the base methods (I realise this is possible but I assume its bad practice)?
To call the base methods, you'd have to inherit from a concrete implementation, e.g. from ConcreteAnimalsRepository.
Also, if your service implements the IAnimalsRepository interface directly or indirectly, it makes the (unfiltered) CRUD operations available to everyone.
My take: Don't inherit, aggregate. A service layer has a repository, but it isn't a repository itself: The service layer handles all the additional application logic (permissions, notifications) and the repository is a very thin wrapper around the db layer.
As an extreme example, what if deleting something directly was forbidden, and only the service would be allowed to make use of it when inserting a newer revision of sth.? This can be easily built when aggregating.
Repository by definition should be a generic collection-like class that abstracts DB interactions. It would contain typical methods for persistence like Get(object id), Add(T), Remove(T) and possibly implement IQueryable<T>.
The service would look like the following code.
public class AnimalsService : IAnimalsService
{
private readonly IRepository<Animal> _repository;
public AnimalsService(IRepository<Animal> repository)
{
_repository = repository;
}
public IEnumerable<Animal> GetFiveLeggedAnimals()
{
// animal specific business logic
}
}
I think is not good to use simple CRUD operation in the Controller and have a wrapper in the Service class, you should keep all business logic in the service layer, not in controller
for example you want to create a new Animal
in the controller you will have method
look at the example
// not good design
public ActionResult Create(AnimalInput input)
{
Animal animal = new Animal { Name = input.Name}; // set the other propreties
// if you have a CRUD operations in service class you will call
animalService.UpdateOrInsert(animal);
}
// better disign
public ActionResult Create(AnimalInput input)
{
animalService.Create(input.Name);
}
in the service class implementation you should have
follow
public void Create(string name)
{
Animal animal = new Animal { Name = input.Name};
animalRepository.UpdateOrInsert(animal);
}
for the methods like GetAll or GetFiveLeggedAnimals(); you can have wrapper in the service classes I think it's ok . And I want to give you adives allways when you write some code in controller or in Service class keep in mind how you will test this code
and don't forget about SOLID