Dependency Injection in multilayered Application - c#

So my problem is the following. My solution contains the following projects (with references):
Presentation Layer, contains Views (has a reference to Application Layer)
Application Layer, contains ViewModels (has a reference to Domain and Persistence Layer)
Domain Layer, contains all Models (no reference to anything)
Persistence Layer, stores data with Entity Framework (reference to Domain Layer)
All right, now I want to use Dependency Injection to decouple my ViewModels from Services and other stuff. Because I'm also using a dialogs, I also need to inject the IDialogService with the implementation DialogService.
Now, the DialogService uses some Presentation-specific DLLs which are only in the Presentation project so I had to implement the IDialogService interface in the Presentation project, but the Unity-Container is in the Application Layer. I think you can see what my problem is: I only have a reference from Presentation Layer to Application Layer, not the other way.
Am I doing this right and how can I solve this problem?

You are missing a layer: the Composition Root layer. This is the top-most layer of your application and it references all other layers in you application. Often you see that this layer is put into the same assembly as the presentation layer (which is fine, because layers are logical artifacts, while assemblies are physical artifacts). In the case of WPF however, it is very easy to move all WPF related stuff to a different assembly and let the start-up project consist of nothing more than the bootstrapping logic (with the container) that wires everything together.
So in general you shouldn't let each assembly be responsible of its own wiring, because that would cause a needless dependency on the container. In general only the composition root has to take a dependency on your DI library.
Also see this related question.

Related

Does application services belong to domain layer or application layer?

I have a N-Layered Winforms application with 4 layers as follows:
Presentation Layer
Application Layer
Domain Layer
Infrastructure Layer
My Application Layer has a Product Services class which is used for all repository related actions for Products.
Does the interface file for the Product Services class belong in the Application Layer or Domain Layer? I ask because the interface file for my repositories is defined in the Domain Layer even though they are implemented in the Infrastructure Layer.
Thanks in advance.
Service concept can belong to any layer. If you ask for application services, then these should live in the application layer.
In the other hand, if these services are the ones directly accessing the domain, then they're still domain. That is, I would expect to find both a service interface and one or more implementations in any project prefixed with Domain.
BTW, the project has nothing to do with software layers. It's just an organizational unit to group files by some criteria. The most important point is your flow should work with inversion of control in mind to glue layers.
With DDD, is usually recommended to use Dependency Inversion (the D in SOLID), so the tree of dependencies should be
Domain Layer
|
/ \
/ \
Presentation Layer Infrastructure Layer
So the Presentation and Infrastructure "layers" depend on your domain, and not the other way around (the generic version of this is also know as Hexagonal Architecture or Ports and Adapters)
And the Application Layer is indeed part of your domain, as it defines how use cases are supposed to work. I've never used (or seen) an application layer in an application, but what I've done is to put the Application Services in a different package inside the same artefact (the terminology here might be a bit different as I come from a Java background).

Should I separate IoC binding seperation by project

I am new at domain driven design architecture. My project solution is like this:
Presentation(Web)
ApplicationLayer
QueryLayer
QueryHandlerLayer
DataLayer
I read from articles theese separations is doing to isolate jobs.
Presentation project references ApplicationLayer
But does not reference QueryLayer,QueryHandlerLayer and DataLayer.
But I am using IoC container and bind types to interface.
container.Bind(data interfaces).To(data classes);
container.Bind(query interfaces).To(query classes);
I can do this on PresentationLayer. But now all projects will be add reference to presentation layer.
Is this an issue about architecture? Or May I separated IoC container binding for all layers?
Using DI is about composing applications. An application might have multiple layers, but they are still part of the same application and must be composed together.
The appropriate place to compose an application is in the composition root, which should be as close to the entry point of the application as possible.
There are basically 3 common recommendations for composing applications with multiple layers, and all of them are perfectly acceptable.
Don't separate the layers into physical assemblies.
Compose the application in the presentation layer, and reference all other layers from the presentation layer.
Create a separate composition layer that references all of the other layers.
For the 3rd option, you should keep in mind that the composition layer is supposed to drive, not be driven by, the rest of the application.
See this answer for the reasoning behind this referencing and why it is important that you do reference every library from the composition root to avoid tight coupling. Or, as mentioned, you could use late binding to compose your application without referencing the assemblies directly, provided your deployment script copies over the DLLs.
I think the biggest thing I have learnt in recent usage is that at the fundamental level, DI is about Injecting Dependancies. That's a pretty redundant description, so let me elaborate:
DI starts with design. Everything should have what it needs provided to it via a constructor, or factory of some sort. This is where Interfaces are your best friend. Once you have done this, most of the work is done. Assuming some of the projects are shared, you have now delegated out all of the work to whoever is using it. This is probably old news, however.
Next, if you are in control of the container, consider creating a default module, which in the case of Ninject is a, NinjectModule. Create one of these for each application layer. This will form the "instructions" so to speak, for the container at the highest level of your program to put all the pieces together.
This can all be loaded by reflection trickery of which there is plenty of information around, like this.
Then it is as simple as loading all of these binding "instruction manuals" into the composition root (usually in the application) and you're good to go.

UI layer dependency in DDD

