asp.net 5 dependency injection in multiple projects - dependency-injection

I've got an ASP.NET 5 dnxcore solution with some projects to separate my logic:
API
Core (with services for business logic)
DAL (repository interfaces)
Entity Framework (the repositories implementations)
Now I use DI to call my services in the constructors of my API controllers:
private readonly IMyService _myService;
public Controller(IMyService myservice){ _myService = myService; }
The services in my core get the repository thru constructor injection too:
private readonly IMyRepository _myRepo;
public MyService(IMyRepository myRepo){ _myRepo = myRepo; }
Currently I need to define my DI container in the startup class of my API to make it work.
My question is, how can I put the 'building' of the DI container of the repositories in my services in my Core-project. This way, my API is loosely coupled of the fact that my services use Entity Framework, so I can change to, for example, mongodb without changing my API project.

My question is, how can I put the 'building' of the DI container of the repositories in my services in my Core-project. This way, my API is loosely coupled of the fact that my services use Entity Framework, so I can change to, for example, mongodb without changing my API project.
You could, but you shouldn't do that.
Dependency Injection is the practice of making loosely-coupled classes throughout the libraries that can be plugged together (often in many ways).
However, each application should have a composition root, which is the one place in the application where we put the coupling code. Our first instinct as developers is to try to farm the coupling code off into its own library, but that is an urge that you should resist. See composition root reuse.
Mark Seeman's illustration sums it up well. Avoiding transitive dependencies is what is desired when using DI in order to flatten the dependency graph. This ensures assemblies can be used/tested in isolation without dragging along unnecessary dependencies, which in turn makes maintenance easier.
That said, many DI containers have a way to organize the configuration of certain parts of the application by using modules. In Autofac, the documentation for modules is here.

You can easily add an extension method of IServiceCollection into your services layer and use it to register its own dependencies.
Then in the startup you just call the method on the service layer without having any reference to EntityFramework in your web app.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace your.service.layer
{
public static class MyServiceCollectionExtensions
{
public static IServiceCollection AddMyServiceDependencies(this IServiceCollection services)
{
services.AddScoped<My.Data.Tier.DbContext, My.Data.Tier.DbContext>();
}
}
}
Startup:
using your.service.layer;
public void ConfigureServices(IServiceCollection services)
{
services.AddMyServiceDependencies();
}
Now your web app only needs a reference to your service layer and it is not directly dependent on EntityFramework.

As NightOwl888 have said, you should have a CompositionRoot in your application, the place where all your dependencies are set.
What I did is this:
1. Create a Core Class Library named CompositionRoot.
2. Add a class to handle your dependencies:
public class DependencyMapper
{
public static void SetDependencies(IServiceCollection serviceCollection, IConfigurationRoot configuration)
{
serviceCollection.AddEntityFramework()
.AddDbContext<SonoPeopleContext>(options =>
options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
);
MapperConfiguration mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfileConfiguration());
});
serviceCollection.AddSingleton<IMapper>(sp => mapperConfiguration.CreateMapper());
serviceCollection.AddScoped<IUserService, UserService>();
}
}
Then you reference your CompositionRoot in your MVC project and in your Startup.cs you just do
DependencyMapper.SetDependencies(services, Configuration);
That's all.

See this question, I have the same problem because my application is DB agnostic and base on the request will need to switch between a document oriented database (noSQL) and transaccional database (SQL).

Related

Is it common to aggregate all dependency injection modules?

