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.
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.
So, I've decided to use the Microsoft Extensibility Framework(MEF) with my new ASP.NET MVC web project. The project is a very typical employee management system, with 3 traditional layers :- a presentation layer (with views and controllers), a business layer (with business objects) and ofcourse, a data access layer. After some research, I read a lot, that MEF is supposed to help us implement the plug-in architecture.And this is where, I seem to get stuck. I'm not able to relate with this pluggable part. I'm pretty sure that, since MEF is the part of the core .NET framework, it is not limited to any specific kind of application, and is supposed to be useful in general. I just need to see my application structure in a new light, and that's where I need some helpful insights.
As I'm still trying to get started with MEF, my main question is; what would be the main extensible(pluggable) points in my application? What objects should one be typically composing using the MEF's compose method, and what would be the advantages of doing so using MEF instead of the traditional way?
MEF will not help you solve extensibility issues in the case you have described in the question, because it doesn't seem to have any. What MEF can bring to the table for this particular case is Dependency Injection. If you develop your application in a way that the presentation layer depends on business abstraction and the business layer depends on a data access abstraction rather than on concrete implementation, you will get a highly decoupled application that is easy to test, maintain and change without affecting unnecessary components. Here is one way to do this:
Lets say you have data access class that performs CRUD operations on employees:
[Export(typeof(IEmployeeRepository))]
public class EmployeeRepository : IEmployeeRepository
{
//Some logic here
}
As you can see the EmployeeRepository class implements IEmployeeRepository interface which adds the level of abstraction that is needed to develop a decoupled application. Now lets say that in the business layer you have a class that needs to call some method from the EmployeeRepository class. To be able to call a method of EmployeeRepository, you would need an instance of it. Without using MEF (or any other IoC framework, this would be a way to do it:
public class EmployeeManager
{
private EmployeeRepository _employeeRepository;
public EmployeeManager
{
_employeeRepository = new EmployeeRepository();
}
}
By using the above code sample, a hard dependency between the EmployeeManager and EmployeeRepository classes is created. This hard dependency is difficult to isolate when writing unit tests and causes any change of the EmployeeRepository class to directly affect the EmployeeManager class. By refactoring the code sample a little bit and putting MEF into the game, you'll get this:
[Export(typeof(IEmployeeManager))]
public class EmployeeManager : IEmployeeManager
{
private IEmployeeRepository _employeeRepository;
[ImportingConstructor]
public EmployeeManager(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
}
As you can see the EmployeeManager class now doesn't depend on the EmployeeRepository class, but it depends on IEmployeeRepository interface, in other words it depends on abstraction. And it doesn't create the instance of EmployeeRepository class by itself. That job is left to MEF. By now it should be clear that export and ImportingConstructor attributes are part of MEF and are used by it to discover parts and resolve dependencies at runtime. With the last code sample the classes are decoupled, easy to test and maintain and you can change the internal logic in EmployeeRepository class without making EmployeeManager class aware of it. Of course the contract between them, IEmployeeRepository have to be maintained.
The above said, can be used to decouple the presentation layer from the business layer also. Also the above said, can be implemented by using any other IoC framework, like Ninject, Autofac, StructureMap etc. The difference between these IoC frameworks and MEF is that if you use them, you'll need to configure at application start which instance gets created when some interface is encountered:
//something like this, in the case of Ninject
this.Bind<IEmployeeRepository>().To<EmployeeRepository>();
On the other hand, MEF has the ability to discover parts at runtime. On application start, you'll just need to inform it where to look for parts: Directory, Assembly, Type etc. The auto-wire capabilities of MEF (the ability to discover parts at runtime), make it more than a regular IoC framework. This ability makes MEF great for developing pluggable and extensible applications because you'll be able to add plugins while the application is running. MEF is able load them and let the application to use them.
So I have been really struggling to grasp the concept, but I am making progress :)
Anyway I have a question, using the Service/Repository/UnitOfWork/EF 4 w/POCOS approach.
My MVC app can reference my Repository layer, that References System.Data.Entity, to setup the bindings in Ninject to the concrete classes that live there, and as long as I use Interface driven design, that does not tie my MVC app to EF. Correct?
Just by referencing an assembly that references System.Data.Entity, you are not tying your MVC application to EF?
If I am wrong, can someone please tell me how to bind the interfaces to the concrete classes of the repository and unitfowork in the Ninject Module in the MVC app.
Make any sense?
Just by referencing an assembly that references System.Data.Entity, you are not tying your MVC application to EF?
Yes, you are tying it but that shouldn't bother you. The MVC application is the Host application, it is where all layers and assemblies need to be aggregated into a final product that is deployed on a web server and just works. Jeffrey Palermo has a nice blog post about onion architecture you might take a look at. In this pattern outer layers of the onion know about the inner layers but not the opposite (inner layers shouldn't know about the outer layers). The ASP.NET MVC application is the outermost layer. Then you could simply change the outer layer with some other Host application (for example WPF) and reuse the inner layers.
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.
I would like to inject a dependency into an ASP.NET MVC model, but I can't figure out where in the pipeline to do the injection.
It's very straightforward with a ControllerFactory, but not nearly as much when dealing with models.
You can find a reasonable How-To on Shiju Vargheses Blog: ASP.NET MVC Tip: Dependency Injection with Unity Application Block
usually i inject dependencies in the controller like this
PersonController(IPersonRepository r)
{
\\ constrtuctor code
}
in the models probably when need some instance of something that inherits an interface you do something like this :
var r = container.Resolve<IPersonRepository>();
I ended up creating a service locator: http://martinfowler.com/articles/injection.html#UsingAServiceLocator
I find it easier than dealing with an IoC container and trying to insert my DI code all over the MVC pipeline.
I'd recommend reviewing S#arp Architecture
http://www.sharparchitecture.net/
Open source framework addon for asp.net mvc.
Are you completely sure you need to inject a dependency into your domain model itself? An entity or business object will typically encapsulate the state and expose methods to modify that state according to business rules. Code that does not fall into this category typically will be found in a service. Have you read into the concept of a domain service at all? Perhaps using one would better suit your needs and you won't need to inject any dependencies into your domain itself.
Checkout this sample I've created based on Ayende's explanations on his blog. Basically, I use Castle as my IoC container and I use Mvc Contrib to add all controllers to the container and make Mvc get them from it. Then I can inject anything into the containers, such as NHibernate ISession.
If you want to inject stuff inside your model classes (entities), NH now supports Dependency Injection of Hibernate-managed objects. See this, this, and this for specific examples for Spring and Windsor.
What your talking about is more along the lines of the Active Record pattern.
Whether AR is possible or not will depend on which ORM/DAO your using.
The AR pattern is generally better suited for small projects.