I know how I can inject one or a collection of dependency interface instances into a class via constructor injection. However, in my current situation I have a bit different task.
I have several classes, and each of them has an associated "Processor" class. These processors are implementing the same IProcessor interface, and a common Processor class will process a collection of objects, using the appropriate processors for each of them. Creating a processor for a type can be expensive, so I'm using factories and instantiate the processor only when it's needed.
The code would look something like this.
public interface IProcessor {
void Process(object item);
}
public class Processor {
private readonly Dictionary<Type, Func<IProcessor>> _processors;
public Processor(IDictionary<Type, Func<IProcessor>> processors) {
_processors = processors;
}
public void Process(IEnumerable items) {
foreach (var item in items) {
var processorFactory = _processors.GetValueOrDefault(item.GetType());
if (processorFactory == null) continue; // for simplicity
var processor = processorFactory();
processor.Process(item);
}
}
}
How could I register the binding for this in Ninject? Or is there any kind of alternative patterns which are more "DI friendly"?
I would like to configure these "processor bindings" at application entry point level.
An alternative would be to have a static dictionary of processor factories in the Processor class, and register the bindings manually at the entry point, but I would like to avoid using static dependencies. Or would it be still better in this particular case?
UPDATE
Another, kind of hybrid alternative which I arrived to is something like this. I would have a static Factories dictionary in the Processor class. There I could have basic, default implementations as a facade.
Then in my Ninject module I could write something like this.
public class MyModule : NinjectModule
{
public override void Load()
{
// ... my "standard" bindings
Processor.Factories[typeof(MyItem1)] = () => Kernel.Get<MyItem1Processor>();
Processor.Factories[typeof(MyItem2)] = () => Kernel.Get<MyItem2Processor>();
}
}
I know that I'm using the "evil" static stuff here, but still can utilize DI quite easily and in a well readable way, utilizing the Kernel property of the module.
Is it safe to use the Kernel property of the module inside the Load method? I mean can a module be loaded into more kernels for example?
Any thoughts are appreciated.
I'm answering my question with my final solution.
I believe, that in software development process if something "doesn't want to be put together", then it's an indication of some smell and most of the times I needed to get back a few levels to find it. It's something similar here too.
I realized that it's not a good design to use the factory pattern in this scenario because:
I think instantiating a processor object should never be so expensive, as each processor object should optimize their resources to use them only if Process is called.
Even if instantiation is expensive, with my original pattern, whenever a suitable object is in the processed list, a new instance is created. (This could be handled by the processor, but still doesn't look good at all.)
No way to add custom processors with respect to priority. Let's say ProcessorA processes ClassA, ClassB extends ClassA and ProcessorB processes ClassB. I have no way to prevent ProcessorA to process ClassB and allow other (non custom processed) ClassA descendandts to be still processed with ProcessorA at the same time. This is because of the Dictionary structure.
So I decided to simplify the implementation and pass an enumerable of IProcessors directly to the main processor, and have a CanProcess(object obj) in IProcessor. This way I can directly use any DI container to inject a list of all bound implementations.
If you want lazy initialization, how about a factory class rather than a Func?
Have a base factory class:
public abstract class ProcessorFactory
{
public abstract Type ItemType { get; }
public abstract IProcessor GetProcessor();
}
Create a concrete instance of the class for each item type and inject a collection of those into your constructor. Then build your dictionary from that:
public class Processor
{
private readonly Dictionary<Type, ProcessorFactory> _processors;
public Processor(IEnumerable<ProcessorFactory> processors)
{
_processors = processors.ToDictionary<ProcessorFactory, Type>(p => p.ItemType);
}
public void Process(IEnumerable items)
{
foreach (var item in items)
{
var processorFactory = _processors.GetValueOrDefault(item.GetType());
if (processorFactory == null) continue; // for simplicity
var processor = processorFactory.GetProcessor();
processor.Process(item);
}
}
}
Update 1
Here's sample code for the full factory implementation:
First I changed the factory to an interface:
public interface IProcessorFactory
{
Type ItemType { get; }
IProcessor GetProcessor();
}
Then I created an abstract generic base class for the factories:
public abstract class ProcessorFactoryBase<TItem> : IProcessorFactory
{
private Lazy<IProcessor> _factory;
public ProcessorFactoryBase(Func<IProcessor> factory)
{
_factory = new Lazy<IProcessor>(factory);
}
public Type ItemType
{
get { return typeof(TItem); }
}
public IProcessor GetProcessor()
{
return _factory.Value;
}
}
To create a factory, simply inherit from the base with the appropriate item type and implement the constructor:
public class ProcessorFactoryA : ProcessorFactoryBase<ItemA>
{
public ProcessorFactoryA(Func<IProcessor> factory) : base(factory) { }
}
Note that the factory class is tied to the item type; the processor type is injected via the bindings:
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryA(() => context.Kernel.Get<ProcessorX>()));
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryB(() => context.Kernel.Get<ProcessorY>()));
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryC(() => context.Kernel.Get<ProcessorZ>()));
// Note that item type D is handled by processor X
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryD(() => context.Kernel.Get<ProcessorX>()));
}
}
I made a .NET fiddle with the full working code: http://dotnetfiddle.net/aD9E2y.
It has an error when you try to run the fiddle, but you can just grab the code into a .NET console project and it runs.
Some people don't like them, but I've used T4 templates to do things like automatically generating the processor factory classes using reflection. The bindings will still have to be manually created, however, because the association between item type and processor can't be inferred.
Related
I've got a very big list of ISample registrations in my MS.DI container, which I inject as an IEnumerable<ISample>. But at runtime I typically need a very few. MS.DI, however, always creates all items of the collection immediately, which causes a performance problem in my application.
Is there a way to allow items of an injected IEnumerable<T> to be loaded lazily, making it function as a stream, rather than a pre-populated array?
Here's my sample code that demonstrates the problem:
services.AddTransient<ISample, SampleA>();
services.AddTransient<ISample, SampleB>();
services.AddTransient<ISample, SampleC>();
public class SampleA : ISample
{
public Guid Id = FirstGuid;
public SampleA()
{
Console.WriteLine("SampleA created.");
}
}
public class SampleB : ISample
{
public Guid Id = SecondGuid;
public SampleB()
{
Console.WriteLine("SampleB created.");
}
}
public class SampleC : ISample
{
public Guid Id = ThirdGuid;
public SampleC()
{
Console.WriteLine("SampleC created.");
}
}
In other class I use service provider for creating an instance of any of these classes.
public ISample GetInstance(Guid Id)
{
return _serviceProvider.GetServices<ISample>().FirstOrDefault(d => d.Id==Id);
}
What's the best way to prevent all items to be pre-populated?
For solve this issue I would suggest using Dictionary<Guid, Type> and add all your implementations to it by their Ids, this what I've tried and works fine:
public interface ISample
{
public Guid Id { get; }
}
public class SampleA : ISample
{
public Guid Id => Guid.Parse("3f30ae05-b88e-4abf-85b5-22e7ce4b639f");
public SampleA()
{
Console.WriteLine("SampleA created.");
}
}
public class SampleB : ISample
{
public Guid Id => Guid.Parse("c4a5b853-433b-4889-af41-cb99a8c71c4a");
public SampleB()
{
Console.WriteLine("SampleB created.");
}
}
public class SampleC : ISample
{
public Guid Id => Guid.NewGuid();
public SampleC()
{
Console.WriteLine("SampleC created.");
}
}
and in your startup register them like this:
services.AddTransient<SampleA>();
services.AddTransient<SampleB>();
services.AddTransient<SampleC>();
var dic = new Dictionary<Guid, Type>()
{
{Guid.Parse("3f30ae05-b88e-4abf-85b5-22e7ce4b639f"), typeof(SampleA)},
{Guid.Parse("c4a5b853-433b-4889-af41-cb99a8c71c4a"), typeof(SampleB)},
{Guid.Parse("c4a5b853-433b-4889-af41-cb99a8c71c4a"), typeof(SampleC)},
};
//you will inject this
services.AddScoped<Func<Guid, ISample>>
(provider => (id) => provider.GetService(dic[id]) as ISample);
and I you class inject it in this way:
public class UseDI
{
private readonly Func<Guid, ISample> _funcSample;
public UseDI(Func<Guid, ISample> funcSample)
{
_funcSample= funcSample;
}
public ISample GetInstance(Guid Id)
{
return _funcSample(Id);
}
}
I have tested this var sampleB=GetInstance(Guid.Parse("c4a5b853-433b-4889-af41-cb99a8c71c4a")) and only SampleB constructor run.
The default behavior of MS.DI is to resolve the complete collection. This is done both when you call GetServices or when you inject an IEnumerable<T>. Under the covers the enumerable is an array of eagerly loaded instances.
Although you could refactor your code to use factories of some sort, you can also register an enumerable that truly acts as a stream. This, however, is not something that is supported out of the box with MS.DI. But this can be achieved using the following code:
public static void AddStream<TService>(
this IServiceCollection services, params Type[] implementations)
{
foreach (var implementation in implementations)
{
// TODO: Check if implementation implements TService
services.AddTransient(implementation, implementation);
}
services.AddTransient(c =>
implementations.Select(c.GetRequiredService).OfType<TService>());
}
When called, this extension method registers all supplied implementations as transient inside the container and registers an IEnumerable<T> that starts resolving instances when its iterated.
The AddStream extension method can be called as follows:
services.AddStream<ISample>(typeof(SampleA), typeof(SampleB), typeof(SampleC));
Depending on your needs, it will get more complicated though, because the above example does not support:
Registering generic types (and it would be quite cumbersome to add a fully functional implementation that allows registering types for generic abstractions that support streaming)
O(n) access when using .Last() or .ElementAt(x). This would require implementing returning a special ICollection<T> that allow LINQ extension methods to work on. This would also be much more cumbersome to write. Switching to a different DI Container that supports streaming OOTB would in that case be a better option.
No note though that even with this lazy approach, you will still be initializing half of the list on average (meaning a performance of O(n/2). If you want O(1) performance, consider using either a dictionary instead.
It depends on the nature of was is really done in // do some thing.
If this work is always the same regardless of the instance created, it could be initialized once with a static constructor.
Otherwise, your intuition to add an Initialize method in ISample will guide you in the right direction. My only concern is that calling this method inside GetInstance will not change anything performance wise because you just deferred the same work from the constructor to an initialization method and will introduce a temporal coupling between the constructor and this method. That is, forgetting to call this method after the construction and the returned instance will be in a corrupted state (this is even worse than before).
If you want to fully go down the road, you need to ask yourself how to defer this complex code from the object's construction (this is considered as an anti-pattern) to a subsequent method call. But again, without seeing what is really done in the constructor and where and how the initialized part is used, I can't really say anything as how to do it.
I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.
These days I'm facing this situation often and I'm looking for an elegant solution. I have :
public abstract class TypeA
{
public abstract void AbtractMethod(IDependency dependency);
}
public class TypeB : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForB dependency) { }
}
public class TypeC : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForC dependency) { }
}
public interface IDependency { }
public interface ISpecializedDependencyForB : IDependency { }
public interface ISpecializedDependencyForC : IDependency { }
My objective is to make things transparent in the client perspective and to consume this code like that :
TypeA myDomainObject = database.TypeARepository.GetById(id); // The important point here is that I don't know if the object is of TypeB or TypeC when I consume it.
IDependency dependency = ? // How do I get the right dependency
myDomainObject.AbtractMethod(dependency);
So the thing is that since I don't know the concrete type of the object, I can't inject the right dependency into it.
What I'm currently doing is that I create an abstract factory, to inject the right properties. I have two problems with that, the first one is that I would end up with a lot of factories. The second one is that it makes polymorphism useless since the client actually needs to care about "managing" the underlying type (I need to inject all the possible dependencies in the factory, and to instantiate the factory on the client code).
1) Therefore I was thinking of using property injection with unity, but I can't find out if it's possible to resolve the dependencies of an object, after it's been instanciated manually. Even with this approach I think I could still meet the same problem : I'm not sure if unity would check the actual type of the object and resolve the right dependency if a syntax like this existed :
unityContainer.Resolve<TypeA>(myDomainObject)
If not, I would need to know the type in advance and would be back to the same problem.
2) I have found this article mentionning that EF provides some mechanism for DI, but it seems that it is only meant to inject the framework services (PluralizationService, etc...). Otherwise it would have been a nice way to achieve that.
3) I could also not use DI in this case... It looks like by concept DI does not fit well with polymorphism. I'm not excited by this idea though.
I'd be happy to have a solution for the property injection I'm trying to achieve, or an idea of pattern I could use. However I really don't want to create a big infrastructure and obfuscate my code just for this purpose.
Note : I don't want to you use domain events in this case.
Thank you
TL;DR
Replace the IDependency parameter of the polymorphic AbstractMethod with an implementation-specific construction dependency parameter, which is injected by the IoC container, not by the consumer.
In more detail
The original class hierarchy will need to look like more like this for inheritance polymorphicism to work, as the superclass virtual method and subclass override methods must match signatures:
public abstract class TypeA // superclass
{
public abstract void AbtractMethod(IDependency dependency);
}
public class TypeB : TypeA // subclass 1
{
public override void AbtractMethod(IDependency dependency)
{
Contract.Requires(dependency is ISpecializedDependencyForB);
// ...
}
}
public class TypeC : TypeA // subclass 2
{
public override void AbtractMethod(IDependency dependency)
{
Contract.Requires(dependency is ISpecializedDependencyForC)
// ...
}
}
However, some things don't ring true with this design:
The LSP appears to be violated, since the although AbtractMethod() advertises that it accepts the base IDependency interface, the two subclasses actually depend on a specialized subclassed dependency.
It is also unusual, and arguably inconvenient, for a caller of these methods to build up the correct dependency and pass it to the method in order for it to be invoked correctly.
So, if possible, I would adopt a more conventional approach to the arrangement of dependencies, whereby the dependency is passed to the subclass constructor, and will be available to the polymorphic method when needed. This decouples the need to supply the appropriate IDependency to the method. Leave it to the IoC container to do the appropriate dependency resolution:
Use constructor injection to create the correct dependency into Classes TypeB and TypeC
If there is a secondary requirement to Expose an IDependency on the base class TypeA to consumers, then add an additional abstract property to TypeA of type IDependency (but this seems iffy)
As per Ewan's observation, the repository would need some kind of strategy pattern in order to serve up polymorphic domain entities (B or C). In which case, couple the repository to a factory to do exactly this. The concrete factory would need to be bound to the container in order to tap into Resolve().
So putting this all together, you might wind up with something like this:
using System;
using System.Diagnostics;
using Microsoft.Practices.Unity;
namespace SO29233419
{
public interface IDependency { }
public interface ISpecializedDependencyForB : IDependency { }
public interface ISpecializedDependencyForC : IDependency { }
public class ConcreteDependencyForB : ISpecializedDependencyForB {};
public class ConcreteDependencyForC : ISpecializedDependencyForC { };
public abstract class TypeA
{
// Your polymorphic method
public abstract void AbtractMethod();
// Only exposing this for the purpose of demonstration
public abstract IDependency Dependency { get; }
}
public class TypeB : TypeA
{
private readonly ISpecializedDependencyForB _dependency;
public TypeB(ISpecializedDependencyForB dependency)
{
_dependency = dependency;
}
public override void AbtractMethod()
{
// Do stuff with ISpecializedDependencyForB without leaking the dependency to the caller
}
// You hopefully won't need this prop
public override IDependency Dependency
{
get { return _dependency; }
}
}
public class TypeC : TypeA
{
private readonly ISpecializedDependencyForC _dependency;
public TypeC(ISpecializedDependencyForC dependency)
{
_dependency = dependency;
}
public override void AbtractMethod()
{
// Do stuff with ISpecializedDependencyForC without leaking the dependency to the caller
}
public override IDependency Dependency
{
get { return _dependency; }
}
}
public interface ITypeAFactory
{
TypeA CreateInstance(Type typeOfA);
}
public class ConcreteTypeAFactory : ITypeAFactory
{
private readonly IUnityContainer _container;
public ConcreteTypeAFactory(IUnityContainer container)
{
_container = container;
}
public TypeA CreateInstance(Type typeOfA)
{
return _container.Resolve(typeOfA) as TypeA;
}
}
public class TypeARepository
{
private readonly ITypeAFactory _factory;
public TypeARepository(ITypeAFactory factory)
{
_factory = factory;
}
public TypeA GetById(int id)
{
// As per Ewan, some kind of Strategy Pattern.
// e.g. fetching a record from a database and use a discriminating column etc.
return (id%2 == 0)
? _factory.CreateInstance(typeof (TypeB))
: _factory.CreateInstance(typeof (TypeC));
// Set the properties of the TypeA from the database after creation?
}
}
class Program
{
static void Main(string[] args)
{
// Unity Bootstrapping
var myContainer = new UnityContainer();
myContainer.RegisterType<ISpecializedDependencyForB, ConcreteDependencyForB>();
myContainer.RegisterType<ISpecializedDependencyForC, ConcreteDependencyForC>();
myContainer.RegisterType(typeof(TypeB));
myContainer.RegisterType(typeof(TypeC));
var factory = new ConcreteTypeAFactory(myContainer);
myContainer.RegisterInstance(factory);
myContainer.RegisterType<TypeARepository>(new InjectionFactory(c => new TypeARepository(factory)));
// And finally, your client code.
// Obviously your actual client would use Dependency Injection, not Service Location
var repository = myContainer.Resolve<TypeARepository>();
var evenNumberIsB = repository.GetById(100);
Debug.Assert(evenNumberIsB is TypeB);
Debug.Assert(evenNumberIsB.Dependency is ISpecializedDependencyForB);
var oddNumberIsC = repository.GetById(101);
Debug.Assert(oddNumberIsC is TypeC);
Debug.Assert(oddNumberIsC.Dependency is ISpecializedDependencyForC);
}
}
}
Could whatever it is that knows about the dependencies live behind an interface IDependencyProvider which has a function
IDependency GetDependency(Type type).
This could even just return an object and the class that realises the interface needs to know all the sub types and their associated dependencies.
AbstractMethod is then changed to:
void AbstractMethod(IDependencyProvider provider);
In your sub classes you then override this and call
var dependency = provider.GetDependency(this.GetType());
Your middle tier then knows nothing about the sub types or the sub dependencies.
It's an interesting problem, what I was thinking is that your repository knows about and creates the TypeB and TypeC classes and so you can add the correct dependency at that point
public class TypeARepository
{
private ISpecializedDependencyForB depB;
private ISpecializedDependencyForC depC;
public TypeARepository(ISpecializedDependencyForB depB, ISpecializedDependencyForC depC)
{
this.depB = depB;
this.depC = depC;
}
public TypeA GetById(string id)
{
if (id == "B")
{
return new TypeB(depB);
}
else
{
return new TypeC(depC);
}
}
}
The TypeB and TypeC would then implement their abstract methods with their private ref to the dependency rather than having it passed in in the method.
I come across this problem in various forms myself from time to time and it always seems to me that if there is that hard link between the types just having it setup via an injection config or the like is wrong. As it allows the installer to potentially set a bad config
This approach also allows you to inject your dependencies with unity
Thank you a lot for your interest in my question, I came up with a solution yesterday evening. The objective is to keep things transparent for the client and to take full advantage of polymorphism by syntaxes such as baseObjectReference.AbstractMethodCall().
I finally realized that I was able to achieve what I'm after by taking advantage of the static modifier and using it for DI purposes. So I have that :
public abstract class TypeA
{
public abstract void AbtractMethod();
}
public class TypeB : TypeA
{
private ISpecializedDependencyForB SpecializedDependencyForB
{
get
{
return GetSpecializedDependencyForB.CreateSpecializedDependencyForB();
}
}
public override void AbtractMethod() { // do stuff with dependency }
}
public static class GetSpecializedDependencyForB
{
public static ISpecializedDependencyForB DependencyForB
{
return CreateSpecializedDependencyForB();
}
public delegate ISpecializedDependencyForB CreateSpecializedDependencyForBDelegate();
public static CreateSpecializedDependencyForBDelegate CreateSpecializedDependencyForB;
}
And then, in my unity container I add this code :
public static void RegisterTypes(IUnityContainer container)
{
// .... registrations are here as usual
GetSpecializedDependencyForB.CreateSpecializedDependencyForB = CreateMyDomainService;
}
Having this method in the same unity config class :
private ISpecializedDependencyForB CreateMyDomainService()
{
return container.Value.Resolve<ISpecializedDependencyForB>();
}
And finally, I can simply use my object like this :
TypeA myDomainObject = database.TypeARepository.GetById(id);
myDomainObject.AbtractMethod();
And that's it !
So four things here :
The first one is that I inject the delegate that will create and instance of the service.
Then it is thread safe because static member is only written one time at the beginning of the application. All other accesses will be read. Moreover two threads won't share the same instance of the dependency since the delegate creates a new one all the time.
Also one interesting thing is that I can rely on my existing unity container configuration, no extra code is needed. It is important because my dependency may need other dependency to be constructed.
And finally the unity container is anyway also static, so there is no memory leak.
It's basically a manual and easy to set up "DI framework" sitting beside Unity.
And more importantly it works like a charm ! I'm finally satisfied with my design. I will only use this approach for polymorphic situations since injecting the right dependency in the method is easy for other situations. However it might be interesting to fully encapsulate the domain model using this approach.
I have a question about creating a factory interface with a create method that can cater for accepting different argument types depending on the implementation.
To give you a bit more background, I am using dependency in injection in a project, and require stateful objects to be generated at runtime - therefore I am injecting factories (rather than the objects themselves) to create these stateful objects. The problem I have come across is that, for some interfaces, the concrete implementations simply cannot have the same constructor argument types, and so the factories that create an instance of these interfaces require almost 'dynamic' arguments to be passed to the create method.
I have been going over this for a couple of days, and the following is the best solution I could come up with (namely, passing an object to the factory create method and casting it in the concrete implementation of the factory). I am really looking for feedback from people who have come across this scenario before, to hear what they came up with, and whether or not the solution I am proposing below is acceptable.
Apologies if this is missing any information, and many thanks in advance!
//
// Types...
//
interface IDataStore
{
List<string> GetItems();
}
public class XmlDataStore : IDataStore
{
public XmlDataStore(XmlDocument xmlDoc)
{
// Initialise from XML Document...
}
public List<string> GetItems()
{
// Get Items from XML Doc...
}
}
public class SQLDataStore : IDataStore
{
public SQLDataStore(SqlConnection conn)
{
// Initialise from SqlConnection...
}
public List<string> GetItems()
{
// Get Items from Database Doc...
}
}
//
// Factories...
//
interface IDataStoreFactory
{
IDataStore Create(object obj);
}
class XmlDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to XmlDocument
return new XmlDataStore((XmlDocument)obj);
}
}
class SQLDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to SqlConnection
return new SQLDataStore((SqlConnection)obj);
}
}
Based on this comment you need one factory which produces several types of IDataStore. You could accomplish by creating a open generic factory method in the singleton factory instance.
interface IDataStore<TStoreType>
{
void SetBaseType(TStoreType obj);
List<string> GetItems();
}
interface IDataStoreFactory
{
IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
}
class DataStoreFactory : IDataStoreFactory
{
public IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
{
if (obj.GetType() == typeof(SqlConnection))
{
var store = new SQLDataStore((SqlConnection)(Object)obj);
return (IDataStore<TStoreType>)store;
}
if (obj.GetType() == typeof(XmlDocument))
{ //... and so on }
}
}
class SQLDataStore : IDataStore<SqlConnection>
{
private readonly SqlConnection connection;
public SQLDataStore(SqlConnection connection)
{
this.connection = connection;
}
public List<string> GetItems() { return new List<string>(); }
}
You can use this factory like this:
var factory = new DataStoreFactory();
var sqlDatastore = factory.Create(new SqlConnection());
var xmlDatastore = factory.Create(new XmlDocument());
Your datastore factory would become a lot less complex if you would use a DI container. You could inject the container in the factory and retrieve your instances directly from the container, which would typically build your instances from bottom to top, including there own dependencies, lifetime management and so on. But be very carefull with this approach, it is the first step to using the service locator pattern which is an anti pattern
Not really sure if I understand your question correctly but to me it sounds a little odd to have factory instances which you use for the creation of your statefull objects as you call them.
To directly answer your question: generics are your solution. You rinterface becomes an open generic abstraction:
interface IDataStore<TStoreType>
{
List<string> GetItems();
}
interface IDataStoreFactory<TStoreType>
{
IDataStore<TStoreType> Create(TStoreType obj);
}
and your factory classes will look like this:
class XmlDataStoreFactory : IDataStoreFactory<XmlDocument>
{
IDataStore<XmlDocument> Create(XmlDocument document)
{
return new XmlDataStore(document);
}
}
class SQLDataStoreFactory : IDataStoreFactory<SqlConnection>
{
IDataStore<SqlConnection> Create(SqlConnection connection)
{
return new SQLDataStore(connection);
}
}
This will work, but from the examples you give I got the impression you're using factories throughout your codebase. Maybe I'm wrong on this point, but look at your design and minimize the number of factories. Needing a factory means mixing data with behaviour and this will always, eventually, get you into trouble.
For example, let's say you have some kind of service which adds the current user to a audit log when he logs in. This service offcourse needs the current user which is a typical example of runtime data (or contextual data). But instead of:
public class AuditLogService
{
public void AddApplicationSignIn(User user)
{
//... add user to some log
}
}
I know this is not a good example because you actually wouldn't need a factory for this class, but with the next code example you'll get the point:
public class AuditLogService
{
private readonly IUserContext userContext;
public AuditLogService(IUserContext userContext)
{
this.userContext = userContext;
}
public void AddApplicationSignIn()
{
var user = this.userContext.GetCurrentUser();
//... add user to some log
}
}
So by splitting data from behaviour you rule out the need for factories. And admitted there are cases where a factory is the best solution. I do think an IDataStore is not something you need a factory for.
For a good blog on splitting data and behaviour read here
I'm brand new to using Simple Injector although I have been using Ninject for a long time, so I am comfortable with DI in general. One thing that attracted me to want to use Simple Injector was the ease of use of Decorators.
I have been able to successfully use decorators with Simple Injector in all normal cases where the dependencies are resolved when the service is requested. However, I am having a hard time figuring out if there is a way to get my decorators applied in a case when the service must be constructed using a runtime value.
In Ninject, I could pass a ConstructorArgument to the kernel.Get<IService> request that could be inherited down the chain of N decorators all the way to the "real" implementing class. I cannot figure out a way to replicate that using Simple Injector.
I have put some very basic code below to illustrate. What I would want to do in the real world would be to pass an IMyClassFactory instance into other classes in my application. Those other classes could then use it to create IMyClass instances using the IRuntimeValue they would provide. The IMyClass instance they got from the IMyClassFactory would be decorated automatically by the registered decorators.
I know I could manually apply my decorator(s) in my IMyClassFactory or any Func<IMyClass> I could come up with, but I would like it to "just work".
I keep going around and around trying to abstract out the MyClass construction, but I can't figure out how to get it to resolve with the IRuntimeValue constructor argument and be decorated.
Am I overlooking an obvious solution?
using System;
using SimpleInjector;
using SimpleInjector.Extensions;
public class MyApp
{
[STAThread]
public static void Main()
{
var container = new Container();
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof (IMyClass), typeof (MyClassDecorator));
container.Register<Func<IRuntimeValue, IMyClass>>(
() => r => container.GetInstance<IMyClassFactory>().Create(r));
container.Register<IMyClass>(() => ?????)); // Don't know what to do
container.GetInstance<IMyClass>(); // Expect to get decorated class
}
}
public interface IRuntimeValue
{
}
public interface IMyClass
{
IRuntimeValue RuntimeValue { get; }
}
public interface IMyClassFactory
{
IMyClass Create(IRuntimeValue runtimeValue);
}
public class MyClassFactory : IMyClassFactory
{
public IMyClass Create(IRuntimeValue runtimeValue)
{
return new MyClass(runtimeValue);
}
}
public class MyClass : IMyClass
{
private readonly IRuntimeValue _runtimeValue;
public MyClass(IRuntimeValue runtimeValue)
{
_runtimeValue = runtimeValue;
}
public IRuntimeValue RuntimeValue
{
get
{
return _runtimeValue;
}
}
}
public class MyClassDecorator : IMyClass
{
private readonly IMyClass _inner;
public MyClassDecorator(IMyClass inner)
{
_inner = inner;
}
public IRuntimeValue RuntimeValue
{
get
{
return _inner.RuntimeValue;
}
}
}
Edit 1:
Ok, thanks to Steven for the great answer. It has given me a couple of ideas.
Maybe to make it a little more concrete though (although not my situation, more "classic"). Say I have an ICustomer that I create at runtime by reading a DB or deserializing from disk or something. So I guess that would be considered a "newable" to quote one of the articles Steven linked. I would like to create an instance of ICustomerViewModel so I can display and manipulate my ICustomer. My concrete CustomerViewModel class takes in an ICustomer in its constructor along with another dependency that can be resolved by the container.
So I have an ICustomerViewModelFactory that has a .Create(ICustomer customer) method defined which returns ICustomerViewModel. I could always get this working before I asked this question because in my implementation of ICustomerViewModelFactory I could do this (factory implemented in composition root):
return new CustomerViewModel(customer, container.GetInstance<IDependency>());
My issue was that I wanted my ICustomerViewModel to be decorated by the container and newing it up bypassed that. Now I know how to get around this limitation.
So I guess my follow-up question is: Is my design wrong in the first place? I really feel like the ICustomer should be passed into the constructor of CustomerViewModel because that demonstrates intent that it is required, gets validated, etc. I don't want to add it after the fact.
Simple Injector explicitly lacks support for passing on runtime values through the GetInstance method. Reason for this is that runtime values should not be used when the object graph is constructed. In other words, the constructors of your injectables should not depend on runtime values. There are several problems with doing that. First of all, your injectables might need to live much longer than those runtime values do. But perhaps more importantly, you want to be able to verify and diagnose your container's configuration and that becomes much more troublesome when you start using runtime values in the object graphs.
So in general there are two solutions for this. Either you pass on the runtime value through the method call graph or you create a 'contextual' service that can supply this runtime value when requested.
Passing on the runtime value through the call graph is especially a valid solution when you practice architectures like this and this where you pass on messages through your system or when the runtime value can be an obvious part of the service's contract. In that case it is easy to pass on the runtime value with the message or the method and this runtime value will also pass through any decorator on the way through.
In your case this would mean that the factory creates the IMyService without passing in the IRuntimeValue and your code passes this value on to the IMyService using the method(s) it specifies:
var service = _myServiceFactory.Create();
service.DoYourThing(runtimeValue);
Passing through the runtime value through the call graph however is not always a good solution. Especially when this runtime value should not be part of the contract of the message that is sent. This especially holds for contextual information use as information about the current logged in user, the current system time, etc. You don't want to pass this information through; you just want it to be available. We don't want this, because this would give an extra burden to the consumers of passing the right value every time, while they probably shouldn't even be able to change this information (take the user in who's context the request is executed for instance).
In that case you should define service that can be injected and allows retrieving this context. For instance:
public interface IUserContext {
User CurrentUser { get; }
}
public interface ITimeProvider {
DateTime Now { get; }
}
In these cases the current user and the current time aren't injected directly into a constructor, but instead these services are. The component that needs to access the current user can simply call _userContext.CurrentUser and this will be done after the object is constructed (read: not inside the constructor). Thus: in a lazy fashion.
This does mean however that the IRuntimeValue must be set somewhere before MyClass gets invoked. This probably means you need to set it inside the factory. Here's an example:
var container = new Container();
var context = new RuntimeValueContext();
container.RegisterSingle<RuntimeValueContext>(context);
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof(IMyClass), typeof(MyClassDecorator));
container.Register<IMyClass, MyClass>();
public class RuntimeValueContext {
private ThreadLocal<IRuntimeValue> _runtime;
public IRuntimeValue RuntimeValue {
get { return _runtime.Value; }
set { _runtime.Value = value; }
}
}
public class MyClassFactory : IMyClassFactory {
private readonly Container _container;
private readonly RuntimeValueContext context;
public MyClassFactory(Container container, RuntimeValueContext context) {
_container = container;
_context = context;
}
public IMyClass Create(IRuntimeValue runtimeValue) {
var instance = _container.GetInstance<IMyClass>();
_context.RuntimeValue = runtimeValue;
return instance;
}
}
public class MyClass : IMyClass {
private readonly RuntimeValueContext _context;
public MyClass(RuntimeValueContext context) {
_context = context;
}
public IRuntimeValue RuntimeValue { get { return _context.Value; } }
}
You can also let the MyClass accept the IRuntimeValue and make the following registration:
container.Register<IRuntimeValue>(() => context.Value);
But the disallows verifying the object graph, since Simple Injector will ensure that registrations never return null, but context.Value will be null by default. So another option is to do the following:
container.Register<IMyClass>(() => new MyClass(context.Value));
This allows the IMyClass registration to be verified, but will during verification still create a new MyClass instance that is injected with a null value. If you have a guard clause in the MyClass constructor, this will fail. This registration however disallows MyClass to be auto-wired by the container. Auto-wiring that class can come in handy when you've got more dependencies to inject into MyClass for instance.