I'm using Ninject in a .NET project to handle dependency injection.
I have divided my solution into multiple projects :
Business Logic
FrontEnd
ViewModels
They have carefully selected references :
FrontEnd has a reference to ViewModels
ViewModels has a reference to BusinessLogic
It seems common to initialize the IoC container in the entrypoint of the application (in my case this is the FrontEnd).
But FrontEnd doesn't have a reference to Business Logic, so I'll get an unresolved reference error.
namespace FrontEnd
{
class ServiceModule : NinjectModule
{
public override void Load()
{
this.Bind<AccountViewModel>().ToSelf();
this.Bind<DetailsViewModel>().ToSelf();
this.Bind<ISessionContext>().To<SessionContext>()
.InSingletonScope();
this.Bind<INavigationViewModel>().To<NavigationViewModel>();
this.Bind<ILoggingService>().To<LoggingService>();
// This will not work because MathClient is in the Business Logic assembly
this.Bind<IMathProvider>().To<MathClient>()
.WithConstructorArgument("binding", new BasicHttpBinding())
.WithConstructorArgument("remoteAddress", new EndpointAddress("http://localhost/server.php"));
}
}
}
I feel like aggregating all the dependency injection declaration in the same place isn't the right thing to do.
I though about declaring some static method in the IoC container so that external projects can register their own modules, but that would make things even worse, because it would mean BackEnd has a reference to the FrontEnd :
namespace FrontEnd
{
class ServiceModule : NinjectModule
{
public static void RegisterModule(Module m)
{
...
}
}
}
namespace BackEnd
{
class BackEnd
{
public void Init()
{
ServiceModule.RegisterModule(new Module() ...)
}
}
}
How can I configure all my services into my IoC container without having suspicious references between projects (like Backend -> FrontEnd) ?
It is a common and good practice to have all of your dependency injection configuration code in one place, in the composition root.
Let's imagine that you decide to split your DI configuration code between projects. Actually, it is technically possible. You can create a separate NinjectModule in your BusinessLogic assembly. But after that, you have to load this module in your FrontEnd assembly anyway. It means that you still have to add a reference from FrontEnd assembly to BusinessLogic assembly.
Just configure all services in a top-level assembly. If you need to add some references to low-level modules, do it. It is much better than having a backward reference from the BusinessLogic assembly to some top-level assembly or having a reference from your BusinessLogic assembly to a DI-library.
See this article of Mark Seemann. Your composition code should be
as close as possible to the application's entry point
and:
A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container.

How to eliminate dependency in Startup.cs Asp.net core? [duplicate]

