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

I am using Microsoft's Unity for dependency injection and I want to do something like this:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA and RepositoryB both have a constructor that takes an IDataContext parameter, and I want Unity to initialize the repository with the context that I pass it. Also note that IDataContext is not registered with Unity (I don't want 3 instances of IDataContext).

As of today they have added this functionality:
It’s in the latest drop here:
http://unity.codeplex.com/SourceControl/changeset/view/33899
Discussion on it here:
http://unity.codeplex.com/Thread/View.aspx?ThreadId=66434
Example:
container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"

< 2 cents>
What if you later on decide to use a different service that requires more or less than just the context?
The problem with constructor parameters and IoC is that the parameters are ultimately tied to the concrete type being used, as opposed to being part of the contract that the service interface defines.
My suggestion would be that you either resolve the context as well, and I believe Unity should have a way for you to avoid constructing 3 instances of it, or you should consider a factory service that has a way for you to construct the object.
For instance, what if you later on decide to construct a repository that doesn't rely on a traditional database at all, but instead use an XML file to produce dummy-data for the test? How would you go about feeding the XML content to that constructor?
IoC is based around decoupling code, by tying in the type and semantics of the arguments to the concrete types, you really haven't done the decoupling correctly, there's still a dependency.
"This code can talk to any type of repository possibly, as long as it implements this interface.... Oh, and uses a data context".
Now, I know that other IoC containers have support for this, and I had it in my first version of my own as well, but in my opinion, it doesn't belong with the resolution step.
< /2 cents>

Thanks guys ... mine is similar to the post by "Exist". See below:
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
_activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
{
new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
});

You can use InjectionConstructor / InjectionProperty / InjectionMethod depending on your Injection Architecture within the ResolvedParameter< T >("name") to get a instance of a pre-registered Object in the container.
In your case this Object must be registered with a Name, and for the same insance you need ContainerControlledLifeTimeManager() as the LifeTimeManager.
_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");
var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));

The very short answer is: no. Unity currently has no way to pass parameters into the constructor that aren't constant or injected, that I have been able to find. IMHO that's the single biggest thing it's missing, but I think it is by design rather than by omission.
As Jeff Fritz notes, you could in theory create a custom lifetime manager that knows which context instance to inject into various types, but that's a level of hard-coding which seems to obviate the purpose of using Unity or DI in the first place.
You could take a small step back from full DI and make your repository implementations responsible for establishing their own data contexts. The context instance can still be resolved from the container but the logic for deciding which one to use would have to go into the implementation of the repository. It's not as pure, certainly, but it would get rid of the problem.

