I'm using Prism, which gives be the nice Unity IoC container too. I'm new to the concept, so I haven't gotten my hands all around it yet. What I want to do now is to create an object using the IoC container, but passing an extra parameter too. Allow me to explain with an example..:
I have a class that takes a commands object. This is registered in the IoC container, so it will handle it nicely:
public class Person
{
public Person(IApplicationCommands commands) { .. }
..
}
Person person = _container.Resolve<Person>();
Now - I want to pass in another argument - e.g. the name of the person. However, I still want to use the IoC container to handle the resolving and hence get the other paramenters from the IoC container. But pass in the name as a "custom" parameter. Can this be done?
public class Person
{
public Person(IApplicationCommands commands, string name) { .. }
..
}
string name = "John";
Person person = _container.Resolve<Person>(name); // ....??
This example doesn't seem to work, but is there a way to make it work? Or does Unity IoC container require all parameters to be registered in the container before calling Resolve?
A class that holds the collection of information for a constructor, so that the container can be configured to call this constructor.
The Unity Container (Unity) is a full featured, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages: Simplified object creation, especially for hierarchical object structures and dependencies.
Dependency Injection (DI) Dependency Injection is defined as a design pattern that allows removing hard-coded dependencies from an application. There is one major point to remember: “Inversion of control is principal and Dependency Injection is implementation”.
Can I pass constructor parameters to Unity's Resolve() method?
container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
Edit: this answer is obsolete, in my opinion, because it has an assumption of an older version of Unity. NotDan's answer is better.
You've got a few options. They are honestly a bit lame, but they will work.
Option 1: Scoped Container
If you want to use constructor injection, you'll need to create a scoped container and put your data into that scoped container:
IUnityContainer subContainer = _container.CreateChildContainer();
//Don't do this... create a custom type other than string, like
// MyConstructorParams or something like that... this gets the point across.
subContainer.RegisterInstance<string>("John");
Person person = subContainer.Resolve<Person>();
Option 2: Initialize Method
What I typically do, though, is have a seperate Initialize method on my target objects for instance variables:
public class Person { public Person(IApplicationCommands commands) { .. } public void Initialize(string name) { .. } .. }
And then your usage becomes:
Person person = container.Resolve<Person>();
person.Initialize("John");
Neither is particularly pleasant, but it'll get the job done. The important thing is to pick a convention and stick to it, otherwise you'll get a bit lost.
Hope this helps.
There are a few choices you might consider:
In the case where you need to create a new entity which has legitimate dependencies in addition to any data being supplied (e.g. customer name), encapsulate this into a factory which itself has been injected into the calling object:
Person person = _personFactory.CreatePerson("bubba");
The factory can be injected with the entity's dependencies and supplied to the constructor if required or set by other means if optional:
var person = new Person("bubba", _domainService);
For transient-variable dependencies, such as a strategy used by a particular method, use Double Dispatch:
public class Person
{
public void DoSomethingWith(SomeStrategy strategy)
{
strategy.DoSomething(this);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With