(Related to this question, EF4: Why does proxy creation have to be enabled when lazy loading is enabled?).
I'm new to DI, so bear with me. I understand that the container is in charge of instantiating all of my registered types but in order to do so it requires a reference to all of the DLLs in my solution and their references.
If I weren't using a DI container, I wouldn't have to reference the EntityFramework library in my MVC3 app, only my business layer, which would reference my DAL/Repo layer.
I know that at the end of the day all DLLs are included in the bin folder but my problem is having to reference it explicitly via "add reference" in VS in order to be able to publish a WAP with all necessary files.
If I wasn't using a DI container, I wouldn't have to reference EntityFramework library in my MVC3 app, only my business layer which would reference my DAL/Repo layer.
Yes, that's exactly the situation DI works so hard to avoid :)
With tightly coupled code, each library may only have a few references, but these again have other references, creating a deep graph of dependencies, like this:
Because the dependency graph is deep, it means that most libraries drag along a lot of other dependencies - e.g. in the diagram, Library C drags along Library H, Library E, Library J, Library M, Library K and Library N. This makes it harder to reuse each library independently from the rest - for example in unit testing.
However, in a loosely coupled application, by moving all the references to the Composition Root, the dependency graph is severely flattened:
As illustrated by the green color, it's now possible to reuse Library C without dragging along any unwanted dependencies.
However, all that said, with many DI Containers, you don't have to add hard references to all required libraries. Instead, you can use late binding either in the form of convention-based assembly-scanning (preferred) or XML configuration.
When you do that, however, you must remember to copy the assemblies to the application's bin folder, because that no longer happens automatically. Personally, I rarely find it worth that extra effort.
A more elaborate version of this answer can be found in this excerpt from my book Dependency Injection, Principles, Practices, Patterns.
If I wasn't using an DI container, I wouldn't have to reference
EntityFramework library in my MVC3 app
Even when using a DI container, you don't have to let your MVC3 project reference Entity Framework, but you (implicitly) choose to do this by implementing the Composition Root (the startup path where you compose your object graphs) inside your MVC3 project. If you are very strict about protecting your architectural boundaries using assemblies, you can move your presentation logic to a different project.
When you move all MVC related logic (controllers, etc) from the startup project to a class library, it allows this presentation layer assembly to stay disconnected from the rest of the application. Your web application project itself will become a very thin shell with the required startup logic. The web application project will be the Composition Root that references all other assemblies.
Extracting the presentation logic to a class library can complicate things when working with MVC. It will be harder to wire everything up, since controllers are not in the startup project (while views, images, CSS files, must likely stay in the startup project). This is probably doable but will take more time to set up.
Because of the downsides I generally advice to just keep the Composition Root in the web project. Many developers don’t want their MVC assembly to depend on the DAL assembly, but that should not be a problem. Don't forget that assemblies are a deployment artifact; you split code into multiple assemblies to allow code to be deployed separately. An architectural layer on the other hand is a logical artifact. It's very well possible (and common) to have multiple layers in the same assembly.
In this case you'll end up having the Composition Root (layer) and the Presentation Layer in the same web application project (thus in the same assembly). And even though that assembly references the assembly containing the DAL, the Presentation Layer still does not reference the DAL—this is a big distinction.
Of course, when you do this, you're losing the ability for the compiler to check this architectural rule at compile time. But most architectural rules actually can't be checked by the compiler. In case you're afraid your team won't follow the architectural rules, I'd advise introducing code reviews, which is an important practice to increase code quality, consistency and improve the skills of a team. You can also use tools like NDepend (which is commercial), which help you verifying your architectural rules. When you integrate NDepend with your build process, it can warn you when somebody checked code in that violates such architectural rule.
You can read a more elaborate discussion on how the Composition Root works in chapter 4 of my book Dependency Injection, Principles, Practices, Patterns.
If I wasn't using an DI container, I wouldn't have to reference
EntityFramework library in my MVC3 app, only my business layer which
would reference my DAL/Repo layer.
You can create a seperate project called "DependencyResolver".
In this project you have to reference all your libraries.
Now the UI Layer doesn't need NHibernate/EF or any other not UI relevant library except of Castle Windsor to be referenced.
If you want to hide Castle Windsor and DependencyResolver from your UI layer you could write an HttpModule which calls the IoC registry stuff.
I have only an example for StructureMap:
public class DependencyRegistrarModule : IHttpModule
{
private static bool _dependenciesRegistered;
private static readonly object Lock = new object();
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, args) => EnsureDependenciesRegistered();
}
public void Dispose() { }
private static void EnsureDependenciesRegistered()
{
if (!_dependenciesRegistered)
{
lock (Lock)
{
if (!_dependenciesRegistered)
{
ObjectFactory.ResetDefaults();
// Register all you dependencies here
ObjectFactory.Initialize(x => x.AddRegistry(new DependencyRegistry()));
new InitiailizeDefaultFactories().Configure();
_dependenciesRegistered = true;
}
}
}
}
}
public class InitiailizeDefaultFactories
{
public void Configure()
{
StructureMapControllerFactory.GetController = type => ObjectFactory.GetInstance(type);
...
}
}
The DefaultControllerFactory doesn't use the IoC container directly, but it delegates to IoC container methods.
public class StructureMapControllerFactory : DefaultControllerFactory
{
public static Func<Type, object> GetController = type =>
{
throw new InvalidOperationException("The dependency callback for the StructureMapControllerFactory is not configured!");
};
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}
return GetController(controllerType) as Controller;
}
}
The GetController delegate is set in a StructureMap Registry (in Windsor it should be an Installer).
There is a dependency : if an object instantiate another object.
There is no dependency : if an object expects an abstraction (contructor injection, method injection ...)
Assembly References (referencing dll, webservices..) are independant from the dependency concept, because to resolve an abstraction and be able to compile the code, the layer must reference it.

How to use .net core dependency injection in multiprojects solution?

