If I use the Repository Pattern in an ASP.NET MVC Application I need DI to let the program know, to interface the classes must be mapped. If I implement Unity I need to add the DAL project to my MVC project, and then register the types in the global.asax.
In my mind, I think it's bad to add the namespace of the DAL Layer to the MVC project, there is a business layer also in between. I think, it would be beautiful to inject the DAL classes in the business layer and only the business layer mappings in the MVC app.
What's the way to go here? Do you have suggestions?
UPDATE:
To make it clear to me. In the service layer, there are only DTO's and the DI for the business and data access layer. In the service layer I map the DTOs to the domain model. What I don't understand is, how can I call the business layer methods then?
If you want to be pragmatic, a true 3-tier architecture requires a service layer. Between the service and MVC are Data Transfer Objects (DTOs). The service layer hides both the DAL and the business layer.
If you set it up like this, the MVC itself knows nothing about DAL, only DTOs and Service (contracts).
Even if you don't use a distinct service layer, you can accomplish what you want, which is to decouple the MVC application from the DAL project using DI.
The way to do this is to add a couple of projects/assemblies in between that wires up your IoC container with specific instances of the interfaces you have defined.
I typically use this naming convention:
MyCompany.MyProject.Infrastructure
MyCompany.MyProject.Abstract
Your main MVC project would then have a reference to your Abstract and Infrastructure projects. Your Infrastructure project would have a reference to the Abstract and instance specific projects like the Business and DAL projects. Within Infrastructure project you wire up the dependencies.
You'll have to setup a mechanism for your MVC project to bootstrap your IoC in the Infrastructure assembly. You can do that in your global.asax or as an App_Start method and call a Registration class within your Infrastructure assembly.
We use StructureMap, but the concept is the same. Here's some sample code.
In your MVC App, create a App_Start method to setup the DI.
public static class StructuremapMvc
{
public static void Start()
{
// Create new Structuremap Controller factory so Structure map can resolve the parameter dependencies.
ControllerBuilder.Current.SetControllerFactory(new StructuremapControllerFactory());
IContainer container = IoC.Initialize();
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
}
}
In your Infrastructure assembly, wire up the dependencies.
public static class IoC
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
x.For<IRepositoryNum1>().Use<Num1Repository>();
x.For<IRepositoryNum2>().Use<Num2Repository>();
x.For<IRepositoryNum3>().Use<Num3Repository>();
});
return ObjectFactory.Container;
}
}
You should use DI to inject the Domain/DAL interfaces into your constructors. This has a lot of upside including allowing you to moq your interfaces when you write your unit tests. You can use Autofac to handle the injection.
Related
I have a solution with multiple projects - similar to below:
WebAPI
ICustomerService.cs
Business Logic
CustomerService.cs
IDatabaseService.cs
Database Access
DatabaseService.cs
Previously the WebAPI project had a reference to the business logic, then that had a reference to database access. I am trying to invert this logic.
Currently, I am using Unity in my WebAPI project to resolve the interfaces with implementations from the business logic layer, however once I have inverted my logic so that the business logic layer has a reference to the WebAPI layer the Unity registration doesn't work without a circular reference:
var container = new UnityContainer();
container.RegisterType<ICustomerService, CustomerService>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
When I am trying to register my types, the ICustomerService lives in the top project, CustomerService is invisible to it.
I have read about having a separate project to house the unity configuration but that would create a circular reference also. How can I make this work?
Why do you wanna invert that? Seems to me like the only way of doing it. The WebAPI project is the main entrance (if it was self-hosted, it would contain a programs.cs). This project would also contain your composition root for setting up dependency injection and resolving types (this is handled by the WebAPI). See also Composition Root. Could you explain to me the benefit of doing this?
Also be aware that it is bad practice to spread out the IoC container cross projects. Only the composition root (main) should know about the fact that Unity is being used. Also avoid using the ServiceLocator pattern.
The objects in the different projects should just have a reference/dependency through for example the constructor.
If you think about it like that the Controller is dependent on ICustomService, CustomerService is dependent on IDatabaseService.
Also a note: I would put the implementation and interface in the same projects.
WebAPI
Controller
Business Logic
ICustomerService.cs
CustomerService.cs
Database Access
IDatabaseService.cs
DatabaseService.cs
You are on the right path. Your controller should inject the icustomerservice implementation in the constructor and the service should inject the idatabaseservice in its constructor.
public FooController(ICustomerService svc)
...
public CustomerService(IDatabaseService db)
...
And add the database DI config
container.RegisterType<IDatabaseService, DatabaseService>();
container.RegisterType<ICustomerService, CustomerService>();
When you are ready to use the new implementation, just change the reference in the config to instantiate the new implementation.
The interfaces should be in a project together and the implementation should be in a project together. The new and old implementation should share a common interface.
I'm trying to design WebApi application with using IoC like Ninject. I have the following layers(3 projects):
Domain(Repository) layer
Service
Web API application core
The Repository layer has interface IRepository<T> and a few implementations of it. And in the Service also exists interface IService<T> with a two different implementations.
Could you please advise me should I use DI container (Ninject) in WebApi project to bind IService<T> and ServiceConcrete<T> and DI container in the Service project to bind IRepository<T> and RepositoryConcrete<T>?
Or maybe should I use only one DI in WebAppi project?
A practical way I have found to set up Ninject modules can be found below.
Overview
Create an assembly called DependencyResolution
Create the Ninject modules (that you will utilize in your WebAPI project)
Have only this DependencyResolution and your Domain projects referenced in your WebAPI project
Initalize/register your modules in NinjectWebCommon.cs
Details
Should be easy as create a project, add Ninject as reference from NuGet for instance.
Add new class file(s) to this project named after the modules you want to create like: ServiceModule.cs, RepositoryModule.cs, etc.
Create your Ninject module(s). For detailed instructions on this you can refer my answer on this.
In your WebAPI project, you add reference to this just created DependencyResolution project and your Domain project.
Initializing/registering your just created module(s) in the WebAPI project's NinjectWebCommon.cs as:
private static void RegisterServices(IKernel kernel)
{
var modules = new List<INinjectModule>
{
new ServiceModule(),
new RepositoryModule()
};
kernel.Load(modules);
}
I will also try to address another concern that is loosely related to your question. I think your current layering setup would need a bit to be changed.
The basic and probably my biggest problem with your layers are that you mix up and therefore tightly couple the Domain and Repository which is clearly an infrastructural concern.
I would suggest to re-architect your layers as:
Domain
Services
Infrastructure (Repository implementations could go here for instance)
Dependency Resolution
WebAPI
Do not forget that your Domain layer should not have any idea about infrastructural details like Repository, else you are going to tightly couple your domain with unneeded implementation details.
EDIT: From the comments I see that you have some concerns about where to place and how to name things which is obviously one of the hardest things in programming.
So my thoughts on clearing this confusion up are:
Layer: is a logical separation or collection point of classes, methods, etc. that those belong together.
Each layer can consists of multiple projects or assemblies. So if you want to categorize your projects into layers, you could create directories in your solution named about your layers and place the individual projects inside these directories. It's really just a matter of taste in the mouth, take it just as a tip.
Example structure
Solution root
Core directory
Domain assembly: the root of you domain where you have your business or domain entities AND the all the interfaces that your domain is using.
Domain services assembly (just could be in Domain assembly as well)
Services directory
Application services assembly: for example an example this assembly houses services or facades that spans operations accross multiple domain entities or aggregates, etc.)
Infrastructure directory
Repository assembly: this is where you have the implementations of your EF repositories
Custom logging/email/whatever else assemblies or implementations that doesn't belong to the domain.
DependencyResolution assembly: this is the place of your NInject modules and all IOC container related wirings.
UI directory
WebAPI assembly
Asp.Net MVC assembly
Summary
The Dependency Resolution project has references to any needed assemblies (Domain for interfaces, Services/Infrastructure for their implementations) and wire them altogether for later use.
The WebAPI project would only need to have reference added Domain and Dependency Resolution so then you could just ask for your interfaces in your WebAPI methods/functions public constructor and Ninject will do the dirty job for you behind the scenes.
Please don't forget that this is just an easy quick 'n dirty architecture suggestion of mine, without knowing your exact requirements and use cases.
If I understand your question, you're having troubles configuring your Repository layer because your config code is in your application layer, which probably only references your service layer (which in turn references your repository layer). What I've done in order to get around this is first create your configurations in modules (these can live on any layer, but you must reference Ninject)
For your repo layer:
public class RepoNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IMyRepo>().To<MyRepo>();
}
}
create a similar Module in your service layer:
public class ServiceNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IMyService>().To<MyServce>();
}
}
Then, in your application layer, you can load the modules dynamically (this is what NinjectWebCommon.cs looks like):
private static void RegisterServices(IKernel kernel)
{
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());
}
More info on modules: https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel
I've read few articles and watched many lectures/tutorials on YT about DI and IoC, but I didn't find any recommended layout of catalogs in VS solution.
I'm talking about the project (a game for example) where you have few classes/interfaces, logger, database provider, wcf services, wpf presentation layer (that's actually different project)...
Is there any pattern project, that shows how should I organize my project, so next, experienced programmer will not waste time figuring out what's going on? Like we're talking about "self commented code", I'm talking about "self commented project structure".
For example, should I put all interfaces into "Interfaces" catalog? Or should I (in case of logger) create "Logger" catalog and put there interface, classes, class with extension methods (all, focused on logging). Code focused on Board, in "Board" catalog. Separate catalog for "Field" etc etc..
Right now the structure looks like that. I'm not sure about "Business" there and Logger. I have interface in different catalog then other logger classes. Should I call Log4Net provider? or adapter? or decorator? It's just a logger class implementing ILogger interface. Here is the screen: link
Here is the sample code (there is no IoC yet, but everybody will notice there will be 3 interfaces there mapped. Very simple):
public class Game
{
public IBoard Board { get; set; }
public Game(IBoard board)
{
Board = board;
}
}
public interface IBoard {}
public class Board : IBoard
{
public IField[,] Fields { get; set; }
public Board(IField field, int boardWidth, int boardHeight)
{
Fields = new IField[boardHeight, boardWidth];
Fields.Initialize();
}
}
public interface IField {}
public class Field : IField {}
public interface ILogger
{
void Log(LogEntry entry);
}
What I usually do is that I have a MyApplication.Core (Class library) layer, which contains all the applications interfaces with as little (read: none) third-party dependencies, e.g. ILogger, ICommand or IQuery<TResult>.
Next I have a MyApplication.Domain (Class library) layer which contains all the application domain specific knowledge - this is the business layer. This is implementations of the core interfaces ICommand, IQuery<TResult>. These implementations then have an dependency on e.g. ILogger. Never concrete implementations.
Then I have the MyApplication.Infrastructure (Class library) which is where all the service interfaces from MyApplication.Core is implemented, e.g. ILogger. Here you can have dependencies on third-party libraries such as Log4Net.
Then last I have the presentation layer, which is in my case usually an MVC applications so I would name this MyApplication.Web.Mvc. All controllers have only dependencies on the interfaces. Never concrete implementations. This layer is also responsible of bootstrapping all the interfaces to the concrete implementations using a Composition Root.
TL;DR:
MyApplication.Core (Application Interface Layer)
MyApplication.Domain (Business Logic)
MyApplication.Infrastructure (Implementations of Application Interface Layer)
MyApplication.Web.Mvc (Presentation and Composition Root Layer)
From Microsoft's "Common web application architectures".
The Application Core Project
The Application Core holds the business model, which includes entities, services, and interfaces. These interfaces include abstractions for operations that will be performed using Infrastructure, such as data access, file system access, network calls, etc. Sometimes services or interfaces defined at this layer will need to work with non-entity types that have no dependencies on UI or Infrastructure. These can be defined as simple Data Transfer Objects (DTOs).
The Infrastructure Project
The Infrastructure project typically includes data access implementations. In a typical ASP.NET Core web application, these implementations include the Entity Framework (EF) DbContext, any EF Core Migration objects that have been defined, and data access implementation classes. The most common way to abstract data access implementation code is through the use of the Repository design pattern.
In addition to data access implementations, the Infrastructure project should contain implementations of services that must interact with infrastructure concerns. These services should implement interfaces defined in the Application Core, and so Infrastructure should have a reference to the Application Core project.
The ASP.NET Core Web App Project
The user interface layer in an ASP.NET Core MVC application is the entry point for the application. This project should reference the Application Core project, and its types should interact with infrastructure strictly through interfaces defined in Application Core. No direct instantiation of or static calls to the Infrastructure layer types should be allowed in the UI layer.
A starting point repo for Clean Architecture with ASP.NET Core
https://github.com/ardalis/CleanArchitecture
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/
I'm trying to get more and more familliar with DI and IoC. At this moment I understand the concept and implementation of DI with the controllers in an MVC application. But assume I have a layered application.
The Controllers call businesslogic classes and the businesslogic clases call the repository classes.
How do I setup the second layer, the businesslogic to repository part with DI. This ensures I can test on different levels in my application. What I don't want to do is passing the dependancy to the repository from the controllers.
Hope someone can give some hints on this.
Patrick
Minimalistic example how to implement using Ninject. This is not absolute truth about DI/IoC, just a brief example how it could be done.
Configuration
// repositories
base.Bind<IMyRepository>().To<MyRepository>();
// services
base.Bind<IMyServices>().To<MyServices>();
When ever IMyRepository is used then it will use concrete implementation MyRepository.
Controller
public class MyController : Controller
{
private readonly IMyServices _myServices;
public AnimalController(IMyServices myServices)
{
_myServices = myServices;
}
// your actions
}
Again, inside MyService there is a similar pattern (constructor injection)
Service
public class MyServices : IMyServices
{
private readonly IMyRepository _myRepository;
public MyServices(IMyRepository myRepository)
{
_myRepository = myRepository;
}
public void Example()
{
_myRepository.PleaseDoSomething();
}
}
Also remember that there are lots of other things in the ASP.NET MVC where IoC can be used:
localization
authorization
model metadata provider (for example localized error messages)
custom model binders
controller factory
etc.
Update
In the example code there was a bug. Dependency injection was not done in the service. Now it should be correct.
Update 2
I think it's highly recommended to use NuGet packages to bootstrap your app. Saves time, might apply some "best practices", other projects will get similar base etc. Here are some instructions for different IoC's + MVC 3
Ninject
Autofac
StructureMap
put simply, each layer in the hierarchy asks for the dependencies on the next layer down via a constructor argument, which is an interface.
your controllers ask for their dependencies on a business logic through their constructors. They do this by a dependency on an interface to the business logic not by asking for a particular implementation. You create an interface for your business logic class, and inject an implementation of that interface into your controller, this can be done manually or you can get a DI container to do it for you. Your controller knows nothing about the repository classes (or any other dependencies of any implementation of the business logic), only about the interface to the business logic class on which it depends.
You then rinse and repeat on the business logic concrete classes.
You create an interface for your repository classes and the business logic classes which require those ask for them through their constructor, and then you again inject the dependency in either manually or via a DI container.
You application should have a composition root where all of this setup takes place, which is where you either manually wire up your dependencies (create the lowest objects first and then pass them in to the constructors of the higher up objects as you create those), or you configure the container with the details of the implementation of various interfaces you have, so that it can then use that information to correctly construct objects which have dependencies.
A DI container just creates and resolves dependencies for types it's configured to. It is unrelated to how do you design your application layers. Why don't you want to pass the repository where it's needed?! Those objects depend on an abstraction and not on implementation.
You configure the DI container to serve a certain instance of Repository anywhere where it's required. The controller receives the repository instance, which then can be passed on to the business layer to be used.
Decoupling means an object doesn't depend on implementation details, that's it. Testing is possible because the dependecies are expressed as interfaces and you can mock them.