I have a asp.net mvc app having three layers
1. dataAccess layer (class library)
2. business layer (class library)
3. web layer (asp.net mvc project)
and also have a domain project (class library for poco)
I am doing the structureMap mappings in my Application_start of the MVC project, but to map the TYPES in dataAccesslayer (for eg. personRepository with IPersonReository) i need the reference of the DAL in my web layer, which i dont think is correct.
What are your suggestions
Thanks
As a pragmatic approach what you are doing may be okay if you can keep the discipline and never use the DAL from the Web Layer. However, once the reference is there, this can be surprisingly hard to do - and what about other developers on the project?
A better option is to split the web layer into two layers:
The Application Bootstrapping layer. This is the real web project, but apart from bootstrapping the container and implementing the Views (.aspx pages) there should be nothing else. This is what we call a Humble Executable. It will contain references to all other projects in order to compose them (via the DI container), but otherwise it doesn't do anything. We call this the Register Resolve Release pattern.
An Application Model layer. This project would contain all of your application logic (as opposed to domain logic): View Models and Controllers. It needs no reference to the DAL, but will get implementations injected into it by the DI container.
There is nothing wrong in having a reference to the DAL in your web project as long as you are not directly making calls to that assembly. But if you are uncomfortable with that approach, you can use a Registry in your Business layer and there register types for the DAL. Since the Web layer would anyway need to have a reference to the Business layer, you can use that registry from the Business layer in Web's App start
Here is some sample code
The registry class in your Bsns layer
public class BusinessRegistry:Registry
{
public BusinessRegistry()
{
For<IDALInterface1>().Use<DALImpl1>();
}
}
and in the Application start method
var container = new Container(x => x.AddRegistry(new BusinessRegistry()));
Like others have said, a reference to your DAL project is not the end of the world unless you use it incorrectly (or maybe at all in your web project). I prefer to have an Infrastructure project contains all things related to cross-cutting concerns. Among other things, this includes my Logging and IoC Container.
Related
I am making an ASP.NET MVC website with an Onion architecture. I have implemented a repository pattern and am now creating a Controller method in my project. This is my architecture:
Domain : Entities / Domain Interfaces
Repository : Generic repository (for now) using Entity Framework Code First
Service : Generic Service that calls the Repository
MVC
Now in my MVC project I need to access repository but according to Jeffrey Palermo, MVC is dependant from Service and Domain, but nothing is said of Repository.
Can i make my UI dependant of Repository?
I cannot do anything without the dependency right now, because Service creation depends on Repository. I have tried modifying Startup.cs to not directly use Repository objects in my Controllers, but it still means I need to add a reference to Repository (see http://dotnetliberty.com/index.php/2015/10/15/asp-net-5-mvc6-dependency-injection-in-6-steps/ )
At this point MVC (UI) is the composition root, which would need to know all the layers in order to register them with the DI container.
The start up would either refer to the implementations directly when registering them or indirectly via extension methods exposed from that layer. Either way the composition root needs to reference all lower layers if they are to be added to DI container.
The controllers should also be dependent on abstractions from lower layers and not concretions.
If injecting repositories directly into controllers then I suggest reviewing the design as that may indicate mixing of responsibilities.
I'm not sure if I did a good job of searching the topics but I can't seem to find answers to my questions. Based from my understanding, Onion Architecture has the UI and Infrastructure on the same layer. Let say I have my UI in ASP.NET MVC project and I have DAL project which is my Infrastructure. Lets assume my code is like the one below:
Core:
//IOrderSaver interface was also defined on the core
public class OrderService
{
private IOrderSaver orderSaver;
public OrderService(IOrderSaver orderSaver)
{
this.orderSaver = orderSaver;
}
public void AcceptOrder(Order order)
{
orderSaver.SaveOrder(order);
}
}
Infrastructure (DAL):
public class OrderSaverDAL : IOrderSaver
{
//implementation goes here
}
Now, in my UI (ASP.NET MVC) I would like to instantiate OrderService class so that it can accept orders. For the UI to do that, it has to pass IOrderSaver to the constructor. It needs to pass OrderSaverDAL.
Questions:
Does the UI (ASP.NET MVC) needs to reference OrderSaverDAL? From my understanding of Onion Architecture (if I understand it correctly), the UI should have no reference to the DAL. Can someone please explain?
If I don't need to reference OrderSaverDAL from my ASP.NET MVC project, how will I construct OrderService within ASP.NET MVC? Can you please guide me by giving sample code on how to achieve this?
Many thanks in advance for the help!
You need an additional configuration module/layer that will wire up ui and dal. If you implement this yourself without reflection then this configuration moudul needs all reference.
Usually the onion-architecture works together with an dependency injection container that can resolve the references at runtime through configuration files or inspection of local assemblies.
Does the UI (ASP.NET MVC) needs to reference OrderSaverDAL? From my understanding of Onion Architecture (if I understand it correctly),
the UI should have no reference to the DAL. Can someone please
explain?
You're right to say that the UI should logically not have a dependency to the DAL.
However, as k3b points out, a common way of doing dependency inversion (upon which Onion Architecture relies heavily) is through a DI container. You then need some kind of Composition Root, a place where your application's object graphs are composed using the container. The Composition Root has to be "omniscient" and needs a reference to every project in order to wire things up.
It turns out that the UI is often where the Composition Root is hosted, as the UI is a natural starting point in your application and a perfect fit to do the composition at the right time. You could have a separate project for your Composition Root, but this would be less convenient.
I'm sure someone has asked this before, but I'm struggling to find where.
I'm using Ninject to remove dependencies from my controllers, along with a repository design pattern.
As I understand it, one of the benefits of this approach is that I can easily whip apart my repositories and domain entities and use another assembly should I so wish. Consequently I've kept my domain entities and repositories in external assemblies and can mock all my dependencies from interfaces.
It seems that while I can use interfaces to refer to my domain entities in most places I must use references to my concrete classes when it comes to model binding. I've read that this is to do with serialization which I understand, but is the only way to avoid referring to domain entities to create separate models?
Anything I can do with Custom Model Binding?
A bit of background: I'm an experienced ASP.net developer, but new to MVC.
View Models should be plain data containers with no logic and therefore shouldn't have any dependencies at all. Instead inject the repositories to your controller and have it assign the required data from the repository to the appropriate property of your view model.
The major advantage of using a dependency injection framework is IoC (Inversion of Control):
loosely coupling
more flexibility
easier testing
So what one usually does is to inject repositories through their interfaces like
public class MyController : Controller
{
private IPersonRepository personRepo;
public MyController(IPersonRepository personRepo)
{
this.personRepo = personRepo;
}
...
}
During testing this allows to easily inject my mock repository which returns exactly those values I want to test.
Injecting domain entities doesn't make that much sense as they are more tightly linked with the functionality in the specific class/controller and thus abstracting them further would just be an overhead rather than being a benefit. Instead, if you want to decouple your actual entity model from the controller you might take a look at the MVVM pattern, creating specialized "ViewModels".
Just think in terms of testability of your controller: "What would I want to mock out to unit test it?"
DB accesses -> the repository
External dependencies -> other BL classes, WS calls etc.
I wouldn't include domain entities here as they're normally just a data container.
Some more details would help. A bit of code perhaps?
To start with, you should avoid injecting dependencies into domain entities, but rather use domain services.
Some more info here.
Edit 001:
I think we should clarify our terminology.
There is the domain layer with all you domain entities, e.g. product, category etc.
Then there's the Data Layer with your repositories that hydrate your domain entities and then you have a Service Layer with you application services that talks to the data layer.
Finally you have a presentation layer with your views and controllers. The Controllers talk to you Aplication Service Layer. So a Product Controller talks to a Catalogue Service (e.g. GetProductBySku). The CatalogueService will have one or more repositories injected into its constructor (IProductRepository, ICategoryRepository etc.).
It's quite common in asp.net mvc to have ViewModels too. Put the ViewModels in your Application Service Layer.
So I'm not sure what you mean when you say "models" and "domain enntities" but I hope that clears up the terminology.
I am about to start developing a medium sized ASP.Net MVC application.
I am trying to get the design right. I intend to have the following layers:
UI layer (MVC)
Service Layer
Repository Layer
Data Access Layer
I will be using Unity as my IOC container and EF4.1 Code First for Data Access.
The app will be split into several assemblies. I have a problem deciding which assemblies I will need
and where to put the following:
Entities/Domain objects e.g. Customer, Invoice
DTOs e.g. CustomerDTO, InvoiceDTO
Service interfaces e.g. ICustomerService
Repository Interfaces e.g. ICustomerRepository
Services(Service interface implementation classes) e.g. CustomerService
Repositories (Repository Service implementation classes) e.g. CustomerRepository
ViewModels e.g. CustomerViewModel
Enums
My question is:
How do you usually split yours and why?
Edit: prompted by the #TheHurt's answer.
How would the references be between the assemblies, i.e. which assembly would be referencing which?
This is how I might tackle it:
App.UI assembly:
ViewModels go in Models area.
App.Repository assembly:
Abstract implementation of concrete repository.
ICustomerRepository
App.Repository.SQL:
Concrete implementation.
EFCF POCOs
App.Services assembly:
Abstract service.
ICustomerService
DTOs
App.Services.Implementation:
Concrete service.
CustomerService
App.Common:
Shared code.
Enums
There are a couple issues that I still struggle with. You lose the data annotations from EFCF when you cross the services boundary. So then you have to do server side validation or you have to keep your view models validation in sync with the repository entities. It feels that the more layered things are, the more DRY is violated. I suppose that is par for the course though when your view models don't map to your entities directly. You could have your view models be your DTOs and toss them into the Common assembly, but that seems to couple things too tightly if you have the need to be super flexible with your services.
EDIT
If you are wanting to integrate WCF into the mix you would probably want to create data contracts that are very close to the MVC view model (or use the contracts as the view model). You probably wouldn't expose that to the world as the service would be specific to that implementation of your MVC site, spin up another service for public consumption. If you are doing a WCF service you probably want to have all of your business logic in the service, the controllers would just handle navigation logic.
Side note, I try to stay away from the "metal" as much as possible, while developing a design that will allow me to separate the code into various layers in the future. If I cannot clearly explain the various system layers to my manager with one sheet of paper, the design is more than likely too complex. Everything for the most part will look pretty in Visio if it is designed well.
As far as how things reference each other: UI would ref the Serivce (or service implementation, which may not be needed. Just keep it all in the same place.). Service refs the Repository. The repository implementation refs nothing, since it is loaded by IOC. Everything refs Common.
I have an MVC solution setup like this, with three 'projects'.
Web (MVC Project, Views, Controllers, ViewModels)
Models (Domain Objects)
Persistence (nHibernate Mapping, SessionFactory)
I need to begin building the repositories, and was going to start with the Authentication Model. Basically following the default MVC template, have an IMembershipService and an IFormsAuthenticationService and related classes (using custom code, not built in authentication providers).
My question is ...where should this go? My Repositories will need access to both my Domain objects and my Persistence Layer. However I keep reading that any kind of 'coupling' means it is a bad design. So I am hesitant to create a fourth project for the Repositories/Services that references the Models/Persistence ...but I can't really find any other way to do it logically.
This is very subjective.
Do what makes sense to you and your team.
I throw them in with the rest of my Repositories. I mean a User is pretty central to any application right? Does a User own anything? If so then isn't he an root?
Repositories are part of the domain.
Tension will always exist between reducing assembly references and minimizing number of projects. That is, you can make each assembly reference fewer dependencies by breaking up functionality into more fine-grained assemblies; however, excessive division of a project into many assemblies requires more effort to manage.
Another point worth mentioning is that authentication has a couple sides to it. One is managing the model around Users, Roles, Permissions, etc. - this is a domain concern. The other is interfacing with the context of execution (whether this is an ASP.Net app, WinForms, etc.) - this is an infrastructure concern. Consequently, I end up with a small service in my MVC project or WinForms project that performs functions like setting Forms Authentication cookies, or setting the current thread principal, etc.
The Separated interface pattern says that your models and repository interfaces should be in a seperate assembly, apart from the GUI and the actual repository implementation. This is to be able to switch implementations later on and to be able to simplify testing.
I would have no problem with putting the interfaces along with the repository interfaces and the actual implementation in the mvc project or the repository project. It's quite easy to move stuff later on if you use a IoC container.