I'm new to asp.net core.
What I'm trying to do is to build multi projects solution and use dependency injection to pass interfaces between projects.
What I know is that in ASP.NET core project we have ConfigureServices method in startup.cs file to register our interfaces and their implementations like this:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddTransient<IMyInterface,MyImplementation>();
.....
}
This is good if you have classes all in the same project, but what if I have multi projects ?
Usually what I'll do is create separate project with installers (Windsor installers) to register the needed interfaces and their implementations.
In .net core we can do this by creating static ServiceCollection(); and get from it static IServiceProvider to use it any time to get any service you register:
public static IServiceCollection _serviceCollection { get; private set; }
public static IServiceProvider serviceProvider { get; private set; }
public static RegisterationMethod() {
_serviceCollection = new ServiceCollection();
_serviceCollection.AddSingleton<IMyInterface,MyImplementation>();
.....
serviceProvider = _serviceCollection.BuildServiceProvider();
}
public T GetService<T>() where T : class
{
return serviceProvider.GetService<T>();
}
Now we call RegisterationMethod from ower startup project and continue to develop as usual with always registering the services in this class.
The problem in this approach is if I used it in ASP.NET core project I'll have two places to register the services, this one and the one in the startup.cs file which has ConfigureServices(IServiceCollection services) .
You may say,
OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using.
But in this way I'll be tight coupled to the dependency injection module of the .net core.
Is there more clean way to do this ? or should I have replace the default DI with Windsor for example ?
...in ASP.NET core project[s] we have ConfigureServices... to register our interfaces and their implementations... This is good if you have classes all in the same project, but what if I have multi projects?
It doesn't matter that you have multi projects. The same principle applies:
Put your composition root in your application, as close to the entry point as possible.
Lets assume that you have a single application that references several class libraries. In your application's Startup class, use ConfigureServices to register all of the dependencies. In each of the class library projects, use constructor injection. It does not matter whether your classes live in the same or in different projects.
OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using.
Yes, that's the way to do it. Here is an example from the github.com/aspnet/logging repository:
public static IServiceCollection AddLogging(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));
return services;
}
Based on your comments...
...it sounds like you are trying to avoid having a composition root in your application. The composition root is the single location where we register dependencies with the dependency injection container. The composition root is placed as close as possible to the application's entry point (the ConfigureServices method, for instance) and it belongs in the application not in its libraries.

using ninject with layered asp.net mvc application and Entity Framework edmx