Another alternative you could use (don't really know if it is a good practice or not) is creating two containers and registering an instance for each:
IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context
//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance
hope this helps too

NotDan, I think you may have answered your own question in comments to lassevk.
First, I would use a LifetimeManager to manage the lifecycle and number of instances of IDataContext that Unity creates.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
It sounds like the ContainerControlledLifetimeManager object will give you the instance management that you need. With that LifetimeManager in place, Unity should add the same instance of the IDataContext to all objects that require an IDataContext dependency.

Related

C# Dependency Injection In Constructor with a parameter at runtime

Perhaps I am missing something or tried something improperly, but I thought I would reach out.
I have a singleton service that I want to create multiple times. The service has the same logic except for a configuration parameter. So I want to inject a parameter at runtime into the service constructor.
Is this possible, or will I have to do something more elaborate?
Thanks for your input.
For example…
// I am creating three different configurations
services.Configure<ProfileCacheOptions>(
ProfileCacheOptions.Key1,
config.GetSection(ProfileCacheOptions.Key1));
services.Configure<ProfileCacheOptions>(
ProfileCacheOptions.Key2,
config.GetSection(ProfileCacheOptions.Key2));
services.Configure<ProfileCacheOptions>(
ProfileCacheOptions.Key2,
config.GetSection(ProfileCacheOptions.Key3));
.
.
.
// I have tried multiple ways to inject a parameter, but as you can see
// my last attempt was a simple string representing the key
services.AddSingleton<ICachedDataSource<Class1>,
MemoryCacheData<Class1>>(ProfileCacheOptions.Key1);
services.AddSingleton<ICachedDataSource<Class2>,
MemoryCacheData<Class2>>(ProfileCacheOptions.Key2);
services.AddSingleton<ICachedDataSource<Class3>,
MemoryCacheData<Class3>>(ProfileCacheOptions.Key3);
// The proposed argument, whatever it may be
public MemoryCacheData(
IMemoryCache cache,
IOptionsSnapshot<CachedDataBaseClassOptions> options,
string TheArgument
{
_options = options.Get(TheArgument);
}
I have tried creating an argument class and multiple attempts to create a runtime injected parameter.
You can create an instance of the singleton before you add it to the DI container, like so:
var singleton1 = new MemoryCacheData<Class1>(ProfileCacheOptions.Key1);
services.AddSingleton(typeof(ICachedDataSource<Class1>), singleton1);
You have to provide a factory (or in this case a simple Func<>) that creates the desired instance at runtime. Something like this:
services.AddSingleton<ICachedDataSource<Class1>>(provider =>
{
// The provider is the running DI container and you can ask
// for any service as usual to retrieve dependencies
var cacheOptions = provider.GetRequiredService<ICachedDataSource<Class1>>();
var data = new MemoryCacheData<Class1>(cacheOptions);
return data;
});
I think it doesn't fully match your code, but hopefully you understand the approach and can use it.

Unity IoC InjectionFactory not respecting DependencyOverride

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

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!

About SOLID principles, DI using containers and Unity: How to manage the DI mapping in the container?

Allright. I finally understood all those complicated concepts of DI even IoC, containers, and so on and on. But there is something I'm missing still.
Say that I have a class called SomeClass that will instaciate in his constructor one of the classes that implememnts IFirstLevelOfAbstraction. The classes that implements IFirstLevelOfAbstraction are SubClass1 and SubClass2. Those classes I mentioned instanciate a class implementing ISecondLevelOfAbstraction, which are SubClass3 and SubClass4.
TL;DR here is the image.
Using unity in my entry point this should look something like this:
IUnityContainer container = new UnityContainer();
container.RegisterType<SomeClass>();
container.RegisterType<IFirstLevelOfAbstraction, SubClass1>();
container.RegisterType<IFirstLevelOfAbstraction, SubClass2>();
container.RegisterType<ISecondLevelOfAbstraction, SubClass3>();
container.RegisterType<ISecondLevelOfAbstraction, SubClass4>();
var someClass= container.Resolve<SomeClass>();
Question Being: How do I choose which path will the DI have in the container?
i.e The instance of IFirstLevelOfAbstraction being SubClass1 and for ISecondLevelOfAbstraction being SubClass4.
How do I easily change this later on?
Having so many DI nested isn't an anti-pattern? Why? Why is this any good?
I feel like nobody uses this. It's not even native in C#.
One way to do it is not to register SubClass1, SubClass2,SubClass3, or SubClass4 and then choose such dependencies when you resolve. Here is an example:
IUnityContainer container = new UnityContainer();
var someClass = container.Resolve<SomeClass>(
new DependencyOverride<IFirstLevelOfAbstraction>(new ResolvedParameter<SubClass1>()),
new DependencyOverride<ISecondLevelOfAbstraction>(new ResolvedParameter<SubClass4>()));
If this is not an option for you (you don't want to specify anything at resolve time), you need to use named registrations. I wouldn't recommend going that route though.
Since you have multiple implementations for a single interface, I recommend that you use Pure DI. See my article here for a reason why.
Here is how your code would look like with Pure DI:
var someClass =
new SomeClass(
new SubClass1(
new SubClass4()));

What is an IOC container actually doing for me here?

So I've refactored completely to constructor injection, and now I have a bootstrapper class that looks similar to this:
var container = new UnityContainer();
container.RegisterType<Type1, Impl1>();
container.RegisterType<Type2, Impl2>();
container.RegisterType<Type3, Impl3>();
container.RegisterType<Type4, Impl4>();
var type4Impl = container.Resolve((typeof)Type4) as Type4;
type4Impl.Run();
I stared at it for a second before realizing that Unity is really not doing anything special here for me. Leaving out the ctor sigs, the above could be written as:
Type1 type1Impl = Impl1();
Type2 type2Impl = Impl2();
Type3 type3Impl = Impl3(type1Impl, type2Impl);
Type4 type4Impl = Impl4(type1Impl, type3Impl);
type4Impl.Run();
The constructor injection refactoring is great and really opens up the testability of the code. However, I'm doubting the usefulness of Unity here. I realize I may be using the framework in a limited manner (ie not injecting the container anywhere, configuring in code rather than XML, not taking advantage of lifetime management options), but I am failing to see how it is actually helping in this example. I've read more than one comment with the sentiment that DI is better off simply used as a pattern, without a container. Is this a good example of that situation? What other benefits does this solution provide that I am missing out on?
I have found that a DI container becomes valuable when you have many types in the container that are dependent on each other. It is at that point that the auto-wire-up capability of a container shines.
If you find that you are referring to the container when you are getting object out of, then you are really following the Service Locator pattern.
To some extent you're right. Inversion of control does not need to mean using IoC container at all. If your object graph is small enough and convenient enough to be created at once in some kind of bootstrapping code, that's inversion of control, too.
But using an IoC tools simplifies the object creation in case of more complex scenarios. Using IoC tools you can manage object lifecycles, compose your object graph from different configurations or when not the whole graph is known at compile time, easily defer the object creation etc. etc.
There is no general solution. Everything depends from your specific needs. For a simple project with few classes, using IoC can be more annoying than helpful. For a big project I can't even imagine how the bootstrapping code need to look like.
See my post here for an extensive response to this question.
Most of the other answers here are correct, and say pretty much the same thing. I would add that most IoC containers allow you to auto-bind types to themselves, or use binding by convention. If you set up Unity to do that, then you can get rid of all that binding code entirely.
The difference is that you are doing the dependency injection instead of Unity doing dependency injection. In your example, you would have to know what types need to be created coupling your code to those types. You now need to know in your code that Impl1 should be created whenever you need a Type1.
Here's a simple code illustration of what other's have said (albeit taking a few liberties, property injection instead of constructor injection and assuming you've registered your types, etc).
public interface IFoo { }
public interface IBar { IFoo FooImpl { get; set; } }
public interface IBaz { IBar BarImpl { get; set; } }
public interface IBat { IBaz BazImpl { get; set; } }
As your object graph grows and dependencies are nested further and further down the graph, you'll have to provide the whole tree:
var bat = new Bat{
BazImpl = new BazImpl() {
BarImpl = new BarImpl() {
FooImpl = new FooImpl()
}
}
};
However, if you use the container correctly, all of that resolution comes based on what you've registered:
var bat = container.Resolve<IBat>()
Much like the other answers have probably stated, an IoC container is not required to perform dependency injection. It simply provides for automated dependency injection. If you don't get much of an advantage from the automation, then don't worry too much about a container, especially at the entry point of your application where you're injecting the initial objects.
There are however some things an IoC can make easier:
Lazy initialization. Autofac and a few others (not sure about Unity) can detect a constructor that takes a Func<IMyDependency> and, given a registration for an IDependency, will automatically generate the appropriate factory method. This reduces the front-loading often required in a DI system, where a lot of big objects like repositories have to be initialized and passed into the top-level object.
Sub-dependency hiding. Say class A needs to instantiate a class B, and B needs C, but A shouldn't know about C. Maybe even class Z which created A can't even know about C. This is the thing for which IoCs were created; throw A, B and C into the container, shake it up and resolve a fully-hydrated B to give to A, or a factory method which can be injected into A (automatically) and which the A can use to create all the B references it wants.
Simple "singletoning". Instead of creating and using a static singleton, an IoC can be told to create and return one and only one instance of any registered dependency no matter how many times that dependency is asked for. This allows the developer to turn any ordinary instance class into a singleton for use in the container, with no code change to the class itself required.
Your example is very simple, and the object graph would be very easily managable without using a DI framework. If this is really the extent of what is needed, doing manual DI would work fine.
The value of using a DI framework goes up very quickly as the dependency graph becomes more complex.

Categories

Resources