Remember that property injection is optional and that you must apply the Dependency attribute to target class properties if you want property injection of dependent types to occur.
Using Property Injection with Constructor Parameters
You can also apply the Dependency attribute to the parameters of the constructor of a class if you only require access to these dependent objects within the constructor—though you can use code in the constructor to save the newly created dependent object instances in class-level variables if required.
This approach implements mandatory injection of dependent objects, providing that developers use the Unity container to generate the original (target) object. The dependent object instance is generated when the Unity container creates an instance of the target class using the attributed constructor.
For example, the following extracts from the StoplightPresenter class of the StopLight QuickStart sample show how the property declaration for the Schedule property defines a dependency on the StoplightSchedule class.
[Dependency]
public StoplightSchedule Schedule
{
get { return _schedule; }
set { _schedule = value; }
}
<Dependency> _
Public Property Schedule() As StoplightSchedule
Get
Return _schedule
End Get
Set(ByVal value As StoplightSchedule)
_schedule = value
End Set
End Property
The constructor of the StoplightSchedule class also contains a Dependency attribute that specifies a dependency on a concrete implementation of the IStoplightTimer class.
public StoplightSchedule([Dependency] IStoplightTimer timer)
{
this._timer = timer;
}
Public Sub StoplightSchedule(<Dependency()> timer As IStoplightTimer)
Me._timer = timer
End Sub
The following code located in the main program defines a registered mapping between the IStopLightTimer interface and the concrete implementation named RealTimeTimer.
IUnityContainer container = new UnityContainer();
container.RegisterType<IStoplightTimer, RealTimeTimer>();
Dim container As IUnityContainer = New UnityContainer()
container.RegisterType(Of IStoplightTimer, RealTimeTimer)()
Therefore, when the main program accesses the Schedule property of the StoplightPresenter class, the Unity container will create an instance of the StoplightSchedule class. The Dependency attribute in the parameters of the StoplightSchedule class constructor will cause the Unity container to create an instance of the RealTimeTimer class.
Property Injection with Existing Objects
If you use the RegisterInstance method to register an existing object, property (setter) injection does not take place on that object because it has already been created outside of the influence of the Unity container. However, you can call the BuildUp method of the container and pass it the existing object to force property injection to take place on that object.
Avoiding Circular References
Dependency injection mechanisms can cause application errors if there are circular references between objects that the container will create. For more details, see Circular References with Dependency Injection.
When to Use Property (Setter) Injection
You should consider using property injection in the following situations:
- You want to instantiate dependent objects automatically when you instantiate the parent object.
- You want a simple approach that makes it easy to see in the code what the dependencies are for each class.
- The parent object requires a large number of constructors that forward to each other, making debugging and maintenance difficult.
- The parent object constructors require a large number of parameters, especially if they are of similar types and the only way to identify them is by position.
- You want to make it easier for users to see what settings and objects are available, which is not possible using constructor injection.
- You want to control which objects are injected by editing the code of the dependent object instead of the parent object or application.
If you are not sure which type of injection to use, the recommendation is that you use constructor injection. This is likely to satisfy almost all general requirements.
Note: |
| You can also apply property injection dynamically using the configuration API of the Unity container. For more information, see the section "Dynamically Configuring Constructor, Property, and Method Injection" in the topic Entering Configuration Information. |