I'm working in asp.net mvc 4 with Entity Framework 5 (with edmx). I'm trying to get Ninject to work correctly, but using the bindings has got me quite confused. I've seen Ninject being used before, but that was in a WCF project where the DI was being set in the WCF-layer.
Right now I have 4 layers:
DataAcces (contains edmx and repositories, which I will show later)
BusinessLogic (standard BL)
Common (models)
Gui (a mvc4 project)
Now here's the tricky part: I want to use DI here. The way I saw it being used in my previous WCF-project was that my WCF-layer went to my DataAccess so I can use the kernel.bind.
Now I don't want that here. I'm not using WCF. I also don't want to call my DataAccess in my Gui.
Since I said I'd show some code for insight:
Repository in DataAccess
public class Repo: IRepo
{
Entities context = new Entities();
public IQueryable<PictureSource> PictureSource
{
get { return context.PictureSource; }
}
}
my IRepository is just this:
public interface IRepository
{
IQueryable<PictureSource> PictureSource { get; }
}
What I want to be able to do is in my BusinessLogic. I want to be able to do the following:
public List<Picture> GetStuff(IRepository Repo)
{
//code
}
Now I've looked a lot on the internet. About 80% of the examples use Web Apim which is useless to me. The other 20% just seem to do whatever they want "because it's just a demo" and violate Gui-BL-DA principle. I've seen examples consisting of a single layer to examples doing Business Logic in Data Access.
The ninject wiki also didn't help me as I'm new to DI and I've only seen it being used in an existing application.
Try to code using Poor-Man's-DI. Inject your dependencies in your constructor!
public class BusinessLogic
{
private _repository;
public BusinessLogic(IRepo repository)
{
_repository = repository;
}
public List<Picture> GetStuff()
{
_repository.PictureSource.Where(x=>x.Published == false);
}
}
Once you have your codebase right, register your dependencies in Ninject. Ninject then takes care to inject your Repository to you BusinessLogic class.
Please note that you have an IQueryable in your IRepo, which you should avoid (http://www.infoq.com/news/2012/03/IQueryable-api)
Edit:
This would be your solution structure and the references:
MVC4 (GUI)
-> DataAccess
-> BusinessLogic
-> Common
You need to setup this references, to wire up your bindings.
BusinessLogic
-> Common (including your Interfaces!)
DataAccess
-> Common
IKernel kernel = new StandardKernel();
kernel.Load("*.dll");
This should load NinjectModules in all .dlls in the current directory. So you don't need to add reference to the DAL.

ASP.NET MVC Dependency Injection Unity with WCF services - working sample solution

I'm looking for a working sample of an ASP.NET MVC web application that uses Unity and calls an WCF service. I've looked at a lot of explanations on how to add dependency injection to WCF services but frankly I'm a little over my head here. It doesn't help that I'm new to WCF services as well.
I'm currently using Unity with Contructor injection for our ASP.NET MVC applications but so far we aren't using any WCF Web Services. The plan is to start using web services and I'm very confused on how to incorporate Unity with them.
I would love a nice working sample that I could walk through to better understand how to go about it.
I will try to provide you with some guidance.
Let's suppose that you have an existing products WCF service that is defined like this (we don't care about the implementation, that's not important for the moment, you could implement it as you wish, varying from hardcoded values, passing through a SQL database and an ORM, to consuming another service on the cloud):
[DataContract]
public class Product
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
[ServiceContract]
public interface IProductsService
{
[OperationContract]
Product Get(int id);
}
Now in your ASP.NET MVC application the first step is to add a service reference to it by pointing to the WSDL. This will generate proxy client classes.
Next you could add the Unity.Mvc3 NuGet package to your MVC application
Then in your Application_Start you could configure the container (obviously this configuration could be externalized into a separate method to avoid cluttering your Global.asax with it):
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
var container = new UnityContainer();
container
.RegisterType<IProductsService, ProductsServiceClient>()
.Configure<InjectedMembers>()
.ConfigureInjectionFor<ProductsServiceClient>(new InjectionConstructor("*"));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
IProductsService and ProducsServiceClient used in this configuration are the proxy classes generated when you imported the web service definition.
From now on things become trivial:
public class HomeController : Controller
{
private readonly IProductsService _productsService;
public HomeController(IProductsService productsService)
{
_productsService = productsService;
}
public ActionResult Index()
{
var product = _productsService.Get(1);
return View(product);
}
}
and some corresponding Index view:
#model Product
<div>
#Html.DisplayFor(x => x.Name)
</div>
As you can see from this example thanks to the IProductsService abstraction, HomeController is totally decoupled from any concrete implementations of the service. In Today in your Global.asax you decided to use WCF (ProductsServiceClient), but tomorrow you could decide to use some completely different implementation. With a single changes in your DI container configuration you could switch the implementation. Thanks to this weak coupling, your controllers are fully unit testable in isolation.
What is important to realize here is that your business is the Product class and the IProductsService interface. This is what reflects your domain. This is the M in MVC. Implementations could change, but this should stay the same, otherwise you have wrongly identified your business requirements which could be catastrophic in long term.
Remark: one thing that I haven't covered in this example, and which is very important, is the usage of view models. In a properly architected ASP.NET MVC application you should never pass domain models to your views (in this example the Product class). You should use view models. View models are classes that are specifically designed for the requirements of a given view. So in a real world ASP.NET MVC application you would have a ProductViewModel class which to which the Product domain model will be mapped in the controller action and it is this ProductViewModel that will be passed to the view. Those view models should be defined in the MVC project as, contrary to your domain models, they are not reusable and reflect only the specific requirements of a single view. To ease the mapping between your domain models and view models you may take a look at AutoMapper.
It sounds like you're already injecting your MVC Controllers using Unity and all you want to do is start injecting the WCF services you host as well. To inject WCF services, you need to use an IInstanceProvider.
Complete working solution is here:
http://orand.blogspot.com/2006/10/wcf-service-dependency-injection.html
You need 4 very very simple classes:
MyServiceHostFactory
MyServiceHost
DependencyInjectionServiceBehavior
DependencyInjectionInstanceProvider
define those, specify your new ServiceHostFactory:
<%# ServiceHost
Service="NamespaceC.ServiceLayer, AssemblyC"
Factory="NamespaceD.MyServiceHostFactory, AssemblyD"
%>
and you're done.
I know it's a bit late in the game, but I've written a Nuget package to simplify the process of using WCF in your MVC/WebApi app, and it leverages Unity.
Check out Unity.Mvc.Wcf on Codeplex or GitHub for details.

Resources