Dependency Injection - Passing dependencies all the way down - asp.net-mvc

I have an MVC application with a typical architecture...
ASP.NET MVC Controller -> Person Service -> Person Repository -> Entity Framework DB Context
I am using Castle Windsor and I can see the benefit of using this along with a ControllerFactory to create controller with the right dependencies. Using this approach the Controller gets a Service injected, which in turn knows how to construct the right Repository, which in turn knows the correct DbContext to use.
The windsor config is something like this...
dicontainer = new WindsorContainer();
dicontainer.Register(Component.For<IPersonService>().ImplementedBy<PersonService>());
dicontainer.Register(
Component.For<IPersonRepository>().UsingFactoryMethod(
() => new PersonRepository(new HrContext("connectionString"))));
It this the right way to do it? I don't like the UsingFactoryMethod, but can't think of another way.
Also, what if the Repository needed a dependency (say ILogger) that was not needed by the service layer? Does this mean I have to pass the ILogger into the service layer and not use it. This seems like a poor design. I'd appreciate some pointers here. I have read loads of articles, but not found a concrete example to verify whether I am doing this right. Thanks.

I try to avoid using factory methods (as you mentioned you felt this smelled funny). To avoid this, you could create a database session object that creates a new DbContext. Then your repositories just need to get an instance of IDbSession and use its dbContext property. Then, you can also easily control the scope of the IDbSession object (don't use singleton because it's not thread safe).
I wanted to make that point so that I could make this more important point... Make your constructors take in only objects that are registered in the DI container (no options or configurations in constructors). Options and configurations should be read/writen in classes whose sole purposes it is to read/write those values. If all classes follow this model, then your DI registration becomes easy and classes can just add whatever dependencies they need in their constructors.
If you are trying to use a third party library that has options in constructors, wrap that class in your own class that has an easy to consume constructor and uses a configuration class to read the values needed to pass to the third party library. This design also introduces a layer of abstraction between your code and the third party library which can then be used to more easily swap (or stub) third party libraries when necessary.

Related

Dependency injection - trying to avoid using a service locator

