Unity IoC InjectionFactory not respecting DependencyOverride - c#

I'm currently trying to wrap a class in decorator and inject in one of the dependencies at runtime. I currently have an interface of IStorage that is implemented by a StorageCacheDecorator and a Storage. The StorageCacheDecorator takes in a IStorage and the Storage object takes in aContext` object. However the context object needs to be passed in every time these classes are resolved.
public interface IStorage
{
}
public class Storage : IStorage
{
public Context Context { get; }
public Storage(Context context)
{
this.Context = context;
}
}
public class StorageCacheDecorator : IStorage
{
public IStorage InnerStorage { get; }
public StorageCacheDecorator(IStorage innerStorage)
{
this.InnerStorage = innerStorage;
}
}
public class Context
{
}
I've omitted the implementation details and the test below gives an example of my problem
[Test]
public void ShouldResolveWithCorrectContext()
{
var context = new Context();
var container = new UnityContainer();
container.RegisterType<Storage>();
container.RegisterType<IStorage>(
new InjectionFactory(c => new StorageCacheDecorator(
c.Resolve<Storage>())));
var resolve = container.Resolve<IStorage>(new DependencyOverride<Context>(context));
Assert.That(resolve, Is.TypeOf<StorageCacheDecorator>());
var cacheDecorator = ((StorageCacheDecorator)resolve);
Assert.That(cacheDecorator.InnerStorage, Is.TypeOf<Storage>());
var storage = ((Storage)cacheDecorator.InnerStorage);
Assert.That(storage.Context, Is.SameAs(context));
}
However if we remove the decorator the test passes
[Test]
public void ShouldResolveWithCorrectContext1()
{
var context = new Context();
var container = new UnityContainer();
container.RegisterType<IStorage, Storage>();
var resolve = container.Resolve<IStorage>(new DependencyOverride<Context>(context));
Assert.That(resolve, Is.TypeOf<Storage>());
Assert.That(((Storage)resolve).Context, Is.SameAs(context));
}
How do I get the InjectionFactory to respect the DependencyOverride?

