With Unity how do I inject a named dependency into a constructor?
You can configure dependencies with or without names in the API, attributes, or via the config file. You didn't mention XML above, so I'll assume you're using the API.
To tell the container to resolve a named dependency, you'll need to use an InjectionParameter
object. For your ClientModel
example, do this:
container.RegisterType<IClientModel, ClientModel>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<IRepository>("Client") // Resolve parameter of type IRepository using name "Client"
)
);
This tells the container "When resolving ClientModel
, call the constructor that takes a single IRepository
parameter. When resolving that parameter, resolve with the name 'Client' in addition to the type."
If you wanted to use attributes, your example almost works, you just need to change the attribute name:
public ClientModel([Dependency("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
Unity Dependency Injection how to pass mapping name into sub objects resolved in parent objects constructor
I found a solution to this after many attempts at it
_container.RegisterType<IEntity, EntityA1>("processA",
new InjectionConstructor(new ResolvedParameter<IRepo>("processA")));
This then resolves the correct mapping of IRepo
var entityInstance = container.Resolve<IEntity>(processType);
This achieves what I wished which was to clarify this at the point of registration not resolving.
If anybody has improvements to the above I would be grateful to hear back from you
Thanks
How to inject a Type instead of an instance into a constructor using Unity
The constructor of InjectionConstructor
takes an array of objects. If the type of an object passed to the constructor of InjectionConstructor
(in the array) is of type Type
, unity will try to resolve that type and then pass the result into the constructor (of 'Service` for example).
For example, if you use new InjectionConstructor(typeof(IMyOtherService))
, then unity will expect that the constructor of Service
takes an instance of type IMyOtherService
and will use the container to resolve such type. In other words Type
is a special case that you need to handle in a specific way.
To solve your issue, you should tell Unity that the Type
you are passing is actually a constructor parameter. You can do this like this:
new InjectionConstructor(new InjectionParameter(jobType))
This forces unity to treat jobType
as a constructor parameter.
For more details see the InjectionParameterValue.ToParameter
method here: https://github.com/unitycontainer/unity/blob/master/source/Src/Unity-CoreClr/Injection/InjectionParameterValue.cs
Constructor Injection in C#/Unity?
One way to solve this would be to use an injection constructor with a named registration.
// Register timmy this way
Person son = new Person("Timmy");
container.RegisterInstance<Person>("son", son);
// OR register timmy this way
container.RegisterType<Person>("son", new InjectionConstructor("Timmy"));
// Either way, register bus this way.
container.RegisterType<Bus>(new InjectionConstructor(container.Resolve<Person>("son")));
// Repeat for Joe / Train
Register types in UnityContainer to use other named registrations to resolve constructor parameters
Here is how you can do it:
container.RegisterType<IStd>(
new InjectionFactory(x =>
x.Resolve<Std>(new DependencyOverride<IFace>(x.Resolve<IFace>("impl2")))));
InjectionFactory
allows you to specify the factory logic that creates the IStd
object. We use the Resolve
method to resolve the concrete Std
class and we use the DependencyOverride
class to specify which implementation of IFace
to use. Again we use the Resolve
method to resolve a specific implementation.
Please note that the factory logic will only run when someone tries to resolve IStd
(or a class that depends on IStd
), not when you register IStd
.
Related Topics
How to Take the Cartesian Join of Two Lists in C#
Convert Am/Pm Time to 24 Hours Format
Newtonsoft JSON.Net Serialize Jobject Doesn't Ignore Nulls, Even with the Right Settings
C# Object Initialization of Read Only Collection Properties
Group by Variable Integer Range Using Linq
PDF Compression with Itextsharp
Overloaded Method-Group Argument Confuses Overload Resolution
How Does One Extract Each Folder Name from a Path
Using Statement with Generics: Using Iset<> = System.Collections.Generic.Iset<>
Reading from a Text File in C#
How to Mix Colors "Naturally" with C#
Stream.Seek(0, Seekorigin.Begin) or Position = 0
Dependency Injection VS Service Location
.Net Core 3.0: Razor Views Don't Automatically Recompile on Change