Following the guidelines I read in:
https://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container
I want to try and avoid using a service locator.
But on the other hand, I don't register all the types in the startup.cs file. I don't think this is right that all these internal types are referenced in the main startup.cs
I currently have a factory class that has a collection of builder classes.
Each builder class is in charge of creating a specific object.
I don't want to create all these builder classes in advance as I might not need to use them and creating them is a bit heavy.
I saw an example of how to achieve this in the link above. However the startup.cs class needs to know all these builders. I don't think this is appropriate, I'd rather have the factory class be the only one that is exposed to them. I was trying to understand if there is some kind of func/action method that I can inject from the startup.cs file into my factory class. This func/action will be in charge of creating/registering the builders and then I can activate this func/action within the class factory. I'd like this func/action to receive the interface/class/maybe name of the builder but using generics isn't working. I searched a lot and didn't find any solution so I assume this is not possible.
Seems I have 2 options:
1. Use service locator. This way only the factory class will know the builders. However if in the future, if I want to change the DI I need to "touch" the factory class (I'm contaminating the factory class). Wanted all the DI code to be located only in the startup.cs class.
2. Register the builders in the startup.cs but now the startup.cs is aware of the builders. This kinda couples the code, not really single role of responsibility
It would have been great to inject the factory class a func/action from the startup.cs that would do the registration but the factory class itself activates it.
Is this possible?
I want to try and avoid using a service locator
Great, because the Service Locator is an anti-patttern.
don't register all the types in the startup.cs file.
You should do your registrations in one single 'area' of your application: the start-up path. This area is commonly referred to as the Composition Root (the place where object graphs are composed).
I don't think this is right that all these internal types are referenced in the main startup.cs
No matter how you design it, the startup assembly is the most volatile part of the system and it always depends on all other assemblies in the application. Either directly or transitively (through another referenced assembly). The whole idea of Dependency Injection is to minimize the coupling between components and the way to do this is to centralize coupling by moving it to the Composition Root. By making types internal however, you are decentralizing object composition and that limits your flexability. For instance, it becomes harder to apply decorators or interceptors for those registered types and control them globally. Read this question and its two top voted answers for more information.
I don't register all the types
The concern of having a Composition Root that is too big is not a valid one. One could easily split out the Composition Root into multiple smaller functions or classes that all reside in the startup assembly. On top of that, if you read this, you'll understand that registering all types explicitly (a.k.a. "Explicit Register") is typically pointless. In that case you're probably better off in using DI without a Container (a.k.a. Pure DI). Composition Roots where all types are registered explicitly are not very maintainable. One of the areas a DI Container becomes powerful is through its batch-registration facilities. They use reflection to load and register a complete set of types in a few lines of code. The addition of new types won't cause your Composition Root to change giving you the highest amount of maintainability.
I don't want to create all these builder classes in advance as I might not need to use them and creating them is a bit heavy
Creation of instances should never be heavy. Your injection constructors should be simple and composing object graphs should be reliable. This makes building even the biggest object graphs extremely fast. Factories should be reduced to an absolute minimum.
TLDR;
Register or compose your object graphs solely in the Composition Root.
Refrain from using the Service Locator anti-pattern; Whole applications can (and should) be built purely with Constructor Injection.
Make injection constructors simple and prevent them from doing anything else than storing their incoming dependencies.
Refrain from using factories to compose services, they are not needed in most cases.

Is it a good idea to pass the data context object to controllers with dependency injection?

I am currently using the CustomControllerFactory object to pass services (which each implement an interface) to my controllers.
I am wondering whether it is a good idea to do the same for my data context objects.
Currently at the top of each of my controllers, I have the line:
private dataContextClass db = new dataContextClass();
I have created an interface that dataContextClass implements. I can only see examples online of people passing services in with dependency injection. Is it a good idea to pass the data context object in as well?
Of course it's a good idea. The context is a dependency of your controller, and therefore should be injected if you're using dependency injection. However, you didn't specify what version of MVC you're using, but custom controller factories were deprecated in MVC 3. If you're using that version or later, you should be handling injection via IDependencyResolver. And, in general, it's usually better to just use a full-fledged DI container like Unity or Ninject, than to try to create your own from scratch.

Autofac Container Independence and Relationship Types

We are currently using Autofac as our chosen IoC container. All application code in our reusable assemblies must be kept as clean as possible, so we do not want any direct dependencies on Autofac in our core application. The only place where Autofac is permitted is in the composition root / bootstrappers, where components are registered and wired up. Applications rely on dependency injection to create the required object graphs.
As we are keeping our core application container agnostic, it means that we cannot use the Autofac relationship types, such as Owned, in our core application.
I would like to create a factory that returns components that implement IDisposable. As Autofac tracks disposable objects, I believe I have to use a lifetime scope to create a defined unit of work in which components will be disposed once they go out of scope.
According to the Autofac documentation, this can be achieved by taking a dependency on Func<Owned<T>>, however, as stated above, I cannot take a dependency on Owned as it is an Autofac type. At the bottom of this page, it says
The custom relationship types in Autofac don’t force you to bind your application more tightly to Autofac. They give you a programming model for container configuration that is consistent with the way you write other components (vs. having to know a lot of specific container extension points and APIs that also potentially centralise your configuration.)
For example, you can still create a custom ITaskFactory in your core model, but provide an AutofacTaskFactory implementation based on Func<Owned<T>> if that is desirable.
It is this implementation of ITaskFactory that I believe I need to implement, but I cannot find any examples.
I would be very grateful if someone could provide such an example.
Probably the best "real-world" example of this is the Autofac MVC integration mechanism. While it doesn't use Func<Owned<T>> under the covers it does show you how you might be able to implement a non-Autofac-specific mechanism to talk to Autofac under the covers.
In the MVC case, the System.Web.Mvc.IDependencyResolver is the interface and the Autofac.Integration.Mvc.AutofacDependencyResolver is the implementation. When ASP.NET MVC requests a service, it gets it from System.Web.Mvc.DependencyResolver.Current, which returns an IDependencyResolver. At app startup, that singleton gets set to the Autofac implementation.
The same principle could hold for your custom factory. While IDependencyResolver is not specific to the type it returns (it's just GetService<T>()) you could write a type-specific factory interface just as easily.

How far to go with IoC

I was wondering how far I should take my IoC implementation in terms of loosely coupling my application. I am using constructor injection in my MVC controller but wondered if I should also be resolving all my other dependencies in the controller instead of newing up objects. For example if I was to create a new User object within a controller method would I use?
var user = new User();
var user = myContainer.Resolve<IUser>();
I like the idea of breaking my dependency on User but is that going too far and could possible make my code harder to read?
This is a very good question, when you read and hear about DI it makes sense and this is the next natural conclusion.
First Steven's point is correct you should not pass the container around. If you need to construct IUser on the fly and it needs to be abstract you should rather inject an Abstract Factory.
Sebastian also posted a good link.
I actually wrote about this in an answer I posted here.
The bottom section of the post:
Not every object and dependency needs or should be dependency injected, first consider if what you are using is actually considered a dependency:
What are dependencies?
Application Configuration
System Resources (Clock)
Third Party Libraries
Database
WCF/Network Services
External Systems (File/Email)
Any of the above objects or collaborators can be out of your control and cause side effects and difference in behavior and make it hard to test. These are the times to consider an Abstraction (Class/Interface) and use DI.
What are not dependencies, doesn't really need DI?
List
MemoryStream
Strings/Primitives
Leaf Objects/Dto's
So in your particular case it really depends on what happens when IUser is constructed also whether you actually need to substitute it with different implementations. If this is not the case and User has only simple types with no external dependencies or side effects just new it up.
Consider what happens when you call new User(), look at the graph below, if it causes other objects to be created and looks like something in the graph below consider IoC.
A cascading dependency object graph:
In this example new on the object either requires or creates a whole bunch of other dependencies. It is most likely out of your control what those dependencies are or do.
When your object is a simple dto it doesn't suffer this problem and IoC is likely not so much required.

Dependency Injection: How to inject when using a multi-project solution

hope this question is not all too stupid, I'm trying to get a hold of more advanced programming principles and was thus trying to get used to Dependency Injection using Ninject.
So, my model is split up into several different .dll-projects. One project defines the model specifications (Interfaces) and a couple of others implement these interfaces. All model projects need to use some sort of database system, so they all need access to yet another .dll which implements all my database logic. It is important that all of them can access the same instance of my database object, though, so if wouldn't suffice to just create one instance for each model.
I'm not quite sure how to achieve this using dependency injection, though. My first thought was to create a seperate DI-project and bind all interfaces to their respective implementation, so the DI-project needed references to all the other projects (model interfaces & implementations, database system etc.). Then again, the models would need access to the DI project since, for example, they'd need to request the database system from the DI System (Ninject). Of course this would create a circular reference (binding DI project to model and model to DI project), so it's not possible.
Long story short, I'd need a programming pattern that allows me to bind model interfaces to their implementations but that also allows the model implementations to request other dependencies from Ninject, e.g.
IModel1 -> Model1
IModel2 -> Model2 (different project)
IDatabase -> Database (different project)
Model1 -> request IDatabase -> get Database instance
Model2 -> request IDatabase -> get the same Database instance
Would be glad to get a couple of suggestions, at the moment I'm stuck and out of ideas ;)
Thanks!
the models would need access to the DI project since, for example,
they'd need to request the database system from the DI System
(Ninject)
When you use dependency injection, the model shouldn't need to access the DI framework, since it is the DI framework that injects dependencies. The model objects should not be asking the DI container. When the your objects are asking the container for dependencies it is not called Dependency Injection, but Service Locator. Service Locator is an anti-pattern.
My first thought was to create a seperate DI-project
When you have a single application (e.g. a web app), the usual thing to do is completely configure the DI container in the startup project, as close as possible to the application’s entry point. This entry point where all object graphs are composed is called the Composition Root.
All model projects need to use some sort of database system, so they
all need access to yet another .dll which implements all my database
logic
Try making POCO (plain old CLR objects) model/entity objects, or at least, ensure that those objects don't need to reference any other project, which makes your architecture (and testing) much easier.
Use Ninject with the Register Resolve Release pattern from within a Composition Root.
The client application would use Ninject to inject the actual database and model implementations.
The client application therefore needs to reference the database, idatabase, model and imodel projects.
The idatabase and database projects need to reference the model project, as the methods will return model objects or collections of model objects. Have a look at the repository pattern.
Your model doesn't need to reference any of your projects.

Resources