My current project is organized in this way:
Domain Layer -> Domain objects and Repository Interfaces
Infrastructure -> Repository implementation
Application Layer -> Services in a MVVM pattern
Presentation -> Accessing only Service Layer and working with ViewModels
I´m using an IoC Container (SimpleInjector). My Services receives an IRepository in the constructor like:
public CustomerService : ServiceBase
{
public CustomerService(ICustomerRepository repository, IUnitOfWork<CustomerContext> uow)
{
...
}
}
My question is:
To inject a Repository in the Service, my Presentation Layer should reference the Domain Layer. It´s ok to add this reference? Shouldn't my presentation layer have reference only to the Infrastructure and the Application layer?
Yes, that's OK.
You need a reference to all components from the composition root (which usually resides in the presentation layer).
I understand it feels a bit strange at first, but you need to differentiate between a DLL-dependency and a hard class dependency. It's OK if your presentation layer depends on DLL's, it's not OK when a view depends on a SQL-repository (as an example).
I have written a blog post about this with some more information:
http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/

Can I register all IoC container components in single layer, or each layer where used?

I'm using the Unity IoC framework and have a Bootstrapper.cs class in my host MVC layer to register all components. However in my architecture I have a 'services' layer below the MVC layer, that too uses DI and there are repository interfaces injected into it (repository interfaces are not used in the MVC layer - it has the services layer Interface injected into its Controllers).
So my question is the following: can I still register the repository interface to it's concrete type in the MVC/UI layer for the entire app, or do I add another reference to Unity and create another Bootstrapper.cs class in my 'services' layer to define Interface types for that that specific layer uses?
Even if the answer is I can register the Interface in the UI layer, I'd still like to know the common practice too. The thing I don't like about registering that type in the MVC/UI layer is I would have to add a reference to the Repository layer just to make the registration, even know it is not used in that layer. It's used in the services layer.
Thanks!
Each application should have its own Composition Root, the place where you configure the application (see this answer for details).
It depends on the context, but generally speaking, if you split your container configuration among the layers you are going to make decisions about the configuration of your layers too close to the layers and you'are likely to lose the general view.
For example, in one of your business logic layers you'are registering a service:
container.RegisterType<ISercice1, MyImplementation1>(new PerThreadLifetime())
But when using that layer in a web application you could decide that a PerSession or PerRequest lifetime would be better lifetimes. This decisions should be in only one place and not spread through the layers.
I turn your question on its head.
If you add a reference to Unity in your class libraries, you would have added dependencies to the framework you are using. That is quite the opposite of what you are trying to achieve.
The only adaptation your classes should need is to support constructors or using public properties - on interfaces. That's it!
So your application entry point should do all the 'bootstrapping'.
Note that a entry point could be different applications, as well as different test projects. They could have different configurations and mocking scenarios.
If your bootstrap.cs gets large, you could split it up into smaller parts for readability reasons. But I reject the idea of classes having any knowledge about the fact that they are being bootstrapped/moqed/injected and by what.
Consider re-use. Your current libraries is using Unity. They may be used in a project using StructureMap. Or why not Ninject.
In short, yes it is possible to keep the configuration at the top of the process or localized to each module. However, all dependencies must be resolved for the entire object graph in the process.
Localizing the configuration by keeping it in each module (assembly) is often a good idea because you are allowing your service layer to take responsibility for its own configuration. My answer to this question, IMHO, is a good practice.
Yes, application should have one composition root at entry point. But it can be a good practice to keep registrations of a classes inside a layer where they are implemented. Then pull these registrations from layers at composition root, registering implementations layer by layer. This is why:
Registration within layer can be redefined in other place, for
example at entry point. Most of IoC libraries work in such a way
that registration done later erases the registration done earlier.
So registration within layer defines just a default behavior which
can be easily overridden.
You don't need to reference IoC library in all your projects\layers, even if you have registrations defined inside these
layers. A very simple set of wrapper classes will allow you to
abstract away from IoC specifics anywhere except your entry point.
When your application has several entry points, reusable registration will greatly help to prevent repeating the same
registration. This copy\paste is always bad. And applications have
several entry points quite often. For example, consider the scenario
of cross-platform application having a separate entry point for
every platform it targets. Or business logic reused in web site and
in background process.
With reusable registration, you can build a very effective testing system. You will be able to run a whole layer from tests,
mock whole layers in automated way, and do it very effectively,
minimizing efforts on writing tests.
See my blog article illustrating these points in more detail, with a working sample.

Some architecture and design guidance regarding PRISM and WPF

I have a few questions regarding WPF MVVM application development with PRISM framework:
Should modules in a modular application contain data access code ?
If modules depend on code present in an infrastructure project like the "Stock Trader RI" in the prism documentation does, wouldn't that cause tight coupling between those modules and the infra. project, aren't modules suppose to be self contained functionality !?
I like the DDD (Domain Driven Development) mythology that all code should depend on the business logic layer, thus no "dependency arrows" should go out of the BLL, instead they should go into the BLL (eg. the DAL depends on interfaces in the BLL and then you can use a DI Container to wire everything), and I think that the modules are the BLL of the application, so I don't want them depending on anything, can you achieve that in a modular PRISM app (how) ?
Yes, since a Prism application is usually only made up of modules, then if you want data accessed in your application you will have to access it from the modules in some manner.
Managing dependencies is important. I try to examine what my module does in order to decide whether it makes sense for it to reference my infrastructure project or not. For example, if you were creating an event logging module, you might want to consider putting that interface in a common library that isn't your infrastructure project, because you may re-use that for other projects. However, I do not mind my project specific modules referencing the infrastructure project. The modules still allow me to enforce loose coupling, swap out modules at will to add or remove features, or swap the UI if I were to slice the application horizontally instead of vertically.
I'm not quite sure what you mean by not depending on "anything". I imagine they still depend on the .NET core libraries. So what about Prism? Is that allowed? If you are concerned about them referencing Prism or your infrastructure project you could always have your BLL code in separate DLLS that your modules reference and implement the model repositories, view model logic, and view logic inside of.

Categories