Typical IoC container usage - passing data down the line - c#

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.

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!

Dependency Injection With Unity Using Constructors With Runtime Parameters

I have the basics down of dependency injection but where I'm struggling is trying to put it together properly in an MVC API C# application using Unity. The issue I have is that I will have a controller that has a method, and in that method it will have say two objects. One of these objects will have a dependency on a data access layer and the other doesn't. I'm not quite sure on exactly how to set this up.
Lets say I have a controller with the following method that gets users from a search object. It also uses a SearchParameters object to perform the search. If you search with no name you get all results, or if you put a name you get any users with that name.
public Users[] GetUsers(string name) {
Company.SearchParameters searchParams = new Company.SearchParameters(name);
Company.UserSearchService searchService = new Company.UserSearchService(searchParams);
return searchService.Search();
}
This is of course a super simplified version but in this case UserSearchService in the Search method is doing an explicit database call. So I know that is a dependency I'd have to give it. SearchParameters really is just a class that holds data.
Here is where I'm not sure on exactly what to do next. The Controller itself doesn't have a dependency but since UserSearchService does I'm not sure how using unity I properly set that up and take into account runtime values for the constructor. I'm also not sure if SearchParameters is supposed to be considered a dependency or not.
Additionally SearchParameters and UserSearchService do not have any sort of backing interface if that matters and there are other methods on this controller that interact with other classes that have a similar need of a data access layer dependency such as perhaps Company.UserAccount.
The search parameters shouldn't be part of constructor; it should be part of the "Search" method. The SearchParameter object should not even be known outside of the UserSearchService class (Encapsulation). There should be some refactoring as neleus suggested. At the very least, to get things going, it should be refactored to something similar this:
public Users[] GetUsers(string name) {
// Or however you end up with your UserSearchService object.
// Ideally as an interface and an injected dependency...
Company.UserSearchService searchService = new Company.UserSearchService();
return searchService.Search(name);
}
Company.UserSearchService:
public Users[] Search(string name) {
// A factory would be a better option. This should also be an interface.
Company.SearchParameters searchParams = new Company.SearchParameters(name);
// Your logic here
}
I see here two tasks. The first is a refactoring where static dependencies have to be replaced with interfaces. The second task is to register your stuff in IoC container.
For the first task a minimum you need is to replace all references to Database in your UserSearchService with IDatabase interface (so that it can also be mocked) and allow it to be passed to constructor (constructor injection). To be able to provide an instance of IDatabase to the service you have to create the same dependency for the controller (again constructor injection). Then register the IDatabase implementation as shown in this post.
Update
I agree that dependency has to be removed from the controller. As you #Topojijo have suggested a factory for the UserSearchService can be used in this case. Guessing you have several cervices you need to make a factory for each and there may be an overhead if their count is large. In such case it's better to resolve the service directly from Unity container and move the searchParams to Search method:
public Users[] GetUsers(string name) {
Company.SearchParameters searchParams = new Company.SearchParameters(name);
Company.UserSearchService searchService = container.Resolve<Company.UserSearchService>();
return searchService.Search(searchParams);
}

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.

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.

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