Using IoC/DI Containers with run-time dependent constructor arguments - 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.

Related

Register, Resolve, Release pattern usage

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

Ioc/DI - How to use the registered dependencies?

I think I'm missing a key part of how to actually use IoC/DI. I happen to be using the Unity container. I know how to setup a class to have it's dependencies injected and I also know how to make Unity register a type.
But what I don't know is how to actually then make use of these registrations.
So for example:
var container = new UnityContainer();
container.RegisterType<IRepository, XmlRepository>();
var service = new MyService(container.Resolve<IRepository>());
public interface IRepository
{
void GetStuff();
}
public class XmlRepository : IRepository
{
public void GetStuff()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IRepository _myRepository;
public MyService(IRepository repository)
{
_myRepository = repository;
}
}
Here I have a service layer which accepts a parameter of type IRepository. It's the container part that I seem to not be understanding.
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance? In my code I'm getting the container to resolve a type, unless I'm misunderstanding how this is supposed to work, isn't the container supposed to somehow automatically (with reflection?) inject the dependency I told it to use when I registered the type? var service = new MyService(...) Is calling container.Resolve the correct way of doing this?
I've created a container, but how do I share this container amongst my project/code? This sort of relates to the first question. I had previously thought that there was a single place that you register types. So far the only way I can see how to get around this is to:
Keep registering types wherever I use them and end up with duplicated code
Pass the container around to every place I'm going to be resolving types
Neither of these ways are how I'd expect this to work
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance?
No, that's the point of a DI Container, but there are drawbacks to using a container as well. Favour Pure DI over using a DI Container, as this will teach you how to use Dependency Injection using only first principles.
I've created a container, but how do I share this container amongst my project/code?
You don't. The DI Container should only be used in the Composition Root (if you use a DI Container at all).
Put your container setup in a module that runs when your program starts. You can call it from Main, for example. This is called a boot strapper.
See Dependency Injection with Unity for a good example of how to do this.
You don't need to do new MyService(container.Resolve<IRepository>()). To get an instance of MyService, just use container.Resolve<MyService>(); it will automatically resolves the dependencies for MyService.

Brief question about Microsoft Unity IoC

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!

Can I take advantage of Dependency Injection here?

I'm working on a project that's using the MS Application Blocks. I see the 'Unity' dll is available to me. It's version 1.1 by the way. How can I use dependency injection here?
I have a class
public class ScheduleDataDetailsDC
{
public int ScheduleID;
public List<ScheduleRateLineItem> MinRateList;
public List<ScheduleRateLineItem> MaxRateList;
public List<ScheduleRateLineItem> VotRateList;
public List<ScheduleLOSRateDC> LosRateList;
public List<ScheduleRateParamsDC> RateParams;
}
So when I new it up I am doing this...
new ScheduleDataDetailsDC{
LosRateList = new List<ScheduleLOSRateDC>()
, MaxRateList = new List<ScheduleRateLineItemDC>()
, MinRateList = new List<ScheduleRateLineItemDC>()
, RateParams = new List<ScheduleRateParamsDC>()
, VotRateList = new List<ScheduleRateLineItemDC>()
}
Can Unity 1.1 Help me in anyway here? I would like to just be able to use var x = new ScheduleDetailsDC(), and those 5 inner lists be initialized for me. Can Unity do anything for me here? Please note I've never used DI before.
Thanks for any pointers,
~ck in San Diego
The best thing to do would be to initialise the lists in the constructor and deny direct access to them from other classes by making them into properties:
public class ScheduleDataDetailsDC
{
public ScheduleDataDetailsDC()
{
this.MinRateList = new List<ScheduleRateLineItem>();
//inialise other lists
}
public List<ScheduleRateLineItem> MinRateList { get; private set; }
...
}
It doesn't seem as though dependency injection can really be of use here since the class seems to be a simple data container, although it's difficult to tell without more context.
Yes Unity can help you, but I think it's not the case. You can just initialize your lists incide your object giving them default instances, Unity as any other IoC container shouldn't be used as a simple object builder (despite it could).
I'm not sure specifically what the details of the 1.1 release of Unity are, but generally speaking whenever you are using an Inversion of Control Container, you have to go through the following steps:
Register the types your IoC container (Unity in your case) knows about. This includes all of the main types that you plan to request, plus all of the dependent types. In your case you will need to let it know about ScheduleDataDetailsDC, and what, exactly needs to go into each of the lists that are considered dependencies
Your types should specify all of the required dependencies as constructor arguments. This is what the IoC Container will look at to determine what needs to be injected. If you have optional dependencies then you can use Property Injection to support that (if your IoC container supports it, which I think Unity does)
You must request an instance of your registered type from the container. How exactly you do this depends on you container. There should be a method like Get<T>() or Resolve<T>. Generally your going to request instances of the "Highest Level" classes, i.e the ones that are used somewhere near the entry point for your software. If you do this, and you have applied Dependency Injection for all dependent classes down the line (and you've correctly registered all of the dependent types) you should get an object with all of it's dependencies supplied, and likewise all of that objects dependencies should be supplied, and on down the line.
You also tend to see Interfaces used in conjunction with IoC a lot since you can bind a concrete type to the interface type, and then specify that interface as your dependency. This allows you to apply business rules and configuration values during the binding process that will give you the ability to use different concrete implementations in cases where you would need to do such a thing.
So given all of this, it's hard to say exactly what would be involved in utilizing Unity in the situation you've outlined above. Firstly you would need to register ScheduleDataDetailsDC, but to get the dependencies in place you would also need to register each of the List types, or more specifically each concrete object that would go in each list (and then, of course all of the dependencies for those classes). Since I'm not really sure what the roles of those lists are, it's hard for me to say how you could go about doing that (or even if you could go about doing that).

firsts steps with an IoC because I hit a wall, please explain the 'behind the scenes'

So I started this new project, and I was trying to incorporate all the new design principles I was reading about, namely trying to make things loosely coupled, testable, and following some patterns.
So I then ran into the issue of having to pass too many factories/managers into my classes constructor, which led me into Dependancy injection.
public class SomeClass
{
public SomeClass(IDBFactory factory, IOrderManager orderManager, ....)
}
So if I use ninject, from what I understand, I would then bind a particular implementation to the class.
So what is going on behind the scenes?
NInject will, whenever I instantiate SomeClass, it will bind the implementation that I defined in the config file?
i.e.
I do:
ISomeClass sc = NInject.Get<ISomeClass>();
and ninject will do:
new SomeClassImpl(pass in all the implementaitons in the constructor)
correct?
I don't know NInject, but most DI Containers support Auto-Wiring, which works this way:
When you request ISomeClass, it looks through its list of all registered types. Using this list, it discovers that the desired implementation of ISomClass is SomeClass.
It will use SomeClass' constructor to create an instance (perhaps using Activator.CreateInstance), so it uses Reflection to figure out which paramters are required.
For each paramameter, it looks at the type and repeats step 1-2 for each.
Thus, the process may be recursive, but in the end, you should end up with a fully populated object graph where all dependencies are satisfied.

Categories