Search code examples
c#springdictionaryspring.net

Generic Dictionary containing Generic Dictionary in Spring.Net


I have an object that contains a property:

public Dictionary<string, Dictionary<string, List<ContextMenuItemModel>>> ContextMenuModel { get; set; }

How do I use Spring.Net to configure this property?


Solution

  • Well, configuring this in xml isn't pretty, consider switching to Spring.Net code config to configure your spring context in C#.

    Anyway, to do this in xml, you use the constructors of the generic .net collections. For instance, List<T> takes an IList<T> constructor, so you can configure a list of strings as follows:

    <object id="list1" type="System.Collections.Generic.List&lt;string>">
      <constructor-arg>
        <list element-type="string">
          <value>abc</value> 
          <value>def</value> 
        </list>
      </constructor-arg>
    </object>
    

    Note that in xml you have to use &lt;, because using < isn't legal xml. Setting generic collection values is discussed in the Spring.net docs.

    A generic Dictionary<string, System.Collections.Generic.List<string>> can be configured in a similar manner, which is also discussed in this answer:

    <object id="dic1" type="System.Collections.Generic.Dictionary&lt;string, System.Collections.Generic.List&lt;string>>">
      <constructor-arg>
        <dictionary key-type="string" value-type="System.Collections.Generic.List&lt;string>">
          <entry key="keyToList1" value-ref="list1" />
          <entry key="keyToList2" value-ref="list2" /> 
        </dictionary>
      </constructor-arg>
    </object>
    

    And you probably see the next one coming now:

    <object id="dic0" type="System.Collections.Generic.Dictionary&lt;string, System.Collections.Generic.Dictionary&lt;string, System.Collections.Generic.List&lt;string>>>">
      <constructor-arg>
        <dictionary key-type="string" value-type="System.Collections.Generic.Dictionary&lt;string, System.Collections.Generic.List&lt;string>>">
          <entry key="keyToDic1 " value-ref="dic1" />
        </dictionary>
      </constructor-arg>  
    </object>
    

    Which can be injected:

    <object id="MyObject" type="MyNamespace.MyClass, MyAssembly">
      <property name="ContextMenuModel" ref="dic0" />
    </object>
    

    This isn't really pretty, but you can slightly improve the readability of your xml using type aliases.