Is it common to aggregate all dependency injection modules? - dependency-injection

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.

Related

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.

asp.net 5 dependency injection in multiple projects

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).

Where's Simple Injector's equivalent of StructureMap's ObjectFactory

I am in the process of migrating from StructureMap to Simple Injector in a ASP.NET MVC3 application.
I am using the MVC3 extension for controller DI, but I am running into an issue with trying to replace the static aspects of StructureMap. We have calls to
StructureMap.ObjectFactory.GetInstance<Interface>()
throughout different layers of the app. It does not look like Simple Injector has a way to do that.
Am I missing something? Or is Simple Injector not applicable for my application?
Please advise and thanks in advance.
Allowing the application to directly access the container is considered to be bad practice. It is an form of the Service Locator anti-pattern.
Because this is considered to be a bad thing, Simple Injector does not contain anything like StructureMap's ObjectFactory.GetInstance. And as a matter of fact, the author of StructureMap is considering the removal of the ObjectFactory API in a furure release of StructureMap.
However, nothing stops you from storing the SimpleInjector.Container instance in a static field and let the application use this:
// Service Locator implementation in low application layer.
public static class ObjectFactory
{
private static SimpleInjector.Container container;
public static void SetContainer(Container container)
{
ObjectFactory.container = container;
}
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
}
In Composition root:
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
// Set the service locator here
ObjectFactory.SetContainer(container);
}
So there is no limitation in the Simple Injector that prevents you from doing this, but frankly, you are already witnessing one of the reasons why Service Locator is a bad thing: you switched containers and now you have to change application code.
Perhaps for now it is easiest for you to save the container in a static field (as shown in the example above), but please take the time to understand why this pattern is bad, and do refactor away from this pattern towards dependency injection (and especially constructor injection).

Dependancy issue with static utility classes with repository (.NET MVC project)

I have an MVC project with the standard IoC setup that uses StructureMap to inject repositories into controller constructors.
I also decided I wanted to have a static "utilities" class where I could have common methods that can be called by different controllers. So for example, I have:
public static IEnumerable<CountryCode> GetCountryList()
{
ICountryCodeRepository repo = ObjectFactory.GetInstance<ICountryCodeRepository>();
IEnumerable<CountryCode> countries = repo.GetAll();
return countries;
}
As you can see, that directly creates a repo object from the ObjectFactory. The problem, now, is that when I want to unit-test my controllers, I can mock the repos for the controllers, but not the repos in the utilities class (which the controller eventually calls) I'm sure there are other reasons why my utilities class is wrong, but this is what I see so far. I've also read some stuff saying what I have is bad design, I just don't know how to fix it.
I was thinking about having the GetCountryList() function to accept a repo object
GetCountryList(ICountryCodeRepository _repo)
and the calling controller would pass it in, but isn't that just creating another dependency concern because all controllers will have to know what the utility functions need?
Or is it possible to use StructureMap somehow to inject these utility methods?
It's at least OK that you know that what you are doing is bad design. That's fine and people reading this post will know it as well and avoid doing the same mistake as you.
But now to the point, you could use a provider in your static class:
public static class Foo
{
public static Func<ICountryCodeRepository> CountryRepoProvider =
() => ObjectFactory.GetInstance<ICountryCodeRepository>();
public static IEnumerable<CountryCode> GetCountryList()
{
return CountryRepoProvider().GetAll();
}
}
and now in your unit test you could mock it:
Foo.CountryRepoProvider = () => mocha;
or if you are using ASP.NET MVC 3 and you DI framework uses a dependency resolver you could improve this code by at least making it DI framework agnostic:
public static IEnumerable<CountryCode> GetCountryList()
{
var repo = DependencyResolver.Current.GetService<ICountryCodeRepository>();
return repo.GetAll();
}
Now in your unit test you could of course write a custom dependency resolver which will spit mocked instances of your services.
And now when you look at this code you might really say to yourself: What am I doing? I am writing a static class with one liner methods delegating to a repository I am fetching from the DI. What's the point when I can benefit from my DI framework to directly inject the instance of this repository wherever I need it and then simply call the method I need on it? What am I unit testing in those one liner static methods? Why am I wasting my time.
And if of course you had more complex logic to handle you would simply write a service layer which will take the necessary repositories as constructor dependencies and perform the complex business operations on them. Then you will simply configure your DI framework to inject those ready to be used instance of the service in your controllers or wherever you need it. See? No need of any static class. Weak coupling and unit testing friendly code.

Structuring Dependency Injection for a Class with Injected Services AND Data

I am using an IoC container that uses constructor injection (Castle Windsor, for example). I have the following (example) class which manages a product...
public class ProductDataManager
{
public ProductDataManager(Product product, IProductDataLoader productDataLoader)
{
}
// a number of methods here that manage the products data in different ways...
}
It has a dependency on a Product which is only known by the classes consumer. It also has a dependency on a product data loader service. I define the implementer of this service in the IoC container.
How do I define this class (ProductDataManager) in the IoC container (and/or the consuming class) so that the service dependency (IProductDataLoader) can be injected by the IoC container and the data dependency (Product) can be passed by the consuming class?
Or is this a code smell? If so, how can this be modified?
You can use the TypedFactoryFacility and do something like this (off the top of my head)... first, define an interface for your abstract factory:
public interface IProductDataManagerFactory
{
ProductDataManager Create(Product product);
}
Register the factory like so:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IProductDataManagerFactory>().AsFactory());
Now services can depend on IProductDataManagerFactory and have Windsor invoke container.Resolve through an automagically implemented factory.
Note that the parameter name product in the method signature must correspond to the parameter name in the ctor of ProductDataManager.

Resources