First of all, I'm pretty sure that what you (and today - me) have stumbled upon is a bug in Unity.
I managed to diagnose it a bit thanks to this excellent article from where I got an example of a BuilderStrategy. After I replaced my InjectionFactory with this extension, it worked for some cases, and didn't work for other.
After some investigation, it seems that all resolutions in Unity work against the same Container and its configuration, and any DependencyOverrides are dragged along the call in an IBuilderContext object, in a set of resolverOverrides which contains policies constructed from DependencyOverrides. The IBuilderContext provides a GetResolverOverride(Type) method which allows the implementation to get the value overrides for given Type.
So, if you explicitly ask the IBuilderContext.GetResolverOverride for an override for your Storage Context, you will get the Same-Context-Object you expect.
However, if you ever try to ask the Container itself, you will get a Context object resolved along the standard rules. Not that overridden-at-the-point-of-resolution.
This is why any attempt to container.Resolve(..) in the InjectionFactory delegate like here:
container.RegisterType<IStorage>(
new InjectionFactory(c => new StorageCacheDecorator(
c.Resolve<Storage>()))); // <-- this C is Container
will fail to satisfy overrides, because.. Container has no idea about overrides!
It would have to be:
container.RegisterType<IStorage>(
new InjectionFactory(c => new StorageCacheDecorator(
builderContext.Resolve<Storage>())));
which, if ever implemented, could access the GetResolverOverride and build a proper Storage with correct override. However, no such method exists, and, what's worse, at this point of code you don't have access to the IBuilderContext - InjectionFactory does not give it to you. Probably only extensions&friends can access that.
Fun fact: IBuilderContext has GetResolverOverride but doesn't have any sorts of .Resolve. So, if you'd take the code from that article and if you used the PreBuildUp as in that article to do your own resolution logic, you'd have to either use Container (and fail on resolver overrides), or get in a hell of inspecting everything and doing manually all sub-resolutions needed to construct the instance. IBuilderContext provides you a pretty-looking NewBuildUp() method, which seems a great shortcut, but .. it uses the base Container and doesn't forward resolver overrides.
Seeing how complicated and unintuitive it is, and how easy it is to accidentally drop that set of resolveroverrides and fallback to vanilla context, I'm pretty sure that InjectionFactory is EVIL/BUGGED/MISDESIGNED/etc: it gives you "c", your main Container instance, so you just have no way of resolving the parameters properly with respect to the overrides. Instead of that main container, we should get some sort of derived container, or extra builder object, etc..
Using the code at found in the article I was able to hack something that used this GetResolverOverride to initialize the new object instance in a way I wanted, but it was in no way generic and totally not reusable (I just called proper .GetResolverOverride to get the value and passed it right into new MyObject(value).. but, god, that's just awful. However, I needed as a part of a test setup, so I can live with that until the code gets refactored.
Now, let's get back to your case. Obviously you could do a similar thing, but it turns out that in case of decorators there is a much easier way: just get rid of the InjectionFactory. Your original instance initialization code was probably more complicated, but if by any chance it actually was as simple as in your example:
container.RegisterType<IStorage>(
new InjectionFactory(c =>
new StorageCacheDecorator( // <- NEW &
c.Resolve<Storage>() // <- RESOLVE
)));
you should have actually used declarative way instead of imperative buggy InjectionFactory:
container.RegisterType<IStorage, StorageCacheDecorator>(
new InjectionConstructor(
new ResolvedParameter<Storage>()
));
the net effect is exactly the same: new object created, the single-argument constructor is called, and Storage is resolved and used as that argument. I tried it with your test cases and it worked just fine.
Instead of 'ResolvedParameter` you can also use direct object instances, like:
container.RegisterType<IStorage, StorageCacheDecorator>(
new InjectionConstructor(
"foo", 5, new Shoe()
));
but, just as with new StorageDecorator in your original example, the InjectionConstructor needs to get all of the parameters for the constructor, and obviously we won't get a compile-time error when the constructor parameters change in the future. It's also much more limited than InjectionFactory as it needs to get all parameters specified up front.
All the more reason for for hating Unity..

Related

Inject dependency dynamically based on call chain using simple injector

In my application, I want to construct the following object graphs using my DI Container, Simple Injector:
new Mode1(
new CommonBuilder(
new Grouping(
new GroupingStrategy1())), // NOTE: Strategy 1
new CustomBuilder());
new Mode2(
new CommonBuilder(
new Grouping(
new GroupingStrategy2())), // NOTE: Strategy 2
new CustomBuilder());
The following classes represent the graphs above:
public class Mode1 : IMode
{
private readonly ICommonBuilder commonBuilder;
private readonly ICustomBuilder customBuilder;
public Mode1(ICommonBuilder commonBuilder, ICustomBuilder ICustomBuilder customBuilder)
{
this.commonBuilder = commonBuilder;
this.customBuilder = customBuilder;
}
public void Run()
{
this.commonBuilder.Build();
this.customBuilder.Build();
//some code specific to Mode1
}
}
public class Mode2 : IMode
{
//same code as in Mode1
public void Run()
{
this.commonBuilder.Build();
this.customBuilder.Build();
//some code specific to Mode2
}
}
With CommonBuilder and Grouping being:
public class CommonBuilder : ICommonBuilder
{
private readonly IGrouping grouping;
public CommonBuilder(IGrouping grouping)
{
this.grouping = grouping;
}
public void Build()
{
this.grouping.Group();
}
}
public class Grouping : IGrouping
{
//Grouping strategy should be binded based on mode it is running
private readonly IGroupingStrategy groupingStrategy;
public Grouping(IGroupingStrategy groupingStrategy)
{
this.groupingStrategy = groupingStrategy;
}
public void Group()
{
this.groupingStrategy.Execute();
}
}
I am using Simple Injector for DI in my project. As shown above, I've go 2 modes of code which are called as per user preference, I've got common code for each mode (which I don't want to duplicate), I want to bind my grouping strategy (I've go 2 grouping strategies, one for each mode) in my common code based on the mode of execution. I've come across solution to use factories and switch between bindings at run time, but I'don't want go with that solution as I've same scenario at multiple places in my code (I'll end up creating multiple factories).
Can anyone suggest how to do the binding in cleaner way
You can use Context-Based Injection. However, because the context-based injection based on consumer of the dependency's consumer (or parents of their parents) can lead to all sorts of complications and subtle bugs (especially when caching lifestyles such as Scoped and Singleton are involved), Simple Injector's API limits you to looking one level up.
There are several ways to work around this seeming limitation in Simple Injector. The first thing you should do is take a step back and see whether or not you can simplify your design, as these kinds of requirements often (but not always) come from design inefficiencies. One such issue is Liskov Substitution Principle (LSP) violations. From this perspective, it's good to ask yourself the question, would Mode1 break when it gets injected with a Grouping that contains the strategy for Mode2? If the answer is yes, you are likely violating the LSP and you should first and foremost try to fix that problem first. When fixed, you'll likely see your configuration problems go away as well.
If you determined the design doesn't violate LSP, the second-best option is to burn type information about the consumer's consumer directly into the graph. Here's a quick example:
var container = new Container();
container.Collection.Append<IMode, Mode1>();
container.Collection.Append<IMode, Mode2>();
container.RegisterConditional(
typeof(ICommonBuilder),
c => typeof(CommonBuilder<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);
container.RegisterConditional(
typeof(IGrouping),
c => typeof(Grouping<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);
container.RegisterConditional<IGroupingStrategy, Strategy1>(
c => typeof(Model1) == c.Consumer.ImplementationType
.GetGenericArguments().Single() // Consumer.Consumer
.GetGenericArguments().Single(); // Consumer.Consumer.Consumer
container.RegisterConditional<IGroupingStrategy, Strategy2>(
c => typeof(Mode2)) == c.Consumer.ImplementationType
.GetGenericArguments().Single()
.GetGenericArguments().Single();
In this example, instead of using a non-generic Grouping class, a new Grouping<T> class is created, and the same is done for CommonBuilder<T>. These classes can be a sub class of the non-generic Grouping and CommonBuilder classes, placed in your Composition Root, so you don't have to change your application code for this:
class Grouping<T> : Grouping // inherit from base class
{
public Grouping(IGroupingStrategy strategy) : base(strategy) { }
}
class CommonBuilder<T> : CommonBuilder // inherit from base class
{
public CommonBuilder(IGrouping grouping) : base(grouping) { }
}
Using this generic CommonBuilder<T>,1 you make a registration where the T becomes the type of the consumer it is injected into. In other words, Mode1 will be injected with a CommonBuilder<Mode1> and Mode2 will get a CommonBuilder<Mode2>. This is identical to what is common when registering ILogger implementations as shown in the documentation. Because of the generic typing, however, CommonBuilder<Mode1> will be injected with an Grouping<CommonBuilder<Mode1>>.
These registrations aren't really conditional, rather contextual. The injected type changes based on its consumer. This construct, however, makes the type information of IGrouping's consumer available in the constructed object graph. This allows the conditional registrations for IGroupingStrategy to be applied based on that type information. This is what happens inside the registration's predicate:
c => typeof(Mode2)) == c.Consumer.ImplementationType // = Grouping<CommonBuilder<Mode2>>
.GetGenericArguments().Single() // = CommonBuilder<Mode2>
.GetGenericArguments().Single(); // = Mode2
In other words, if we can change the IGrouping implementation in such way that its implementation's type (Grouping<T>) provides information about its consumers (the IMode implementations). This way the conditional registration of IGroupingStrategy can use that information about it's consumer's consumer.
Here the registration requests the consumer's implementation type (which will be either Grouping<Mode1> or Grouping<Mode2>) and will grab the single generic argument from that implementation (which will be either Mode1 or Mode2). In other words this allows us to get the consumer's consumer. This can be matched with the expected type to return either true or false.
Although this seems a bit awkward and complex, advantage of this model is that the complete object graph is known to Simple Injector, which allows it to analyze and verify the object graph. It also allows Auto-Wiring to take place. In other words, if IGrouping or IGroupingStrategy implementations have (other) dependencies, Simple Injector will automatically inject them and verify their correctness. It also allows you to visualize the object graph without losing any information. For instance, this is the graph that Simple Injector will show if you hover over it in the Visual Studio debugger:
Mode1(
CommonBuilder<Mode1>(
Grouping<CommonBuilder<Mode1>>(
Strategy1())))
The apparent downside of this approach is that if either CommonBuilder<T> or Grouping<T> are registered as singleton, there will now be a single instance per closed-generic type. This means that CommonBuilder<Mode1> will be a different instance than CommonBuilder<Mode2>.
Alternatively, you can also just make the CommonBuilder registration conditional as follows:
var container = new Container();
container.Collection.Append<IMode, Mode1>();
container.Collection.Append<IMode, Mode2>();
container.RegisterConditional<ICommonBuilder>(
Lifestyle.Transient.CreateRegistration(
() => new CommonBuilder(new Grouping(new Strategy1())),
container),
c => c.Consumer.ImplementationType == typeof(Mode1));
container.RegisterConditional<ICommonBuilder>(
Lifestyle.Transient.CreateRegistration(
() => new CommonBuilder(new Grouping(new Strategy2())),
container),
c => c.Consumer.ImplementationType == typeof(Mode2));
This is a bit simpler than the previous approach, but it disables Auto-Wiring. In this case CommonBuilder and its dependencies are wired by hand. When the object graph is simple (doesn't contain many dependencies), this method can be good enough. When dependencies are added to either CommonBuilder, Grouping or the strategies, however, this can cause high maintenance and might hide bugs as Simple Injector will be unable to verify the dependency graph on your behalf.
Please do be aware of the following statement in the documentation about the RegisterConditional methods:
The predicates are only used during object graph compilation and the predicate’s result is burned in the structure of returned object graph. For a requested type, the exact same graph will be created on every subsequent call. This disallows changing the graph based on runtime conditions.

Creating plugin instances with context using DI

I'm refactoring our application to include Dependency Injection (via constructor injection) and have run into a tricky corner-case:
We currently have ImageViewer objects that when instantiated search the assembly for ImageViewerPlugin (an abstract base class) instances, instantiating them using reflection. This is done in the constructor of the ImageViewer using a method (called in a loop for all concrete plugin types) that is similar to:
private ImageViewerPlugin LoadPlugin(Type concretePluginType)
{
var pluginConstructor = concretePluginType.GetConstructor(
BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public,
null,
new[] { typeof(ImageViewer) },
null);
return (ImageViewerPlugin) pluginConstructor.Invoke(
new object[] { constructorParameter });
}
The ImageViewerPlugin class looks roughly like this:
internal ImageViewerPlugin
{
protected ImageViewer _viewer;
protected ImageViewerPlugin(ImageViewer viewer)
{
_viewer = viewer;
}
}
A concrete implementation looks roughly like this:
internal AnImageViewerPlugin
{
public AnImageViewerPlugin(ImageViewer viewer) : base(viewer)
{
}
}
Each ImageViewer instance has its own collection of ImageViewerPlugin instances.
Now that the application being refactored to use a DI container and constructor injection I'm discovering that these plugins have dependencies (which were previously hidden through the use of global static classes) that need to be resolved by the DI container, but I'm not sure how to do that without using a Service Locator (an anti-pattern).
The most sensible solution seems to be to create these plugin instances using DI. This would allow me to add extra constructor parameters to have the dependencies they rely on injected via constructor injection. But if I do that, how can I pass a specific viewer parameter value while having the rest of the parameter values injected?
I thought an ImageViewerPluginFactory would help to achieve this but can't see how to implement such a factory as each plugin is likely to have a different constructor signature.
How can I solve this scenario? Or am I approaching this totally the wrong way?
So you have an ImageViewer that depends on a collection of ImageViewerPlugin instances, which each depend on n ImageViewer that depends on a collection of ImageViewerPlugin instances, which each depend on n ImageViewer that depends on a collection of ImageViewerPlugin instances, which each depend on an ... well you get the picture :-)
This is a circular reference. Leaving the whole DI container thing aside, how would you create this hierarchy when doing this manually? With constructor injection you can't. It can be seen from the following example:
var plugin = new ImageViewerPlugin( [what goes here?] );
var viewer = new ImageViewer(plugin);
You will have to break this dependency cycle somehow and the general advice is to fall back on property injection in this case:
var plugin = new ImageViewerPlugin();
var viewer = new ImageViewer(plugin);
// Property injection
plugin.Viewer = viewer;
But even more, you should take a good look at the design of the application, since a circular reference often is an indication of a problem in the design. For instance, take a good look what behavior the plugin needs from the viewer and what behavior the viewer needs from the plugins. You might be able to extract this to another class, as follows:
var imageServices = new ImageServices();
var plugin = new ImageViewerPlugin(imageServices);
var viewer = new ImageViewer(imageServices, plugin);
This solves the problem completely, but it depends on your situation whether this is feasible.
With the last solution, registration with Simple Injector would be rather straight forward. When breaking the dependency using property injection, you can make use of the RegisterInitializer(Action) method. It allows you to break the dependency cycle. For instance:
container.RegisterInitializer<ImageViewer>(viewer =>
{
foreach (var plugin in viewer.Plugins)
{
plugin.Viewer = viewer;
}
});

Dynamic dependencies in deep object graphs - what am I doing wrong?

I'm trying to modify some existing code to use Castle Windsor as an IoC container.
The application in question is document-oriented. So it has an object graph that relies on data for specifying the data source that can't be known at registration time, and will change every time the object graph is resolved. However, this dependency is a few layers into the object graph, so I can't just pass it as an argument to container.Resolve() since Windsor doesn't propagate inline dependencies.
The solution I've come up with instead is to use the typed factory facility to generate a factory which can resolve every dependency in the graph, and have Document's constructor take an instance of this factory as well as a string specifying the data source. The factory is specified at registration time, and the data source is specified at resolution time. The constructor takes over from there, manually polling the factory to resolve is dependencies. The result looks something like this:
public interface IDataSource { /* . . . */ }
public interface IWidgetRepository { /* . . . */ }
public interface IWhatsitRepository { /* . . . */ }
// Implementation generated by Windsor's typed factory facility
public interface IFactory
{
IDataSource CreateDataSource(string path);
IWidgetRepository CreateWidgetRepository(IDataSource dataSource);
IWhatsitRepository CreateWhatsitRepository(IDataSource dataSource);
void Release(IDataSource dataSource);
void Release(IWidgetRepository widgetRepository);
void Release(IWhatsitRepository whatsitRepository);
}
public class Document
{
private readonly IDataSource _dataSource;
private readonly IWidgetRepository _widgetRepository;
private readonly IWhatsitRepository _whatsitRepository;
public Document (IFactory factory, string dataSourcePath)
{
_dataSource = factory.CreateDataSource(dataSourcePath);
_widgetRepository = factory.CreateWidgetRepository(_dataSource);
_whatsitRepository = factory.CreateWhatsitRepository(_dataSource);
}
}
This absolutely works, and does accomplish the goal of having Windsor take charge of dependency resolution. Or at least, I can easily reconfigure the application by modifying the registration code. At the moment I'm still making one call to container.Resolve() for every Document that gets created, but I believe that sin can easily be amended with a second Typed Factory.
However, it still feels wrong. Windsor is in charge of newing up objects and (somewhat) managing their lifetimes, sure. But it's not really injecting those dependencies into Document's constructor; instead the constructor is pulling them out of the factory. Worse, by passing the instance of IDataSource into the factory methods, it's taken charge of managing the object graph. That seems like a huge subversion of the inversion to me.
So, what am I missing?
EDIT
To clarify, what I think I'm supposed to be shooting for is for Document's constructor to look more like the below.
public Document (IDataSource dataSource, IWidgetRepository widgetRepository, IWhatsitRepository whatsitRepository)
{
_dataSource = dataSource;
_widgetRepository = widgetRepository;
_whatsitRepository = whatsitRepository;
}
That way Windsor is in direct control of supplying all the objects' dependencies using constructor injection. That's actually what the constructor signature looks like in the original code, but I was unable to get it to work with Windsor because container.Resolve() doesn't propagate inline dependency parameters. So I can't just do:
var document = container.Resolve<IDocument>(new { dataSourcePath = somePath }); // throws an exception
because Windsor doesn't pass dataSourcePath on to DataSource's constructor, much less make sure that a DataSource instantiated with that path is passed on to the other constructors.
An answer to another question points out that this is by design - doing otherwise would introduce coupling. This is a no-no, since one shouldn't mandate or assume that implementations of an interface have particular dependencies. Sadly, that points out another way I think the code I came up with is wrong, since Factory.CreateWidgetRepository() and Factory.CreateWhatsitRepository() imply just that sort of assumption.
I believe I've found the correct solution. Apparently the available documentation wasn't quite explicit (verbose?) enough to bang the concept through my thick skull the first twelve times I read it, so I'll make an attempt to document it in more detail here for the sake of others who might be as helpless as I am. (I'll also let it sit a while before accepting in the hope that someone else might come along with any other/better suggestions.)
Long story short, Typed Factory Facility is the wrong tool for the job.
--
The trick is to use the DynamicParameters facility in the fluent registration API, which is (rather sparsely) documented here and in the last section here.
What DynamicParameters lets you do is directly modify the collection of inline parameters that was supplied when the container was asked to resolve a component. This dictionary can then get passed on up the resolution pipeline, making it available to sub-dependencies.
DynamicParameters has three overloads, each taking a single delegate as its parameter. These delegate types aren't explicitly documented, so for the sake of posterity here's what ReSharper (I'm too lazy to download the source.) tells me their declarations look like:
public delegate void DynamicParametersDelegate(IKernel kernel, IDictionary parameters);
public delegate ComponentReleasingDelegate DynamicParametersResolveDelegate(IKernel kernel, IDictionary parameters);
public delegate ComponentReleasingDelegate DynamicParametersWithContextResolveDelegate(IKernel kernel, CreationContext creationContext, IDictionary parameters);
DynamicParametersDelegate is for the most basic case, where you just need to supply parameters that won't be managed by the container. That probably works for me, but in keeping with my tendency to find the complicated option first I ended up making a beeline for the second option, which is to supply a delegate which manually pulls dynamic parameters out of the container. Since Windsor's managing the component's lifetime in that case, you need to make sure it's being released. That's where DynamicParametersResolveDelegate comes in - it's just like the first one, except it also returns a ComponentReleasingDelegate (public delegate void ComponentReleasingDelegate(IKernel kernel);) which Windsor can use to release components at the appropriate time.
(The third, DynamicParametersWithContextResolveDelegate, is presumably for modifying the creation context. I don't know enough about how Windsor works to actually understand what the preceding sentence means, so I'll have to leave it at that.)
That allows me replace the constructor from my example with the much better-looking:
public class Document
{
private readonly IDataSource _dataSource;
private readonly IWidgetRepository _widgetRepository;
private readonly IWhatsitRepository _whatsitRepository;
public Document (IDataSource dataSource, IWidgetRepository widgetRepository, IWhatsitRepository whatsitRepository)
{
_dataSource = dataSource;
_widgetRepository = widgetRepository;
_whatsitRepository = whatsitRepository;
}
}
The factory is removed entirely. Instead, the magic goes in the component registration code for IDocument:
container.Register(Component.For<IDocument>()
.ImplementedBy<Document>()
.DynamicParameters(
(k, d) =>
{
// ask for an IDataSource, passing along any inline
// parameters that were supplied in the request for
// an IDocument
var ds = k.Resolve<IDataSource>(d);
// Add it to the dictionary. This makes it available
// for use when resolving other dependencies in the tree.
d.Add("DataSource", ds);
// Finally, pass back a delegate which can be used to release it
return (r) => r.ReleaseComponent(ds);
}));
So now I can ask for an IDocument with exactly the line of code I had been looking for:
var document = container.Resolve<IDocument>(new { dataSourcePath = somePath });
and the container starts by invoking that DynamicParameters delegate, which supplies the container with a DataSource for the supplied path. From there the container's able to figure the rest out for itself so that the same instance of DataSource gets passed to the constructors for all three of the other objects in the dependency graph.
I have the same issue. The problem I have with the above solution is that you will be calling :
var document = container.Resolve<IDocument>(new { dataSourcePath = somePath });
at each point where you need an IDocument. I think I should really be resolving all of my objects at a single point in the program and not using the container anywhere else. In other words, resolving a factory from the container once, and then using that factory at other points in the program. I think you were on the right track initially. Having said all that, I can't offer a better solution.

Typical IoC container usage - passing data down the line

I've recently started using an IoC container for the first time, but I'm not educated on the best practices for using it. More specificaly I'm using Unity in a C# .NET project, and I started using it because it came with Prism.
I use the container to resolve the "top level" objects, and they get the correct objects injected based on the container. However, I can't see the best practice clearly when I have an object with children and children's children, and I need some data from the IoC container all the way down, but not in between. How you'd typically organize the use of IoC container?
Initially I'd think that you'd pass the container everywhere it is needed instead of extracting the needed data from the container on top-level and passing this data on. But then again I get problems when I reach objects which take other specific data in addition to the injected interfaces, and I'd prefer not to inject these through properties or init-methods after resolving the object.
I hope this was clear enough, but let's look at a fictional (and slightly stupid..) example.
class Employee
{
private ICommands _commands;
priate List<Customer> _customers = new List<Customer>();
public Employee(ICommands commands)
{
_commands = commands;
}
public void AddCustomer(string customerName)
{
var customer = new Customer(customerName, _commands);
_customers.Add(customer);
}
}
class Customer
{
private string _name;
private ICommands _commands;
priate List<Case> _cases = new List<Case>();
public Customer(string, name, ICommands commands)
{
_name = name;
_commands = commands;
}
public void AddCase()
{
var case = new Case(_commands);
_cases.Add(case);
}
}
class Case {
private ICommands _commands;
public Customer(ICommands commands)
{
_commands = commands;
}
public void TriggerCommands()
{
_command.TriggerSomething();
}
}
So, this example doesn't really make much sense, but the essence is the same of what I need to do. I have some application commands I pass down the line through my ViewModel classes, because some of them need to be able to trigger commands to display something. I also have common storage, etc. which may be needed for some classes but currently are passed through and stored in middle classes. With only commands it's no big deal if you store commands or container, but would one in a typical IoC-usage pass the IoC container instead, and use this for resolving objects down the line? And what about specific data like the customer name? You can't just pass this in on the Resolve(), so you need to inject that afterwards?
Sorry - this was as short as I was able to make it. Won't require answers of the same length ;-) .. Just; what's the best practice of doing stuff like this with IoC containers?
I'm not quite sure that I understand your question. But I don't think you should be passing the container around at all. It's much easier to just create a wrapper class for the container. For example:
public class IoCContainer
{
private static ContainerType = null;
public static ContainerType Instance
{
get
{
if (_container == null)
{
string configFileName = ConfigurationManager.AppSettings[ConfigFileAppSettingName];
_container = new WindsorContainer(new XmlInterpreter(configFileName));
}
return _container;
}
}
}
Now you call this everywhere in your code.
IoCContainer.Instance.Resolve<IAwesomeService>();
Does this help you?
I'm not sure if this answers your question, but I would say that a good way to act on an application using the Unity container (also applicable to other IoC engines I think) is:
Design your classes so that all the
required dependencies are specified
in the constructor. This way you
don't need to explicitly deal with
Unity unless you need to create new
objects.
If you need to create new objects
within your classes, pass the Unity
container itself in the constructor
as well (as a reference to
IUnityContainer), and create all new
object instances by using the Resolve
method. Even for objects that are not
registered and have not dependencies,
the container will give you a proper
instance, and later you can decide to register types that were not previously registered, without changing the client code.
As for passing explicit values to resolved objects, you can specify concrete injection members when you register types (see the InjectionMembers parameter in the RegisterType class).
It seems that you need to declare factories for your entities. Resolve factories via constructor injection and pass data values via Create method. All other dependencies must be resolved via factory's constructor.
See this answer.
I'd define a static class IoC, that can be initialized with a particular container and implement methods like Resolve, Resolve(...), which in turn delegate the actual work to the container instance (you'll store this instance in a field or property). This way you don't have to pass anything around, just use
IoC.Resolve<SomeType>();
anywhere in your code.
Regarding the specific data: some containers will take a parameter and resolve depending on this parameter (Autofac has this kind of feature). Or you can always create a factory class that will have a method that accepts a set of parameters (like customer name) and returns a corresponding object instance.

Can I pass constructor parameters to Unity's Resolve() method?

I am using Microsoft's Unity for dependency injection and I want to do something like this:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA and RepositoryB both have a constructor that takes an IDataContext parameter, and I want Unity to initialize the repository with the context that I pass it. Also note that IDataContext is not registered with Unity (I don't want 3 instances of IDataContext).
As of today they have added this functionality:
It’s in the latest drop here:
http://unity.codeplex.com/SourceControl/changeset/view/33899
Discussion on it here:
http://unity.codeplex.com/Thread/View.aspx?ThreadId=66434
Example:
container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
< 2 cents>
What if you later on decide to use a different service that requires more or less than just the context?
The problem with constructor parameters and IoC is that the parameters are ultimately tied to the concrete type being used, as opposed to being part of the contract that the service interface defines.
My suggestion would be that you either resolve the context as well, and I believe Unity should have a way for you to avoid constructing 3 instances of it, or you should consider a factory service that has a way for you to construct the object.
For instance, what if you later on decide to construct a repository that doesn't rely on a traditional database at all, but instead use an XML file to produce dummy-data for the test? How would you go about feeding the XML content to that constructor?
IoC is based around decoupling code, by tying in the type and semantics of the arguments to the concrete types, you really haven't done the decoupling correctly, there's still a dependency.
"This code can talk to any type of repository possibly, as long as it implements this interface.... Oh, and uses a data context".
Now, I know that other IoC containers have support for this, and I had it in my first version of my own as well, but in my opinion, it doesn't belong with the resolution step.
< /2 cents>
Thanks guys ... mine is similar to the post by "Exist". See below:
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
_activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
{
new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
});
You can use InjectionConstructor / InjectionProperty / InjectionMethod depending on your Injection Architecture within the ResolvedParameter< T >("name") to get a instance of a pre-registered Object in the container.
In your case this Object must be registered with a Name, and for the same insance you need ContainerControlledLifeTimeManager() as the LifeTimeManager.
_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");
var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));
The very short answer is: no. Unity currently has no way to pass parameters into the constructor that aren't constant or injected, that I have been able to find. IMHO that's the single biggest thing it's missing, but I think it is by design rather than by omission.
As Jeff Fritz notes, you could in theory create a custom lifetime manager that knows which context instance to inject into various types, but that's a level of hard-coding which seems to obviate the purpose of using Unity or DI in the first place.
You could take a small step back from full DI and make your repository implementations responsible for establishing their own data contexts. The context instance can still be resolved from the container but the logic for deciding which one to use would have to go into the implementation of the repository. It's not as pure, certainly, but it would get rid of the problem.
Another alternative you could use (don't really know if it is a good practice or not) is creating two containers and registering an instance for each:
IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context
//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance
hope this helps too
NotDan, I think you may have answered your own question in comments to lassevk.
First, I would use a LifetimeManager to manage the lifecycle and number of instances of IDataContext that Unity creates.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
It sounds like the ContainerControlledLifetimeManager object will give you the instance management that you need. With that LifetimeManager in place, Unity should add the same instance of the IDataContext to all objects that require an IDataContext dependency.

Categories

Resources