I'd like to know how to register the classes and setup a Simple Injector container to instantiate the classes in the following way. ie go from manual DI to having the below Consumer class have the CompositeService injected and the object graph and lifetimes setup as follows:
To bring some context (if it helps) the Consumer class might be a ViewModel from a WPF application which gets instantiated when the View is requested.
public class Consumer
{
public Consumer()
{
var sharedSvc = new SharedService();
var productSvc = new ProductService(sharedSvc, new MathHelper());
var compositeSvc = new CompositeService(sharedSvc, productSvc, new MathHelper());
compositeSvc.Process();
}
}
where:
MyContext should be shared within the scope of the calls.
ProductService and CompositeService can be transient or shared within the scope.
MathHelper must be transient.
Q: How can the above be achieved with Simple Injector?
OR more specifically:
How can I instantiate multiple MathHelpers within the context of the Simple Injector Scope?
I've read up on http://simpleinjector.readthedocs.org/en/latest/lifetimes.html
and read and followed the SO answer https://stackoverflow.com/a/29808487/625113 however,
it seems either everything can be transient or scoped but not certain specific objects scoped and the rest transient (which seems odd).
Update 1
The following with Simple Injector will achieve the SharedService result, but if I want ProductService and CompositeService to also have a scoped lifetime it wont work:
cont.RegisterLifetimeScope<SharedService>();
cont.Register<MathHelper>();
cont.Register<ProductService>();
cont.Register<CompositeService>();
using (cont.BeginLifetimeScope())
{
var compositeSvc = cont.GetInstance<CompositeService>();
compositeSvc.Process();
}
If I register either or both of the ProductService or CompositeService as RegisterLifetimeScope I get a Lifetime mismatch exception. ie
cont.RegisterLifetimeScope<SharedService>();
cont.Register<MathHelper>();
cont.RegisterLifetimeScope<ProductService>();
cont.Register<CompositeService>(); // or cont.RegisterLifetimeScope<CompositeService>();
using (cont.BeginLifetimeScope())
{
var compositeSvc = cont.GetInstance<CompositeService>(); // Exception thrown
compositeSvc.Process();
}
Throws an exception leading to this page: https://simpleinjector.readthedocs.org/en/latest/LifestyleMismatches.html
I can under that in relation to Singleton should be dependent on Transient and can infer a sort of understanding that the same could be said in this case that Simple Injector is warning that Scoped can't depend on Transient because Transient isn't managed within the scope.
So my question is more specifically how can I instantiate multiple MathHelpers within the context of the Simple Injector Scope?
Update 2 - Further background and example
Brief background - This situation arose as I have a 4 year old, 2-tier, WPF based application currently using Ninject which has the bloated mixed Service architecture that #Steven describes
in his blog series (ie the Services have become a mash of mixed, semi-related, command and queries). Most of these services are a good candidate for separating out into
ICommandHandler/IQueryHandler architecture...but you can't do things overnight, so first crack was to convert from Ninject to SimpleInjector (yes I know Ninject can do the same thing in regards to this architecture
but there are other reasons for moving to SimpleInjector).
As far as "scoping" the dependency resolution, a "scope" (in this application) is considered to be for the life of a form so one DbContext (like the SharedService in the example above) is shared amoungst the
services that the form/viewModel require and MOST of the services are per scope with some injected services or helper classes needing to be injected as Transient.
This (to me) is analogous to Mark Seemann's hand-coded example from http://blog.ploeh.dk/2014/06/03/compile-time-lifetime-matching/ where he has a Per Request (singleton-scoped) service which has
Transient objects injected into it.
Edit: I had misread Mark Seemann's example and was reading the code as if the BarController were a service. So whilst the BarController object composition is the same the lifetime is not. That said the SomeThreadUnsafeService could just as easily have a new SomeServiceThatMustBeTransient injected into it but, I stand corrected, his example doesn't do this.
Hence I was wanting to know how to do the object composition Mark Seemann does in Simple Injector but outside the context of web reqeusts (my assumption is that Simple Injector's
Per web request scoping is in essence a specific type of Lifetime Scoping).
To address #Steve and #Ric .net's comment and answer, I can see that there is the potential to end up with the scenario where 2 different services use another, shared service that uses a transient object (storing state) and the supposedly transient object becomes a
Singleton Scoped object in the context of "some" of those services. eg
public class SingletonScopedService1
{
private readonly TransientX _transientA;
public SingletonScopedService1(TransientX transientA)
{
_transientA = transientA;
}
public void PokeTransient()
{
_transientA.Poke();
}
}
public class SingletonScopedService2
{
private readonly SingletonScopedService1 _service1;
private readonly TransientX _transientB;
public SingletonScopedService2(SingletonScopedService1 service1, TransientX transientB)
{
_service1 = service1;
_transientB = transientB;
}
public void GoFishing()
{
_service1.PokeTransient();
// This TransientX instance isn't affected
_transientB.Poke();
}
}
public class SingletonService3
{
private readonly SingletonScopedService1 _service1;
public SingletonService3(SingletonScopedService1 service1)
{
_service1 = service1;
}
public void DoSomething()
{
_service1.PokeTransient();
}
}
If DoSomething() is called on SingletonScopedService3 and GoFishing() is called on SingletonScopedService2 (and assuming TransientX maintains state) then results "may" be unexpected depending on the purpose of TransientX.
So I'm happy to accept this since the application is operating as expected (but also accept that the current composition is fragile).
With that said, can my original composition or Mark Seemann's example be registered with Simple Injector with the required life-times or is it strictly not possible by design and better to manually compose the object
graph (or inject a Func as #Ric .net suggests) for the instances where this is required until further refactoring/hardening can be done?
Update 3 - Conclusion
Whilst Ninject allows you to register my original composition like:
var kernel = new StandardKernel();
kernel.Bind<SharedService>().ToSelf().InCallScope();
kernel.Bind<MathHelper>().ToSelf();
kernel.Bind<ProductService>().ToSelf().InCallScope();
kernel.Bind<CompositeService>().ToSelf().InCallScope();
Simple Injector by design does not and I believe my second example is an example as to why.
FYI: In my real-world case, for the few instances that the object graph had this, I've manually constructed the graph (just to get switched to Simple Injector) with the intent on refactoring these potential issues out.
As explained in the linked SO question what the Lifestyle Mismatch exception is basically saying is that you're creating a so called captive dependency when you let a object depend on another object which has a shorter lifestyle.
While it maybe sounds odd to you, a captive dependency is:
A real life problem which, if undetected, would typically lead to very strange bugs which are very hard to debug
A sign, as indicated by Steven, that the service has some kind of state which is never a good sign
If MathHelper has mutable state and therefore needs to be injected in other services as transient, MathHelper has become some sort of 'runtime data'. And injecting runtime data is an anti-pattern.
This blogpost describes in detail what the problem is with runtime data and how to solve this. Solving your problem as described there is the way to go!
Because you did not specify the implementation details of MathHelper, it is hard to give you some advice how you should refactor MathHelper. So the only advice I can give you is, let runtime data or 'state' flow through the system as messages. You can read about message based design here and here.
There are however several other options, which will work but aren't good design IMO. So the advice is not to use these, but to be complete:
Instead of injecting MathHelper as a transient you could inject a MathHelperProvider or even simpler inject a Func<MathHelper> which you could register as singleton:
container.RegisterSingleton<Func<MathHelper>>(() => container.GetInstance<MathHelper>());
Notice that by registering a delegate you will make the container blind. It won't be able to warn you of misconfigurations in this part of the object graph anymore.
The other solutions I had in mind are so ugly in its design, that after writing them, I decided to leave them out of this answer!
If you would add some details about why MathHelper needs to be transient, I could give you some advice where you could make adjustments to make it scoped or even better: singleton.
Related
I'm currently reading the book Dependency Injection in .NET by Mark Seeman. In this book he recommends the Register, Resolve, Release pattern and also recommends that each of these operations should appear only once in your application's code.
My situation is the following: I'm creating an application that communicates with a PLC (a kind of industrial embedded computer) using a proprietary communication protocol for which the PLC manufacturer provides an library. The library's documentation recommends creating a connection to the PLC and maintaining it open; then using a timer or a while loop, a request should be periodically sent to read the contents of the PLC's memory, which changes over time.
The values read from the PLC's memory should be used to operate on a database, for which I intend to use Entity Framework. As I understand it, the best option is to create a new dbContext on every execution of the loop in order to avoid a stall cache or concurrency problems (the loop could be potentially executing every few milliseconds for a long time while the connection is kept open all the time).
My first option was calling Resolve on application construction to create a long-lived object that would be injected with the PLC communication object and would handle loop execution and keep the connection alive. Then, at the beginning of every loop execution I intended to call Resolve again to create a short-lived object that would be injected with a new dbContext and which would perform the operations on the database. However, after reading the advice on that book I'm doubting whether I'm on the right track.
My first idea was to pass a delegate to the long-lived object upon its construction that would allow it to build new instances of the short-lived object (I believe it is the factory pattern), thus removing the dependency on the DI container from my long-lived object. However, this construct still violates the aforementioned pattern.
Which is the right way of handling Dependency Injection in this situation?
My first attempt without DI:
class NaiveAttempt
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
public NaiveAttempt()
{
plcCommunicationObject = new PlcCommunicationObject("192.168.0.10");
plcCommunicationObject.Connect();
repeatedExecutionTimer = new Timer(100); //Read values from PLC every 100ms
repeatedExecutionTimer.Elapsed += (_, __) =>
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
using (var ctx = new DbContext())
{
// Operate upon database
ctx.SaveChanges();
}
}
}
}
Second attempt using Poor man's DI.
class OneLoopObject
{
private PlcCommunicationObject plcCommunicationObject;
private Func<DbContext> dbContextFactory;
public OneLoopObject(PlcCommunicationObject plcCommunicationObject, DbContext dbContext
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContext = dbContext;
}
public void Execute()
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
// Operate upon database
}
}
class LongLivedObject
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
private Func<OneLoopObject> oneLoopObjectFactory;
public LongLivedObject(PlcCommunicationObject plcCommunicationObject, Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory)
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContextFactory = dbContextFactory;
this repeatedExecutionTimer = new Timer(100);
this.repeatedExecutionTimer.Elapsed += (_, __) =>
{
var loopObject = oneLoopObjectFactory(plcCommunicationObject);
loopObject.Execute();
}
}
}
static class Program
{
static void Main()
{
Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory = plc => new OneLoopObject(plc, new DbContext());
var myObject = LongLivedObject(new PlcCommunicationObject("192.168.1.1"), oneLoopObjectFactory)
Console.ReadLine();
}
}
The first edition states (chapter 3, page 82):
In its pure form, the Register Resolve Release pattern states that you should only make a single method call in each phase [...] an application should only contain a single call to the Resolve method.
This description stems from the idea that your application only contains either one root object (typically when writing a simple console application), or one single logical group of root types, e.g. MVC controllers. With MVC controllers, for instance, you would have a custom Controller Factory, which is provided by the MVC framework with a controller type to build. That factory will, in that case, only have a single call to Resolve while supplying the type.
There are cases, however, where your application has multiple groups of root types. For instance, a web application could have a mix of API Controllers, MVC Controllers and View Components. For each logical group you would likely have a single call to Resolve, and thus multiple calls to Resolve (typically because each root type gets its own factory) in your application.
There are other valid reasons for calling back into the container. For instance, you might want to defer building part of the object graph, to combat the issue of Captive Dependencies. This seems your case. Another reason for having an extra resolve is when you use the Mediator pattern to dispatch messages to a certain implementation (or implementations) that can handle that message. In that case your Mediator implementation would typically wrap the container and call Resolve. The Mediator’s abstraction would likely be defined in your Domain library, while the Mediator’s implementation, with its knowledge of the container, should be defined inside the Composition Root.
The advice of having a single call to Resolve should, therefore, not be taken literally. The actual goal here is to build a single object graph as much as possible in one call, compared to letting classes themselves call back into the container to resolve their dependencies (i.e. the Service Locator anti-pattern).
The other important point that (the second edition of) the book makes is
Querying for Dependencies, even if through a DI Container, becomes a Service Locator if used incorrectly. When application code (as opposed to infrastructure code) actively queries a service in order to be provided with required Dependencies, then it has become a Service Locator.
A DI Container encapsulated in a Composition Root isn't a Service Locator—it's an infrastructure component.
(note: this quote is from the second edition; Although the first edition contains this information as well, it might be formulated differently).
So the goal of the RRR pattern is to promote encapsulation of the DI Container within the Composition Root, which is why it insists in having a single call to Resolve.
Do note that while writing the second edition, Mark and I wanted to rewrite the discussion of the RRR pattern. Main reason for this was that we found the text to be confusing (as your question indicates). However, we eventually ran out of time so we decided to simply remove that elaborate discussion. We felt that the most important points were already made.
Combining factories with DI is a common solution. There is absolutely nothing wrong with creating and disposing objects dynamically in your program (it's much more difficult and limiting to try to account for every bit of memory you'll need up front).
I found a post by Mark Seeman about the Register, Resolve, Release Pattern (RRR) here: http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/
He states that...
The names originate with Castle Windsor terminology, where we:
Register components with the container
Resolve root components
Release components from the container
So the RRR pattern is limited to the DI Container. You do indeed Register and Release components with the container one time in your application. This says nothing about objects not injected through DI, ie those objects created dynamically in the normal execution of your program.
I have seen various articles use distinct terminology for the two different types of things you create in your program with relation to DI. There are Service Objects, ie those global objects injected via DI to your application. Then there are Data or Value Objects. These are created by your program dynamically as needed and are generally limited to some local scope. Both are perfectly valid.
It sounds like you want to be able to both resolve objects from the container and then release them, all without directly referencing the container.
You can do that by having both a Create and a Release method in your factory interface.
public interface IFooFactory
{
Foo Create();
void Release(Foo created);
}
This allows you to hide references to the container within the implementation of IFooFactory.
You can create your own factory implementation, but for convenience some containers, like Windsor, will create the factory implementation for you.
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<Foo>());
container.Register(
Component.For<IFooFactory>()
.AsFactory()
);
You can inject the factory, call Create to obtain an instance of whatever the factory creates, and when you're done with it, pass that instance to the Release method.
Windsor does this by convention. The method names don't matter. If you call a method of the interface that returns something, it attempts to resolve it. If a method returns void and takes an argument then it tries to release the argument from the container.
Behind the scenes it's roughly the same as if you wrote this:
public class WindsorFooFactory : IFooFactory
{
private readonly IWindsorContainer _container;
public WindsorFooFactory(IWindsorContainer container)
{
_container = container;
}
public Foo Create()
{
return _container.Resolve<Foo>();
}
public void Release(Foo created)
{
_container.Release(created);
}
}
The factory implementation "knows" about the container, but that's okay. Its job is to create objects. The factory interface doesn't mention the container, so classes that depend on the interface aren't coupled to the container. You could create an entirely different implementation of the factory that doesn't use a container. If the object didn't need to be released you could have a Release method that does nothing.
So, in a nutshell, the factory interface is what enables you to follow the resolve/release part of the pattern without directly depending on the container.
Here's another example that shows a little bit more of what you can do with these abstract factories.
Autofac uses Func<> as the factory pattern so you could always do the same:
public class Foo()
{
private readonly Func<Bar> _barFactory;
public Foo(Func<Bar> barFactory)
{
_barFactory = barFactory;
}
}
Adding Factory Interfaces for factories is not something I think anyone should need to do most of the time, it's extra work for little to no reward.
Then you simply need to keep track of which entities are externally owned or DI owned for your release (Dispose in C#).
I'm converting my code to use an IoC Container with StructureMap. Trying to get my head around things, and I feel it's starting to 'click' and I can see how it makes so much sense with the back-end side.
However, I'm working my way down I've spotted a few sitautions where I'm not sure how to make it work. Specifically, the case where my original constructor did something important with an argument that isn't really a dependency, or something that will change at run-time.
Let's say I start with this (pre IoC Container), where I was passing my dependencies using a constructor, but also sending it an ImportantObject that's run-time dependent:
IMyPageViewModel myPageViewModel = new MyPageViewModel(importantObject, dialogManager, pageDisplay, viewModelProvider)
and here it is doing its constructing:
public MyPageViewModel(ImportantObject importantObject, IDialogManager dialogManager,IPageDisplay pageDisplay, IViewModelProvider viewModelProvider)
{
this.dialogManager = dialogManager;
this.pageDisplay = pageDisplay;
this.viewModelProvider = viewModelProvider;
importantObject.DoThatImportantThing();
}
Now, I'm migrating to use the IoC container, and at first I think I should do something like this:
//I need to create an instance to use, so I use my IoC container:
IMyPageViewModel myPageViewModel = container.GetInstance<IMyPageViewModel>();
then letting it resolve it's dependencies, however importantObject is something that's set at runtime. I can't register it as a dependency:
public MyPageViewModel(IDialogManager dialogManager,IPageDisplay pageDisplay, IViewModelProvider viewModelProvider, IContainer container)
{
this.dialogManager = dialogManager;
this.pageDisplay = pageDisplay;
this.viewModelProvider = viewModelProvider;
//however, here I have no access to the important object that I previously passed in my constructor
importantObject.DoThatImportantThing(); //obviously error
}
I thought maybe I should be creating using 'new', and passing the IoC container:
IMyPageViewModel myPageViewModel = new MyPageViewModel(importantObject, container)
then letting it resolve it's dependencies in the constructor:
public MyPageViewModel(ImportantObject importantObject, IContainer container)
{
this.dialogManager = container.GetInstance<IDialogManager>();
this.pageDisplay = container.GetInstance<IPageDisplay>();
this.viewModelProvider = container.GetInstance<IViewModelProvider>();
importantObject.DoThatImportantThing();
}
But that strikes me as not a good idea, specifically, I can't run it with a test register and have it create a dummy/stub "MyPageViewModel" for unit testing.
The only other thing I can think of is to remove all the logic from the constructor and putting it in an initialize method, or property setters. However, this means I have to ensure that initialize is always called before use and it will hide errors/problems.
Are any of these options sensible, how should I manage passing a run-time dependent object in a constructor with Dependency Injection?
I tried to stray away from static factories, as I've read lots about them being anti-pattern/bad practice.
Edit: In response to Bruno Garcia's answer I decided to use a factory type pattern that holds the container and deals with object creation like this:
class PageProvider : IPageProvider
{
public MyPageViewModel GetMyPage(ImportantObject importantObject)
{
//might just get, if it's a single only instance
return MyPageViewModel(ImportantObject importantObject,
container.GetInstance<IDialogManager>(),
container.GetInstance<IPageDisplay>(),
container.GetInstance<IViewModelProvider>())
}
}
StructureMap supports passing arguments to Resolve. This could help you with passing the ImportantObject to the Service you are resolving.
It's worth noting that if you pass your container around, things can get really messy really fast. Avoid using it as a Service Locator.
Ideally you'd use the container to resolve an entry point (e.g: Controller, Consumer worker) and from that point on, there's no direct use of the container anymore. If you need to control the lifetime of the dependencies you are taking into your constructor, there are a number of ways to go about that like:
Taking a Factory or a Func<>.
I suggest you reading carefully the docs of the Container you want to use to understand who controls the lifetime of objects (if a Component implements IDisposable, who's going to dispose it?). When are lifetime scopes created/disposed?
IoC Container's are great but it's very easy to find yourself troubleshooting memory leaks if you don't carefully understand the concept of lifetime ownership.
I'm trying to improve the performance of my IoC container. We are using Unity and SimpleInjector and we have a class with this constructor:
public AuditFacade(
IIocContainer container,
Func<IAuditManager> auditManagerFactory,
Func<ValidatorFactory> validatorCreatorFactory,
IUserContext userContext,
Func<ITenantManager> tenantManagerFactory,
Func<IMonitoringComponent> monitoringComponentFactory)
: base(container, auditManagerFactory, GlobalContext.CurrentTenant,
validatorCreatorFactory, userContext, tenantManagerFactory)
{
_monitoringComponent = new Lazy<IMonitoringComponent>(monitoringComponentFactory);
}
I also have another class with this constructor:
public AuditTenantComponent(Func<IAuditTenantRepository> auditTenantRepository)
{
_auditTenantRepository = new Lazy<IAuditTenantRepository>(auditTenantRepository);
}
I'm seeing that the second one gets resolved in 1 millisecond, most of the time, whereas the first one takes on average 50-60 milliseconds. I'm sure the reasoning for the slower one is because of the parameters, it has more parameters. But how can I improve the performance of this slower one? Is it the fact that we are using Func<T> as parameters? What can I change if it is causing the slowness?
There is possibly a lot to improve on your current design. These improvements can be placed in five different categories, namely:
Possible abuse of base classes
Use of Service Locator anti-pattern
Use of Ambient Context anti-pattern
Leaky abstractions
Doing too much in injection constructors
Possible abuse of base classes
The general consensus is that you should prefer composition over inheritance. Inheritance is often overused and often adds more complexity compared to using composition. With inheritance the derived class is strongly coupled to the base class implementation. I often see a base class being used as practical utility class containing all sorts of helper methods for cross-cutting concerns and other behavior that some of the derived classes may need.
An often better approach is to remove the base class all together and inject a service into the implementation (the AuditFacade class in your case) that exposed just the functionality that the service needs. Or in case of cross-cutting concerns, don't inject that behavior at all, but wrap the implementation with a decorator that extends the class'es behavior with cross-cutting concerns.
In your case, I think the complication is clearly happening, since 6 out of 7 injected dependencies are not used by the implementation, but are only passed on to the base class. In other words, those 6 dependencies are implementation details of the base class, while the implementation still is forced to know about them. By abstracting (part of) that base class behind a service, you can minimize the number of dependencies that AuditFacade needs to two dependencies: the Func<IMonitoringComponent> and the new abstraction. The implementation behind that abstraction will have 6 constructor dependencies, but the AuditFacade (and other implementations) are oblivious to that.
Use of Service Locator anti-pattern
The AuditFacade depends on an IIocContainer abstraction and this is very like an implementation of the Service Locator pattern. Service Locator should be considered an anti-pattern because:
it hides a class' dependencies, causing run-time errors instead of
compile-time errors, as well as making the code more difficult to
maintain because it becomes unclear when you would be introducing a
breaking change.
There are always better alternatives to injecting your container or an abstraction over your container into application code. Do note that at some times you might want to inject the container into factory implementations, but at long as those are placed inside your Composition Root, there's no harm in that, since Service Locator is about roles, not mechanics.
Use of Ambient Context anti-pattern
The static GlobalContext.CurrentTenant property is an implementation of the Ambient Context anti-pattern. Mark Seemann and I write about this pattern in our book:
The problems with AMBIENT CONTEXT are related to the problems with SERVICE
LOCATOR. The main problems are:
The DEPENDENCY is hidden.
Testing becomes more difficult.
It becomes very hard to change the DEPENDENCY based on its context. [paragraph 5.3.3]
The use in this case is really weird IMO, because you grab the current tenant from some static property from inside your constructor to pass it on to the base class. Why doesn't the base class call that property itself?
But no one should call that static property. The use of those static properties makes your code harder to read and maintain. It makes unit testing harder and since your code base will usually be littered with calls to such static, it becomes a hidden dependency; it has the same downsides as the use of Service Locator.
Leaky abstractions
A Leaky Abstraction is a Dependency Inversion Principle violation, where the abstraction violates the second part of the principle, namely:
B. Abstractions should not depend on details. Details should depend on
abstractions.
Although Lazy<T> is not abstractions by itself (Lazy<T> is a concrete type), it can become leaky abstraction when used as constructor argument. For instance, if you are injecting an Lazy<IMonitoringComponent> instead of an IMonitoringComponent directly (which is what you are basically doing in your code), the new Lazy<IMonitoringComponent> dependency leaks implementation details. This Lazy<IMonitoringComponent> communicates to the consumer that the used IMonitoringComponent implementation is expensive or time consuming to create. But why should the consumer care about this?
But there are more problems with this. If at one point in time the used IUserContext implementation becomes costly to create, we must start to make sweeping changes throughout the application (a violation of the Open/Closed Principle) because all IUserContext dependencies need to be changed to Lazy<IUserContext> and all consumers of that IUserContext must be changed to use userContext.Value. instead. And you'll have to change all your unit tests as well. And what happens if you forget to change one IUserContext reference to Lazy<IUserContext> or when you accidentally depend on IUserContext when you create a new class? You have a bug in your code, because at that point the user context implementation is created right away and this will cause a performance problem (this causes a problem, because that is the reason you are using Lazy<T> in the first place).
So why are we exactly making sweeping changes to our code base and polluting it with that extra layer of indirection? There is no reason for this. The fact that a dependency is costly to create is an implementation detail. You should hide it behind an abstraction. Here's an example:
public class LazyMonitoringComponentProxy : IMonitoringComponent {
private Lazy<IMonitoringComponent> component;
public LazyMonitoringComponentProxy(Lazy<IMonitoringComponent> component) {
this.component = component;
}
void IMonitoringComponent.MonitoringMethod(string someVar) {
this.component.Value.MonitoringMethod(someVar);
}
}
In this example we've hidden the Lazy<IMonitoringComponent> behind a proxy class. This allows us to replace the original IMonitoringComponent implementation with this LazyMonitoringComponentProxy without having to make any change to the rest of the applicaiton. With Simple Injector, we can register this type as follows:
container.Register<IMonitoringComponent>(() => new LazyMonitoringComponentProxy(
new Lazy<IMonitoringComponent>(container.GetInstance<CostlyMonitoringComp>));
And just as Lazy<T> can be abused as leaky abstraction, the same holds for Func<T>, especially when you're doing this for performance reasons. When applying DI correctly, there is most of the time no need to inject factory abstractions into your code such as Func<T>.
Do note that if you are injecting Lazy<T> and Func<T> all over the place, you are complicating your code base unneeded.
Doing too much in injection constructors
But besides Lazy<T> and Func<T> being leaky abstractions, the fact that you need them a lot is an indication of a problem with your application, because Injection Constructors should be simple. If constructors take a long time to run, your constructors are doing too much. Constructor logic is often hard to test and if such constructor makes a call to the database or requests data from HttpContext, verification of your object graphs becomes much harder to the point that you might skip verification all together. Skipping verification of the object graph is a terrible thing to do, because this forces you to click through the complete application to find out whether or not your DI container is configured correctly.
I hope this gives you some ideas about improving the design of your classes.
You can hook into Simple Injector's pipeline and add profiling, which allows you to spot which types are slow to create. Here's an extension method that you can use:
public struct ProfileData {
public readonly ExpressionBuildingEventArgs Info;
public readonly TimeSpan Elapsed;
public ProfileData(ExpressionBuildingEventArgs info, TimeSpan elapsed) {
this.Info = info;
this.Elapsed = elapsed;
}
}
static void EnableProfiling(Container container, List<ProfileData> profileLog) {
container.ExpressionBuilding += (s, e) => {
Func<Func<object>, object> profilingWrapper = creator => {
var watch = Stopwatch.StartNew();
var instance = creator.Invoke();
profileLog.Add(new ProfileData(e, watch.Elapsed));
return instance;
};
Func<object> instanceCreator =
Expression.Lambda<Func<object>>(e.Expression).Compile();
e.Expression = Expression.Convert(
Expression.Invoke(
Expression.Constant(profilingWrapper),
Expression.Constant(instanceCreator)),
e.KnownImplementationType);
};
}
And you can use this as follows:
var container = new Container();
// TODO: Your registrations here.
// Hook the profiler
List<ProfileData> profileLog = new List<ProfileData>(1000);
// Call this after all registrations.
EnableProfiling(container, profileLog);
// Trigger verification to allow everything to be precompiled.
container.Verify();
profileLog.Clear();
// Resolve a type:
container.GetInstance<AuditFacade>();
// Display resolve time in order of time.
var slowestFirst = profileLog.OrderByDescending(line => line.Elapsed);
foreach (var line in slowestFirst)
{
Console.WriteLine(string.Format("{0} ms: {1}",
line.Info.KnownImplementationType.Name,
line.Elapsed.TotalMilliseconds);
}
Do note that the shown times include the time it takes to resolve the dependencies, but this will probably allow you pretty easily what type causes the delay.
There are two important thing I want to note about the given code here:
This code will have severely negative impact on the performance of resolving object graphs, and
The code is NOT thread-safe.
So don't use it in your production environment.
Everything you do has a cost associated with it. Typically, more constructor parameters that are resolved recursively take longer than fewer parameters. But you must decide if the cost is ok or too high.
In your case, will the 50 ms cause a bottleneck? are you only creating 1 instance or are you puking them out in a tight loop? Just comparing the 1 ms with 50 ms might cause you to condemn the slower one, but if the user cannot tell that 50 ms passed and it doesn't cause a problem elsewhere in your app, why run through hoops to make it faster if you don't know it'll ever be needed?
Just trying to wrap my head around IoC at the moment, and I am part of the way there. An example I found on another post on SO was this:
http://blog.vascooliveira.com/unity-tutorial-and-examples/
The line I don't quite get is this:
ILogger myExampleInstance = myContainer.Resolve(loggerType);
I am not sure what loggerType is as it doesn't mention it anywhere.
I can see that IoC in this case allows us to create a way of writing a log. Rather than instantiate in the code a specific type of logger, we use IoC to create an ILogger interface, and we code to that. This means I assume that we don't care specifically what type of Logger is being used. If we don't care, I am curious to know why we need to pass in a loggerType, or how we know what the loggerType is due to seperation of concerns.
I am half way to understanding it but I just need a final push! =)
What you see there is actually an anti-pattern called Service Locator. The example code directly references the container, calling its Resolve() method.
In 99% of cases you should not ever reference your container within your code - there should only be a single application wide reference to the container at the very highest level of your code. (the final 1% of cases are almost exclusively where a framework you are using doesn't allow dependency injection)
In that single reference to your container you new up objects as needed with all their dependencies injected in a valid state. All your objects receive their dependencies as parameters (most often passing to the constructor).
There are lots of blog posts (here are two I found with some quick googling: Thou Shalt Not Reference The IoC Container and Service Locator Is An Anti Pattern around explaining the various reasons why ServiceLocator is bad.
You have found one example with your question about what loggerType should be, using proper IoC your application should not care - the Service Locator approach tends to mean your application starts to become aware of the details of its dependencies again, which goes against the entire point of using IoC and dependecy injection in the first place.
For further reading on IoC I'd suggest browsing through blog posts by Jeremy Miller, the creater of StructureMap. Don't take that as me saying use StructureMap instead of Unity, but since he wrote a container from scratch most of what he says on the subject is well thought out and he is a good writer.
It would be something like this
public class MyLogger : ILogger
{
//implementation
}
And then
Type loggerType = typeof(MyLogger);
ILogger myExampleInstance = myContainer.Resolve(loggerType);
output = myExampleInstance.MyInterfaceMethod("Unity rocks!");
The problem is, it is actually a ServiceLocator pattern. The DI and IoC would look like this:
public class Foo
{
private ILogger logger;
//This will be injected automatically by IoC
//once you register it somewhere in the app init e.g.
//container.RegisterType<ILogger, MyLogger>();
public Foo(ILogger logger)
{
this.logger = logger;
}
public void Bar()
{
logger.Debug("In the bar");
}
}
While David Hall's answer is more correct, just to answer your question, loggerType is the Type of the logger. In reality, they probably could have done:
ILogger myExampleInstance = myContainer.Resolve(typeof(ILogger));
Or even better, use the generic extension method:
var myExampleInstance = myContainer.Resolve<ILogger>();
The Unity container will look into its list of known mappings, and see what type is mapped from ILogger. It will then create a new instance, and return it.
As a more concise example:
IContainer container = ...;// get or create Unity container
container.RegisterType<ILogger, MyLogger>(); // tell Unity that when I ask for ILogger, I want a MyLogger back
ILogger logger = container.Resolve<ILogger>(); // logger is set to a new instance of MyLogger
I hope that helps!
After much kicking and screaming, I'm starting to accept DI despite how much cleaner SL may seem as dependencies grow.
However, IMO there's still a significant show-stopper with regards to DI:
DI is not possible when you don't have control over an object's instantiation. In the ASP.NET world, examples include: HttpModule, HttpHandler, Page, etc.
In the above scenario we would resort to static service location to resolve dependencies, typically via HttpContext.Current, which invariably infers scope from the current thread. So if we're going to use static SL here, then why not use it else where too?
Is the answer as simple as: grit your teeth and use SL when necessary (like above), but try and favor DI? And if so: doesn't using static SL just once potentially break the consistency of an entire application? Essentially undoing the hard work of DI everywhere else?
Sometimes you just can't avoid tight coupling, like in your examples. However, that doesn't mean you need to embrace it either. Instead, quarantine it by encapsulating the messiness and factoring it away from your day-to-day life.
For example, if we want the current Forms Authentication user, we don't have much choice but to access HttpContext.Current.Request.User.Identity.Name. We do, however, have the choice of where to make that call.
HttpContext.Current is a solution to a problem. When we call it directly from where we use the results, we are declaring the problem and solution in the same place: "I need the current user name which is declared unwaveringly as coming from the current HTTP context." This muddles the definition of both and doesn't allow for different solutions to the same problem.
What we are missing is a clear articulation of the problem we are solving. For this example, it would be something like:
Determine the user which made the current request
The fact that we are using HttpContext.Current, or even a user name, is not a part of the core problem definition; it is an implementation detail that only serves to complicate the code requiring the current user.
We can represent the intent to retrieve the current user, sans implementation details, through an interface:
public interface IUserContext
{
User GetUser();
}
Any class where we called HttpContext.Current directly can now use this interface instead, injected by the container, to maintain DI goodness. It is also much more intention-revealing for a class to accept an IUserContext in its constructor than to have a dependency which can't be seen from its public API.
The implementation buries the static call in a single place where it can't harm our objects any more:
public class FormsUserContext : IUserContext
{
private readonly IUserRepository _userRepository;
public FormsUserContext(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public User GetUser()
{
return _userRepository.GetByUserName(HttpContext.Current.Request.User.Identity.Name);
}
}
A good codebase is also one where the occasional restriction on the optimal solution is contained to a small area. The lack of possibility of DI partly explains the move from ASP.NET to the MVC counterpart. With HttpHandlers, I usually have a HttpHandler Factory which is the only class to get its "hands" dirty and instantiates HttpHandlers from a container.
Many DI containers have some kind of BuildUp method to perform setter injection on already instantiated objects. If you have service location, try to isolate it into some piece of your application that is purely an infrastructure concern. It will then act as a dampening field to the environment's limitations.
In short, some SL will not invalidate your efforts, but make sure the SL bits are infrastructural and well-contained.
To provide on #flq's answer with an example.
I'm working on an ASP.Net MVC project that makes rather extensive use of Ninject. There were a handful of places where I either couldn't use DI (Extension methods), or it was cleaner not to, and use SL instead (The base class for all of my controllers, constructor injection would make all the constructors for controllers messy).
So, as a compromise, I use a slight hybrid:
public interface IServiceLocator
{
T Create<T>();
}
public class NinjectServiceLocator : IServiceLocator
{
private readonly IKernel kernel;
public NinjectServiceLocator(IKernel kernel)
{
this.kernel = kernel;
}
public T Create<T>()
{
return kernel.Get<T>();
}
}
public class ServiceLocator
{
private static IServiceLocator current;
public static IServiceLocator Current
{
get
{
return current;
}
set
{
current = value;
}
}
public T Create<T>()
{
return current.Create<T>();
}
}
It may not be the best option, or a strict SL pattern, but it works for me. The additional interface lets me swap out the locator itself for testing. IKernel is Ninject's main DI object that gets configured, so substitute with your own framework, as most I've encountered have a similar core.
The typical approach in these cases is to write a generic infrastructure-level wrapper/adapter that does use Service Locator, but provides clean IoC for application-level classes that use this adapter.
I did this to enable IoC in HttpModules and Providers, two cases where the framework doesn't allow control of instantiation. A similar approach can be used for other similar entities.
The point here is that such wrapper/adapter code is part of your reusable infrastructure, and not your application-level code. What's generally not recommended is using service location in your application-level code.
The "BuildUp" feature that some containers offer are a poor workaround for these limitations. BuildUp doesn't allow you to regain control of instantiation, so you won't be able to use some container features such as proxying.