Condividi tramite


Specifying Values for Injection

This topic explains how to configure the information required so that Unity will automatically populate constructor and method parameters and property values when it resolves instances of types. The <param> and <property> elements both let you specify a value to be supplied for the parameter or property, respectively. There are many different kinds of values that can be specified, each with a separate element. In addition, the Unity configuration schema supports a shorthand notation for the most common cases.

For more information about the format of the Unity configuration file, see Using Design-Time Configuration.

This topic contains the following sections describing values for injection:

Resolving Values from the Container

Giving Values in Configuration

Configuring Array Values

Resolving Values from the Container

Probably the most common use is the case when you want the value for a parameter or property to be resolved from the container. You can use the <dependency> element to accomplish this. The type of the dependency to resolve is, by default, the type of the parameter or property being injected. If you want to use a different type, then you must specify the type attribute on the <dependency> element. Also, the container will resolve the default value for that type unless you use the name attribute to specify a named registration to resolve.

There are several shorthand attributes to expedite the configuration process. If you want to resolve the default registration for the type of the parameter or property, you can simply leave out the <dependency> element, as shown in the following example.

<register type="ILogger" mapTo="SerialPortLogger">
    <property name="Settings" />
</register>

Similarly, since specifying a dependency is so common, instead of using the child <dependency> element, you can use the dependencyType and dependencyName attributes on the containing elements. The following example uses the <dependency> element.

<!-- Explicit dependency element -->
<register type="ILogger" mapTo="SerialPortLogger">
    <property name="Settings">
        <dependency type="SpecialPortSettings" name="highSpeedSettings" />
    </property>
</register>

The following example uses attributes instead of the <dependency> element to accomplish the same configuration.

<!--Use attributes instead of the dependency element -->
<register type="ILogger" mapTo="SerialPortLogger">
    <property name="Settings" dependencyType="SpecialPortSettings”
        dependencyName="highSpeedSettings" />
</register>

The previous examples use the <property> element, but the attributes can also be used on the <param> element in exactly the same way.

Optional values, specified by using the <optional> element, are resolved from the container. If the container cannot resolve an optional value, for example when attempting to resolve an interface that is not registered, then instead of getting an exception, as you would for a normal dependency, you get null injected. There are no shorthand attributes for optional dependencies; you must use the explicit child element.

Giving Values in Configuration

The other most common scenario is to specify a particular value to be injected, such as a string or integer. The explicit way to do is by using the <value> element. This lets you specify a string, which will be passed to a TypeConverter to create the underlying object. The type of the value is the type of the enclosing property or parameter.

Like the <dependency> element, the <value> element has shorthand attributes. If you only need the default type converter to turn the string into a value, which is commonly the case for most value types like strings and numbers, you can simply use the value attribute on your enclosing parameter or property, as shown in the following example.

<register type="ILogger" mapTo="NetworkLogger">
    <constructor>

        <!-- Explicit value child element -->
        <param name="logHost">
            <value value="loghost.example.org" />
        </param>

        <!-- using shorthand attribute -->
        <param name="header" value="Log Entry:" />

        <!-- custom typeconverter, no shorthand available -->
        <param name="connectionSettings">
            <value value="port=123;protocol=tcp;timeout=30"
                typeConverter="ConnectionSettingsTypeConverter" />
        </param>
    </constructor>
</register>

Configuring Array Values

The container handles parameter or properties of array types uniquely. There are several options for how to configure array values; the choice depends on what you want to accomplish. See Registering Injected Parameter and Property Values.

The simplest approach for arrays is the default behavior of the container for arrays. In that case simply use the <dependency> child element or, for the equivalent shorthand attribute, just leave the attribute out.

If you wish to have only explicit values injected into the array, then you can use the <array> element with child elements. This element lets you specify explicitly what values you want to have injected.

If you want an empty array, use <array> with no child elements. If you want an array with values, include as children a set of other value elements, such as <dependency>, <optional>, or <value> to give the values for the various array elements. For example:

<register type="ILogger" mapTo="NetworkLogger">

    <!-- Empty array -->
    <property name="noSettings"> 
       <array />
    </property>

    <!-- Type NetworkSettings[], get default array injection -->
    <property name="allSettings" />

    <!--Type NetworkSettings[], get only the specified three values -->
    <property name="someSettings">
        <array>
            <dependency name="fastSettings" />
            <optional name="turboSettings" />
             <value value="port=1234;protocol=tcp;timeout=60"
                typeConverter="ConnectionSettingsTypeConverter" />
        </array>
    </property>
</register>