Unity v1.2 - using enum values from configuration; writing and configuring a custom type converter

Recently, I used Unity v1.2, which in my opinion is a great product. I had difficulty, however, with the configuration for a scenario I encountered. I needed an enum value to be passed to a constructor. Trying as I might, there was no way Unity was accepting my typeAlias, as such:

 <unity>
  <typeAliases>
    <typeAlias 
      alias="contextType" 
      type="System.DirectoryServices.AccountManagement.ContextType, 
            System.DirectoryServices.AccountManagement, Version=3.5.0.0, 
            Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </typeAliases>
  <containers>
    <container name="identitystores">
      <types>
        <type name="primary" type="IIdentityStore" mapTo="ActiveDirectoryIdentityStore" >
          <lifetime type="singleton" />
          <typeConfig 
            extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, 
                           Microsoft.Practices.Unity.Configuration">
            <constructor>
              <param name="context" parameterType="contextType">
                <value
                  value="Domain"
                  type="contextType"  />
              </param>
            </constructor>
          </typeConfig>
        </type>
      </types>
    </container>
  </containers>
</unity>

For the life of me, I couldn't figure out what I did wrong. I asked in an internal discussion list, and someone mentioned writing a plain old TypeConverter... Right he was, getting my enum value to work was pretty easy. The TypeConverter (as always, comments removed for clarity and provided AS IS, etc.):

 public class ContextTypeTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType.GetType() == typeof(string);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(ContextType);
    }
    
    public override object ConvertFrom(
        ITypeDescriptorContext context, 
        CultureInfo culture, 
        object value)
    {
        return Enum.Parse(typeof(ContextType), (string)value);
    }

    public override object ConvertTo(
        ITypeDescriptorContext context, 
        CultureInfo culture, 
        object value, 
        Type destinationType)
    {
        return Enum.GetName(typeof(ContextType), value);
    }
}

and modified configuration file:

 <unity>
  <typeAliases>
    <typeAlias 
     alias="contextType" 
      type="System.DirectoryServices.AccountManagement.ContextType, 
            System.DirectoryServices.AccountManagement, Version=3.5.0.0, 
            Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </typeAliases>
  <containers>
    <containername="identitystores">
      <types>
        <typename="primary" type="IIdentityStore" mapTo="ActiveDirectoryIdentityStore" >
          <lifetimetype="singleton" />
          <typeConfig 
           extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, 
                           Microsoft.Practices.Unity.Configuration">
            <constructor>
              <param name="context" parameterType="string">
                <value
                 value="Domain"
                  type="contextType"
                  typeConverter=" Microsoft.AccountManagement.Extensions.ContextTypeTypeConverter, <br>                                 Microsoft.AccountManagement.Extensions, Version=1.0.0.0, <br>                                 Culture=neutral, PublicKeyToken=4fd564a94067c21"  /> 
              </param>
            </constructor>
          </typeConfig>
        </type>
      </types>
    </container>
  </containers>
</unity>

That's it, now everything works just fine. HTH someone out there :)

Comments

  • Anonymous
    April 06, 2010
    "HTH someone out there :)" It did, many thanks :)