Inject dependency dynamically based on call chain using simple injector - c#

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.

Related

Dependency Injection in Akka .NET with state constructor parameters

Having something like a string parameter in a constructor makes dependency injection very messy. Think:
public class CurrencyActor
{
public CurrencyActor(string currency, IRepository repository)
{
...
There have been other questions (such as this one) to address this particular problem with dependency injection. Often this is solved by rethinking the design and refactoring.
However, what if it actually makes sense to have multiple versions of an object that are each responsible for different data (e.g. a CurrencyActor for each currency)? This is pretty normal when using an actor model such as Akka .NET, but makes sense even outside that domain.
What is the best way to create these multiple instances using dependency injection while passing in the initial state they need?
Having a dependency in a constructor is not messy, it's very very common. There is nothing wrong with this.
You could create a default props static method on the CurrencyActor that takes in your dependencies:
public static Props CreateProps(string currency, Irepository repo)
{
return Props.Create(() => new CurrrncyActor(currency, repo));
}
Then create as many as you like:
var usCurrency = system.ActorOf(CurrencyActor.CreateProps("US", someRepo), "US");
var swedishCurrency = system.ActorOf(CurrencyActor.CreateProps("SEK", someRepo), "SEK");
[Update]
Regarding the use of DI containers with Akka, this was listed as no. 2 out of the top 7 mistakes people make when using akka.net
https://petabridge.com/blog/top-7-akkadotnet-stumbling-blocks/
Thus it’s considered to be a good practice for actors to manage their own dependencies, rather than delegate that work to a DI framework.
So basically don't do it. And if you must, according to that article, Autofac is the best choice
[Update 2]
If you want to dynamically create new instances of the same Actor but change some initial state, then you could have a Supervisor that is responsible for creating them:
public class MatchesSupervisor : ReceiveActor
{
List<IActorRef> _matches = new List<IActorRef>();
public void MatchesSupervisor()
{
Receive<SomeCommandToStartANewMatch>(msg =>
{
// store the currently active matches somewhere, maybe on a FullTime message they would get removed?
_matches.Add(Context.ActorOf(MatchActor.Create(msg.SomeMatchId)));
}
}
}
In the above example, there is no DI container being used, and if each MatchActor needed something else, like an IRepository, then this would be passed into the MatchesSupervisor when it is created, and subsequently passed to each MatchActor when they are created.
It also kinda depends where the state is coming from, and what the mechanism is for starting a new Match - i've just presumed some other Actor is sending a message.
(I'm typing on an ipad so the above code might not actually compile but hopefully you get the idea, i also left out an implementation of MatchActor, but it would just be an Actor that gets some values passed into its constructor)
Hope this helps!

Abstract Factory fit into Unity

We are building an application which has a number integration touch points with other systems. We are effectively using Unity for all our dependency injection needs. The whole business layer has been built with an interface driven approach, with the actual implementation being injected at an outer composition root during bootstrap of the application.
We wanted to handle the integration layer in an elegant manner. The business classes and repositories are dependent on IIntegrationController<A, B> interfaces. Several IIntegrationController<A, B> implementations together represent integration with one target system in the background - forming an integration layer. Currently, we hook up everything in the composition root, one shot, at the beginning. The consumers of this interface are also registered with an appropriate InjectionConstrutor and ResolvedParameter up front. Most types are operating with a PerResolveLifetime and the business classes consuming the IIntegrationController are also resolved for each request context separately.
Refer code below.
// IIntegrationController Family 1
// Currently the default registration for IIntegrationController types injected into the business classes
container.RegisterType<IIntegrationController<A, B>, Family1-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family1-IntegrationController<C, D>>();
// IIntegrationController Family 2 (currently not registered)
// We want to be able to register this, or manage this set of mapping registrations separately from Family 1,
// and be able to hook these up dynamically instead of Family-1 on a per-resolve basis
container.RegisterType<IIntegrationController<A, B>, Family2-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family2-IntegrationController<C, D>>();
// Repository/Business Class that consume IIntegrationControllers.
// There is a whole family of IIntegrationController classes being hooked in,
// and there are multiple implementations for the family (as shown above). A typical AbstractFactory scenario.
container.RegisterType(typeof(Repository<Z>), new PerResolveLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<IIntegrationController<A, B>>(),
new ResolvedParameter<IIntegrationController<C, D>>())
);
Problem Statement:
We want the ability to switch an entire family of IIntegrationController<A, B> at runtime. When the business class is being resolved, we want it to be injected with the right version of IIntegrationController<A, B>, based on a request parameter available in the context.
A "named" registration based solution would not be scalable, due to two reasons (an entire family of integration classes has to be switched, and it would require clunky name registrations and conditional resolution in the code making it hard to maintain).
The solution should work even when there is a chain/hierarchy of resolutions taking place, i.e. the direct consumer of the IIntegrationController is also resolved through Unity, as it is injected into another class dynamically.
We have tried a DependencyOverride and ResolveOverride class during resolution, but that would require the whole set of Family-2 IIntegrationController resolutions to be overriden, instead of just being able to switch the whole layer.
We understand that instead of injecting a IIntegrationController directly into the business class, an AbstractFactory may have to be injected, but we are not able to get that working, and are not sure where the registration and resolution would happen. If the business class is hooked with an AbstractFactory, first I would have to hook up the right factory per-resolve,
Does this require overriding the InjectionFactory? This link suggests an approach, but we were unable to get it to work smoothly.
What's nice about your design is that you already have the right abstractions in place. You use generic abstractions, so the problem can be solved simply by applying the right patterns on top of your already SOLID design.
In other words, use a proxy:
// This class should be considered part of your composition root.
internal class IntegrationControllerDispatcher<TRequest, TResult>
: IIntegrationController<TRequest, TResult>
{
private readonly IUserContext userContext;
private readonly Family1_IntegrationController<A, B> family1Controller;
private readonly Family2_IntegrationController<A, B> family2Controller;
public IntegrationControllerDispatcher(
IUserContext userContext,
Family1_IntegrationController<A, B> family1Controller,
Family2_IntegrationController<A, B> family2Controller) {
this.userContext = userContext;
this.family1Controller = family1Controller;
this.family2Controller = family2Controller;
}
public TResult Handle(TRequest request) {
return this.GetController().Handle(request);
}
private IIntegrationController<TRequest, TResult> GetController() {
return this.userContext.IsInFamily("family1"))
? this.family1Controller
: this.family2Controller;
}
}
With this class you whole configuration can be reduced to about this:
container.RegisterType<IUserContext, AspNetUserContext>();
container.RegisterType(
typeof(IIntegrationController<,>),
typeof(IntegrationControllerDispatcher<,>));
container.RegisterType(typeof(Repository<>), typeof(Repository<>));
Note the following:
Note the use of the registrations that do an open-generic mapping. You don't have to register ALL your closed versions one by one. You can do it with one line of code.
Also note that the types for the different families aren't
registered. Unity can resolve them automatically, because our
IntegrationControllerDispatcher depends on them directly. This
class is a piece of infrastructure logic and should be placed inside
your Composition Root.
Note that the decision to use a specific family implementation is not made during the time that the object graph is built; It is made at runtime, because the value that determines this is a runtime value. Trying to determine this at the time the object graph is built, will only complicate things, and make it much harder to verify your object graphs.
Furthermore, this runtime value is abstracted behind a function call and placed behind an abstraction (IUserContext.IsInFamily in this case, but that's just an example of course).

Is using static factories a valid pattern for dependency injection?

I'm creating an internal framework, and at one point I would like to provide a good extensibility, supporting kind of dependecy injection.
Here is a simplified example of my filtering module in .NET/C#. Imagine there is a filter processor component, which takes a List of objects, each representing a filter condition. Then its task is "translate" these to Expressions and apply it to any IQueryable. There are trivial fitler types, for example a ColumnFilter, which refers to a fieldname, an operator, and some operands. However, I would like to provide a way to consumers to extend the filter processing mechanism with custom filter conditions. So I introduce an interface:
public interface IFilterProcessor {
Expression Process(FilterContext filter);
}
where FilterContext holds information like the currently processed filter, the root ParameterExpression, the Type of the root IQueryable, etc., not important for this example.
Then at some point one could define a new filter condition, and provide a corresponding IFilterProcessor to it, and implement the translation of the condition there.
And here comes my idea, I would provice the extensibility point as staticly registerable factories, something like this:
public class FilterProcessor {
public static readonly Dictionary<Type, Func<IFilterProcessor>> ProcessorFactories = new ...
{
{typeof(ColumnFilter), () => new ColumnFilterProcessor() }
};
...
public Expression Process(object filterCondition) {
if (filterCondition == null) return null;
var factory = ProcessorFactories.GetValueOfDefault(filterCondition.GetType()); // my custom Dictionary extension to avoid exceptions and return null if no key found
if (factory == null) return null;
using (var processor = factory()) {
return processor.Process(filterCondition);
}
}
...
}
Then at the entry point of the application I can "register" my custom filter condition processors like this:
FilterProcess.ProcessorFactories[typeof(MyCustomCondition)] = () => ... get from Ninject for example ...;
The idea behind using this pattern is that the core framework does not have to know anything about the extensions, similar to some "plugin" system.
Note that this is farly simplified and lot of things are omitted for clarity. In reality for example my filters can be grouped, nested, etc., whole lot complex.
And now my question:
I've been reading for a long time about design patterns, especially DI, but haven't found any example similar to this one. Is this a valid, and globally accepted pattern? If there is any, could anyone point out any contras about it? Finally, if this is a valid pattern, does it have a name?
Looks like you're asking and not telling (http://en.wikipedia.org/wiki/Hollywood_principle) by setting the processors using the property.
I think you can achieve the same outcome in a more 'classic' DI way: Make your FilterProcessor dependent on an enumeration of IFilterProcessor and then let the IoC framework do the resolution and injection for you by registering IFilterProcessors by convention.

Dependency Injection and the Strategy Pattern

There is an enormous amount of discussion on this topic, but everyone seems to miss an obvious answer. I'd like help vetting this "obvious" IOC container solution. The various conversations assume run-time selection of strategies and the use of an IOC container. I will continue with these assumptions.
I also want to add the assumption that it is not a single strategy that must be selected. Rather, I might need to retrieve an object-graph that has several strategies found throughout the nodes of the graph.
I will first quickly outline the two commonly proposed solutions, and then I will present the "obvious" alternative that I'd like to see an IOC container support. I will be using Unity as the example syntax, though my question is not specific to Unity.
Named Bindings
This approach requires that every new strategy has a binding manually added:
Container.RegisterType<IDataAccess, DefaultAccessor>();
Container.RegisterType<IDataAccess, AlphaAccessor>("Alpha");
Container.RegisterType<IDataAccess, BetaAccessor>("Beta");
...and then the correct strategy is explicitly requested:
var strategy = Container.Resolve<IDataAccess>("Alpha");
Pros: Simple, and supported by all IOC Containers
Cons:
Typically binds the caller to the IOC Container, and certainly requires the caller to know something about the strategy (such as the name "Alpha").
Every new strategy must be manually added to the list of bindings.
This approach is not suitable for handling multiple strategies in an object graph. In short, it does not meet requirements.
Abstract Factory
To illustrate this approach, assume the following classes:
public class DataAccessFactory{
public IDataAccess Create(string strategy){
return //insert appropriate creation logic here.
}
public IDataAccess Create(){
return //Choose strategy through ambient context, such as thread-local-storage.
}
}
public class Consumer
{
public Consumer(DataAccessFactory datafactory)
{
//variation #1. Not sufficient to meet requirements.
var myDataStrategy = datafactory.Create("Alpha");
//variation #2. This is sufficient for requirements.
var myDataStrategy = datafactory.Create();
}
}
The IOC Container then has the following binding:
Container.RegisterType<DataAccessFactory>();
Pros:
The IOC Container is hidden from consumers
The "ambient context" is closer to the desired result but...
Cons:
The constructors of each strategy might have different needs. But now the responsibility of constructor injection has been transferred to the abstract factory from the container. In other words, every time a new strategy is added it may be necessary to modify the corresponding abstract factory.
Heavy use of strategies means heavy amounts of creating abstract factories. It would be nice if the IOC container simply gave a little more help.
If this is a multi-threaded application and the "ambient context" is indeed provided by thread-local-storage, then by the time an object is using an injected abstract-factory to create the type it needs, it may be operating on a different thread which no longer has access to the necessary thread-local-storage value.
Type Switching / Dynamic Binding
This is the approach that I want to use instead of the above two approaches. It involves providing a delegate as part of the IOC container binding. Most all IOC Containers already have this ability, but this specific approach has an important subtle difference.
The syntax would be something like this:
Container.RegisterType(typeof(IDataAccess),
new InjectionStrategy((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
Type selectedStrategy = ...;
return selectedStrategy;
})
);
Notice that the InjectionStrategy is not returning an instance of IDataAccess. Instead it is returning a type description that implements IDataAccess. The IOC Container would then perform the usual creation and "build up" of that type, which might include other strategies being selected.
This is in contrast to the standard type-to-delegate binding which, in the case of Unity, is coded like this:
Container.RegisterType(typeof(IDataAccess),
new InjectionFactory((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
IDataAccess instanceOfSelectedStrategy = ...;
return instanceOfSelectedStrategy;
})
);
The above actually comes close to satisfying the overall need, but definitely falls short of the hypothetical Unity InjectionStrategy.
Focusing on the first sample (which used a hypothetical Unity InjectionStrategy):
Pros:
Hides the container
No need either to create endless abstract factories, or have consumers fiddle with them.
No need to manually adjust IOC container bindings whenever a new strategy is available.
Allows the container to retain lifetime management controls.
Supports a pure DI story, which means that a multi-threaded app can create the entire object-graph on a thread with the proper thread-local-storage settings.
Cons:
Because the Type returned by the strategy was not available when the initial IOC container bindings were created, it means there may be a tiny performance hit the first time that type is returned. In other words, the container must on-the-spot reflect the type to discover what constructors it has, so that it knows how to inject it. All subsequent occurrences of that type should be fast, because the container can cache the results it found from the first time. This is hardly a "con" worth mentioning, but I'm trying for full-disclosure.
???
Is there an existing IOC container that can behave this way? Anyone have a Unity custom injection class that achieves this effect?
As far as I can tell, this question is about run-time selection or mapping of one of several candidate Strategies.
There's no reason to rely on a DI Container to do this, as there are at least three ways to do this in a container-agnostic way:
Use a Metadata Role Hint
Use a Role Interface Role Hint
Use a Partial Type Name Role Hint
My personal preference is the Partial Type Name Role Hint.
I have achieved this requirement in many forms over the last couple of years. Firstly let's pull the main points I can see in your post
assume run-time selection of strategies and the use of an IOC container ... add the assumption that it is not a single strategy that must be selected. Rather, I might need to retrieve an object-graph that has several strategies ... [must not] binds the caller to the IOC Container ... Every new strategy must [not need to] be manually added to the list of bindings ... It would be nice if the IOC container simply gave a little more help.
I have used Simple Injector as my container of choice for some time now and one of the drivers for this decision is that it has extensive support for generics. It is through this feature that we will implement your requirements.
I'm a firm believer that the code should speak for itself so I'll jump right in ...
I have defined an extra class ContainerResolvedClass<T> to demonstrate that Simple Injector finds the right implementation(s) and successfully injects them into a constructor. That is the only reason for the class ContainerResolvedClass<T>. (This class exposes the handlers that are injected into it for test purposes via result.Handlers.)
This first test requires that we get one implementation back for the fictional class Type1:
[Test]
public void CompositeHandlerForType1_Resolves_WithAlphaHandler()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type1>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(1));
Assert.That(handlers.Contains(typeof(AlphaHandler<Type1>)), Is.True);
}
This second test requires that we get one implementation back for the fictional class Type2:
[Test]
public void CompositeHandlerForType2_Resolves_WithAlphaHandler()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type2>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(1));
Assert.That(handlers.Contains(typeof(BetaHandler<Type2>)), Is.True);
}
This third test requires that we get two implementations back for the fictional class Type3:
[Test]
public void CompositeHandlerForType3_Resolves_WithAlphaAndBetaHandlers()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type3>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(2));
Assert.That(handlers.Contains(typeof(AlphaHandler<Type3>)), Is.True);
Assert.That(handlers.Contains(typeof(BetaHandler<Type3>)), Is.True);
}
These tests seems to meet your requirements and best of all no containers are harmed in the solution.
The trick is to use a combination of parameter objects and marker interfaces. The parameter objects contain the data for the behaviour (i.e. the IHandler's) and the marker interfaces govern which behaviours act on which parameter objects.
Here are the marker interfaces and parameter objects - you'll note that Type3 is marked with both marker interfaces:
private interface IAlpha { }
private interface IBeta { }
private class Type1 : IAlpha { }
private class Type2 : IBeta { }
private class Type3 : IAlpha, IBeta { }
Here are the behaviours (IHandler<T>'s):
private interface IHandler<T> { }
private class AlphaHandler<TAlpha> : IHandler<TAlpha> where TAlpha : IAlpha { }
private class BetaHandler<TBeta> : IHandler<TBeta> where TBeta : IBeta { }
This is the single method that will find all implementations of an open generic:
public IEnumerable<Type> GetLoadedOpenGenericImplementations(Type type)
{
var types =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from t in assembly.GetTypes()
where !t.IsAbstract
from i in t.GetInterfaces()
where i.IsGenericType
where i.GetGenericTypeDefinition() == type
select t;
return types;
}
And this is the code that configures the container for our tests:
private Container ContainerFactory()
{
var container = new Container();
var types = this.GetLoadedOpenGenericImplementations(typeof(IHandler<>));
container.RegisterAllOpenGeneric(typeof(IHandler<>), types);
container.RegisterOpenGeneric(
typeof(ContainerResolvedClass<>),
typeof(ContainerResolvedClass<>));
return container;
}
And finally, the test class ContainerResolvedClass<>
private class ContainerResolvedClass<T>
{
public readonly IEnumerable<IHandler<T>> Handlers;
public ContainerResolvedClass(IEnumerable<IHandler<T>> handlers)
{
this.Handlers = handlers;
}
}
I realise this post is a quite long, but I hope it clearly demonstrates a possible solution to your problem ...
This is a late response but maybe it will help others.
I have a pretty simple approach. I simply create a StrategyResolver to not be directly depending on Unity.
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
Usage:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Registration:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Now, the nice thing about this is that I will never have to touch the StrategyResolver ever again when adding new strategies in the future.
It's very simple. Very clean and I kept the dependency on Unity to a strict minimum. The only time I would have touch the StrategyResolver is if I decide to change container technology which is very unlikely to happen.
Hope this helps!
I generally use a combination of your Abstract Factory and Named Bindings options. After trying many different approaches, I find this approach to be a decent balance.
What I do is create a factory that essentially wraps the instance of the container. See the section in Mark's article called Container-based Factory. As he suggests, I make this factory part of the composition root.
To make my code a little cleaner and less "magic string" based, I use an enum to denote the different possible strategies, and use the .ToString() method to register and resolve.
From your Cons of these approaches:
Typically binds the caller to the IOC Container
In this approach, the container is referenced in the factory, which is part of the Composition Root, so this is no longer an issue (in my opinion).
. . . and certainly requires the caller to know something about the strategy (such as the
name "Alpha").
Every new strategy must be manually added to the list
of bindings. This approach is not suitable for handling multiple
strategies in an object graph. In short, it does not meet
requirements.
At some point, code needs to be written to acknowledge the mapping between the structure that provides the implementation (container, provider, factory, etc.) and the code that requires it. I don't think you can get around this unless you want to use something that is purely convention-based.
The constructors of each strategy might have different needs. But now the responsibility of constructor injection has been transferred to the abstract factory from the container. In other words, every time a new strategy is added it may be necessary to modify the corresponding abstract factory.
This approach solves this concern completely.
Heavy use of strategies means heavy amounts of creating abstract factories.[...]
Yes, you will need one abstract factory for each set of strategies.
If this is a multi-threaded application and the "ambient context" is indeed provided by thread-local-storage, then by the time an object is using an injected abstract-factory to create the type it needs, it may be operating on a different thread which no longer has access to the necessary thread-local-storage value.
This will no longer be an issue since TLC will not be used.
I don't feel that there is a perfect solution, but this approach has worked well for me.

What do you look for in a dependency to determine if it should be an injected dependency?

I am having difficult figuring out when a dependency should be injected. Let's just work with a simple example from my project:
class CompanyDetailProvider : ICompanyDetailProvider {
private readonly FilePathProvider provider;
public CompanyDetailProvider(FilePathProvider provider) {
this.provider = provider;
}
public IEnumerable<CompanyDetail> GetCompanyDetailsForDate(DateTime date) {
string path = this.provider.GetCompanyDetailFilePathForDate(date);
var factory = new DataReaderFactory();
Func<IDataReader> sourceProvider = () => factory.CreateReader(
DataFileType.FlatFile,
path
);
var hydrator = new Hydrator<CompanyDetail>(sourceProvider);
return hydrator;
}
}
(Not production quality!)
ICompanyDetailProvider is responsible for providing instances of CompanyDetails for consumers. The concrete implementation CompanyDetailProvider does it by hydrating instances of CompanyDetail from a file using a Hydrator<T> which uses reflection to populate instances of T sourced from an IDataReader. Clearly CompanyDetailProvider is dependent on DataReaderFactory (which returns instances of OleDbDataReader given a path to a file) and Hydrator. Should these dependencies be injected? Is it right to inject FilePathProvider? What qualities do I examine to decide if they should be injected?
I evaluate dependencies' points of use through the intent/mechanism lens: is this code clearly communicating its intent, or do I have to extract that from a pile of implementation details?
If the code indeed looks like a pile of implementation details, I determine the inputs and outputs and create an entirely new dependency to represent the why behind all the how. I then push the complexity into the new dependency, making the original code simpler and clearer.
When I read the code in this question, I clearly see the retrieval of a file path based on a date, followed by an opaque set of statements which don't clearly communicate the goal of reading an entity of a certain type at a certain path. I can work my way through it but that breaks my stride.
I suggest you raise the level of abstraction of the second half of the calculation, after you get the path. I would start by defining a dependency which implements the code's inputs/outputs:
public interface IEntityReader
{
IEnumerable<T> ReadEntities<T>(string path);
}
Then, rewrite the original class using this intention-revealing interface:
public sealed class CompanyDetailProvider : ICompanyDetailProvider
{
private readonly IFilePathProvider _filePathProvider;
private readonly IEntityReader _entityReader;
public CompanyDetailProvider(IFilePathProvider filePathProvider, IEntityReader entityReader)
{
_filePathProvider = filePathProvider;
_entityReader = entityReader;
}
public IEnumerable<CompanyDetail> GetCompanyDetailsForDate(DateTime date)
{
var path = _filePathProvider.GetCompanyDetailsFilePathForDate(date);
return _entityReader.ReadEntities<CompanyDetail>(path);
}
}
Now you can sandbox the gory details, which become quite cohesive in isolation:
public sealed class EntityReader : IEntityReader
{
private readonly IDataReaderFactory _dataReaderFactory;
public EntityReader(IDataReaderFactory dataReaderFactory)
{
_dataReaderFactory = dataReaderFactory;
}
public IEnumerable<T> ReadEntities<T>(string path)
{
Func<IDataReader> sourceProvider =
() => _dataReaderFactory.CreateReader(DataFileType.FlatFile, path);
return new Hydrator<T>(sourceProvider);
}
}
As shown in this example, I think you should abstract the data reader factory away and directly instantiate the hydrator. The distinction is that EntityReader uses the data reader factory, while it only creates the hydrator. It isn't actually dependent on the instance at all; instead, it serves as a hydrator factory.
I tend to be on the more liberal side of injecting dependencies so I would definitely want to inject both IDataReader to get rid of the new DataFactoryReader and the Hydrator. It keeps everything more loosely coupled which of course makes it easier to maintain.
Another benefit that is easy to attain right away is better testability. You can create mocks of your IDataReader and Hydrator to isolate your unit tests to just the GetCompanyDetailsForDate method and not have to worry about what happens inside the datareader and hydrator.
How to determine if a class should use dependency injection
Does this class require an external dependency?
If yes, inject.
If no, has no dependency.
To answer "Is it right to inject FilePathProvider?" yes it is right.
Edit: For clarification any external dependency is where you call to an unrelated but dependent class, especially when it involves a physical resources such as reading File Pathes from disk, but this also implies any kind of service or model class that does logic indepedent to the core functionality of the class.
Generally this be surmised with anytime you call the new operator. In most circumstances you want to refactor away all usages of the new operator when it has to deal with any class other than a data transfer object. When the class is internal to the usage location then a new statement can be fine if it reduces complexity such as the new DataReaderFactory() however this does appear to be a very good candidate for constructor injection also.

Categories

Resources