use common constructor values when registering types

Jul 28, 2010 at 4:56 AM

Is it possible to declare a "value alias", similar to creating a "type alias" - and then use that common definition when registering types? The primary usage for this is when registering repository types - and providing a common connection string as a constructor parameter. I have looked at <instance> but not sure if that's the right element.

For example, at the moment i have something like this in the Unity configuration file:

      <containers>
           <container>
                <register type="ILocationRepository" mapTo="LocationRepository">
                    <constructor>
                        <param name="connString" value="Data Source=Server1;Initial Catalog=MyDatabase;"/>
                    </constructor>
                </register>
                <register type="IHotelRepository" mapTo="HotelRepository">
                    <constructor>
                        <param name="connString" value="Data Source=Server1;Initial Catalog=MyDatabase;"/>
                    </constructor>
                </register>
            </container>
        </containers>

Is it possible to re-write this somehow like this:

      <containers>
           <something name="myDefinedValue" value="Data Source=Server1;Initial Catalog=MyDatabase;"/>
           <container>
                <register type="ILocationRepository" mapTo="LocationRepository">
                    <constructor>
                        <param name="connString" value="myDefinedValue"/>
                    </constructor>
                </register>
                <register type="IHotelRepository" mapTo="HotelRepository">
                    <constructor>
                        <param name="connString" value="myDefinedValue"/>
                    </constructor>
                </register>
            </container>
        </containers>

Jul 28, 2010 at 7:30 AM
Edited Jul 28, 2010 at 9:09 AM

Yes, you could register an instance for that and use it as dependency when configuring constructor injection.  Your configuration looks like a mix of the 2.0 version and pre-2.0 version.  Anyway, I assume you're really using Unity 2.0 since you're using the <register> element (no wrapping of <container> element inside <containers>).  This is how your configuration would look like:

<container>
       <instance name="myDefinedValue" type="System.String" value="Data Source=Server1;Initial Catalog=MyDatabase;" />
       <register type="ILocationRepository" mapTo="LocationRepository">
             <constructor>
                   <param name="connString" dependencyName="myDefinedValue" />
             </constructor>
       </register>
       <register type="IHotelRepository" mapTo="HotelRepository">
             <constructor>
                   <param name="connString" dependency Name="myDefinedValue" />
             </constructor>
       </register>
</container>

Note that an instance is defined at the container level so it's not exactly like a type alias since an alias is available to all containers.

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jul 28, 2010 at 9:21 AM
Edited Jul 28, 2010 at 9:28 AM

Thanks for the solution Sarah. Yes i am using Unity 2.0 in the project - although i am interested to see what a "2.0 only" configuration wuld look like. I have only had a brief chance to do research on 2.0 since it was released - so i'm not too clear on best practices for configuring unity IOC via XML in 2.0. How would this config be done in a purely 2.0 manner?

	<unity>
		<alias alias="IHotelRepository" type="Project.Interfaces.IHotelRepository, Project"/>		
		<alias alias="ILocationRepository" type="Project.Interfaces.ILocationRepository, Project"/>		
		<alias alias="HotelRepository" type="Project.HotelRepository, Project"/>
		<alias alias="LocationRepository" type="Project.LocationRepository, Project"/>
		
		<containers>
			<container name="development">
				<instances>
					<add name="connString" type="System.String" value="Data Source=Server1;Initial Catalog=MyDatabase;"/>
				</instances>
				
				<register type="ILocationRepository" mapTo="LocationRepository">
					<constructor>
						<param name="connString" type="System.String">
							<dependency name="connString"/>
						</param>
					</constructor>
				</register>

				<register type="IHotelRepository" mapTo="HotelRepository">
					<constructor>
						<param name="connString" type="System.String">
							<dependency name="connString"/>
						</param>
					</constructor>
				</register>
			</container>
		</containers>
	</unity>

Jul 28, 2010 at 9:31 AM

What do you mean "2.0 only" configuration?  The configuration I posted above is already using the 2.0 version.  The difference is the removal of extraneous wrapping of elements. In Unity 2.0, container elements are no longer wrapped in containers elements; type registrations goes directly under the container element,  no more <types> elements; the same goes for instance registrations and type aliases; no more <typeConfig> as well, <constructor>, <property> and <method> elements for injection goes directly under the <register> element..  In addition, you can now directly specify the actual value of a parameter in a <param> element, whether it's a literal value of a dependency value(as you can see above). 

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 2, 2010 at 4:09 AM

What i meant was - what a 2.0 specification XML config would look like. You said that i had a mix of 1 and 2.0 configuration elements so i wanted to know how to take what i had, remove the extraneous elements - thus making it "only" 2.0.

From what i can see, i just need to remove the <containers> parent element from around the <container> element and put the dependency into the param as an attibute rather than a child element. Correct?

Aug 2, 2010 at 6:54 AM

Yes, that's correct.  And the configuration I posted is already in pure 2.0 version.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com