views:

510

answers:

2

Hi, I'm converting a Castle/Monorails application into a Unity/Asp.NET MVC one, I'm stuck in trying to converting this component configuration:

<component
  id="ComponentBaseConfiguration"
  service="MyFakeNamespace.BOL.IConfiguration, MyFakeAppDll"
  type="MyFakeNamespace.BOL.ConfigurableConfiguration, MyFakeAppDll">
  <parameters>
    <!-- Setting Configuration (Dictionary<string,string>)-->
    <Config>
      <dictionary>
        <entry key="localHost">#{LocalHost}</entry>            
        <entry key="contentHost">#{ContentHost}</entry>
        <entry key="virtualDir">#{VirtualDir}</entry>            
      </dictionary>
    </Config>
  </parameters>

seems that Unity supports Array but not Dictionary, I would like to do something like this:

<unity>
<containers>
 <container>
  <types>
   <type name="ComponentBaseConfiguration" type="MyFakeNamespace.BOL.IConfiguration, MyFakeAppDll" mapTo="MyFakeNamespace.BOL.ConfigurableConfiguration, MyFakeAppDll">
    <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
     <property name="Config" propertyType="System.Collections.Generic.Dictionary`2[[System.String, mscorlib], [System.String, mscorlib]],mscorlib">
      <dictionary>
       <entry key="localHost">127.0.0.1</keyedValue>
       <entry key="contentHost">\\content</keyedValue>
       <entry key="virtualDir">/</keyedValue>
      </dictionary>
     </property>
    </typeConfig>
   </type>
  </types>
 </container>
</containers></unity>

How can I achieve something like this?

+2  A: 

I think you have to use the method-element to archive this. It´s not nice but a workaround.

Your type must define a method Add(string key, string value) which the unity container uses to inject the values.

<method name="Add">
 <param name="key" parameterType="string">
  <value value="localHost"/>
 </param>
 <param name="value" parameterType="string">
  <value value="127.0.0.1"/>
 </param>
</method>

Unity definitely does not support dictionaries for container configuration. See Build Dictionaries using Unity container?

Jehof
A: 

I discovered that Unity have bugs when handling Generics (http://unity.codeplex.com/Thread/View.aspx?ThreadId=30292), there is a quite ugly workaround to this:

public class MyDictionary : Dictionary<string,string>{

    public MyDictionary() { 

    }
}

now in the configuration file:

        <typeAlias alias="string" type="System.String, mscorlib" />            
        <typeAlias alias="Dictionary" type="MyFakeNamespace.MyDictionary, MyFakeAppDll" />

...

and then using the Jehof suggestion:

<type name="ConfigurationDictionary" type="Dictionary">
                    <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
                        <method name="Add" key="0">
                            <param name="key" parameterType="string">
                                <value value="localHost"/>
                            </param>
                            <param name="value" parameterType="string">
                                <value value="127.0.0.1"/>
                            </param>
                        </method>
                        <method name="Add" key="1">
                            <param name="key" parameterType="string">
                                <value value="contentHost"/>
                            </param>
                            <param name="value" parameterType="string">
                                <value value="\\content"/>
                            </param>
                        </method>
                        <method name="Add" key="2">
                            <param name="key" parameterType="string">
                                <value value="virtualDir"/>
                            </param>
                            <param name="value" parameterType="string">
                                <value value="/"/>
                            </param>
                        </method>
                    </typeConfig>

                 </type>

the key attribute in the method tag need to be unique in order to call the method Add multiple times.

Then, when the bug will be solved a little change in the typeAlias allow us to put the right type, but I think I will leave as is it.

kentaromiura