Issue with unity

Aug 11, 2012 at 3:55 AM

Hi,

Facing an issue with Unity 2.0 for inbuilt classes(enums etc).

1) I have a unitofwork class whose constructor has a parameter - IsoLationLevel and I want to set it to IsolationLevel.ReadCommitted while constructing the object using unity config file based registration.How do I do that?

2) I have a logger class whose constructor has a parameter - LogWriter(of Enterprise Library Logging) and I want to pass an instance of LogWriter using LogWriterFactory.Crete() while creating the instance of Logger class.How do I do that?

 

Thanks and Regards,

Sandip

Aug 11, 2012 at 11:01 AM
Edited Aug 11, 2012 at 12:11 PM

For declaring enums in configuration you can use a TypeConverter.  This example is for Unity 1.2 but should still apply for Unity 2 (configuration will be a bit different, though).  

So you could create a TypeConverter:

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

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return typeof(T).IsEnum;
        }

        public override object ConvertFrom(
            ITypeDescriptorContext context,
            CultureInfo culture,
            object value)
        {
            return Enum.Parse(typeof(T), (string)value);
        }

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

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly name="UnityEnum"/>
    <namespace name="UnityEnum"/>
    <alias type="System.Data.IsolationLevel, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" alias="IsolationLevel"/>
    <container>
      <register type="UnitOfWork">
        <constructor>
          <param name="level" type="IsolationLevel">
            <value value="ReadCommitted" typeConverter="EnumTypeConverter[IsolationLevel]">            
            </value>
          </param>
        </constructor>
      </register>
    </container>
  </unity>
</configuration>

For your second question can you expand on the scenario?  Thanks.

If I understand correctly, it sounds like you want to inject an LogWriter instance created from a factory.  To do that you can use an InjectionFactory.

    public class MyLogger
    {
        public MyLogger(LogWriter logWriter)
        {

        }
    }

    var container = new UnityContainer().LoadConfiguration();
    container.RegisterType<LogWriter>(new InjectionFactory((x) => new LogWriterFactory().Create()));
    var logger = container.Resolve<MyLogger>();

Unfortunately, there is no out of the box way to do this using configuration.  See this answer for some pointers on how to implement configuration.

Alternately, you could also create the instance and register it:

    var container = new UnityContainer();
    container.RegisterInstance<LogWriter>(new LogWriterFactory().Create()); 

If you really want to use "configuration" then the approach would be the same as the first question and is to create a TypeConverter that will create the LogWriter instance from the factory.

<register type="LogWriter">
    <lifetime type="Singleton"/>
    <constructor>
      <param name="logWriter">
        <value value="" typeConverter="LogWriterTypeConverter" />
      </param>
    </constructor>
</register>
public class LogWriterTypeConverter : System.ComponentModel.TypeConverter
{
    public override object ConvertTo(ITypeDescriptorContext context,
                                     CultureInfo culture, object value,
                                     Type destinationType)
    {
        return new LogWriterFactory.Create();
    }
}

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com