DCSIMG
Working With Generic Types In Unity Configuration Section - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2013 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

Working With Generic Types In Unity Configuration Section

Working With Generic Types In Unity Configuration Section

In my previous post about Unity Unity Application Block
discussed about configuration
files and how to configure Unity with
them. I got a question in the subject
of how to use generic types in the
configuration files. This post will
answer that question.

The Scenario
I have an interface of IValidator which receives a generic type T.

    public interface IValidator<T>

    {

        #region Methods

        void Validate<T>();

        #endregion

    }

Also, I have a class Validator which receives a generic type T and implement
the IValidator interface.

    public class Validator<T> : IValidator<T>

    {

        #region IValidator<T> Members

        public void Validate<T>()

        {

            // do something

        }

        #endregion

    }

Instead of registering them in code I want to write the mapping in the configuration file
How to do it?

The Configuration File
I return to the configuration file that I showed in the previous post. The only difference
is that I added a new type to map – the IValidator type. Also, I added a type alias to that
type. The configuration file:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name="unity"

      type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,

      Microsoft.Practices.Unity.Configuration, Version=1.1.0.0,

      Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

  </configSections>

  <unity>

    <typeAliases>

      <!-- Lifetime manager types should be inserted

          if you need lifetime managers -->

      <typeAlias alias="singleton"

          type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,

            Microsoft.Practices.Unity" />

      <typeAlias alias="external"

          type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,

            Microsoft.Practices.Unity" />

      <!-- User defined type aliases -->

      <!-- An interface for logger implementation -->

      <typeAlias alias="ILogger"

          type="UnityExamples.Common.ILogger,

          UnityExamples.Common" />

      <!-- An abstarct class for database classes -->

      <typeAlias alias="Database"

          type="UnityExamples.Common.Database,

          UnityExamples.Common" />

      <typeAlias alias="IValidator`1"

          type="UnityExamples.Common.IValidator`1,

          UnityExamples.Common" />

    </typeAliases>

    <containers>

      <container>

        <types>

          <type type="ILogger"

                mapTo="UnityExamples.Common.FileLogger,

                UnityExamples.Common">

            <!-- Will be configured as singleton by the lifetime

                manager above -->

            <lifetime type="singleton" />

          </type>

          <type type="IValidator`1"

                mapTo="UnityExamples.Common.Validator`1,

                UnityExamples.Common">

            <!-- Will be configured as singleton by the lifetime

                manager above -->

            <lifetime type="singleton" />

          </type>

          <type type="Database"

                mapTo="UnityExamples.Common.CustomDatabase,

                UnityExamples.Common">

            <typeConfig

              extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,

                Microsoft.Practices.Unity.Configuration">

              <constructor>

                <param name="connString" parameterType="System.String">

                  <value value="connection value..."/>

                </param>

                <param name="logger" parameterType="ILogger">

                  <dependency />

                </param>

              </constructor>

            </typeConfig>

          </type>

        </types>

      </container>

    </containers>

  </unity>

</configuration>

As you can see in order to write a generic type I use the ` sign followed
by the number of generic types that the interface/class receives. In my
example the IValidator interface receives only one generic type and
therefore I use 1.

The Code To Run The Example
The following code will run the configuration file and map the IValidator
to the Validator class with a string input as the generic type the Validator
gets.

   IUnityContainer container = new UnityContainer();

   var section =

      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

   section.Containers.Default.Configure(container);

   var validator = container.Resolve<IValidator<string>>();

Summary
Lets sum up the post, I showed an example of how to use a Unity
configuration section
with generic types. All you have to remember is the
` sign as the sign for a generic type in the configuration file

Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# July 25, 2008 9:55 AM

Chris Cyvas said:

You rock! I was battling this for last hour and your suggestion fixed me right up. Thanks so much!

# August 7, 2008 12:50 PM

Gil Fink said:

Thanks Chris,

I'm glad I could help.

# August 7, 2008 1:14 PM

Ian said:

Thanks for the help,

can you expand this example to work for this case:

RegisterType<IGenericFactoryInterface<Tractor>, TractorFactory>();

Where IGenericFactoryInterface, Tractor and TractorFactory are all in different namespaces.

It works fine when I can code it, just having difficulty adapting it for the configuration file.

Not sure how to handle all the different namespaces.

# August 13, 2008 9:29 AM

Ian said:

Got it to work.

<type type="NameSpace1.IGenericFactoryInterface`1[[NameSpace2.Tractor,NameSpace2]], NameSpace1"

mapTo="NameSpace3.TractorFactory, NameSpace3"/>

# August 13, 2008 12:42 PM

Gil Fink said:

Hi Ian,

Sorry I couldn't reply until now. I see that you solved the problem by yourself. As you wrote the solution is to write the namespaces where they are needed. Also in order to use a constant type in the generic you need to use brackets like in your example ([[ ]]).

# August 15, 2008 5:30 AM

nawaf said:

Hi again

This could work

   public interface ISettingBehavior <T>

   {

        bool SaveSettings(T settings, string name);

        bool SaveSettings(T settings);

        T GetSettings();

   }

   public interface IAppSettings : ISettingBehavior<IAppSettings>

   {

   }

 public sealed class AppSettings : IAppSettings

   {

       public bool SaveSettings(IAppSettings settings){}

       public IAppSettings GetSettings() {}

       public bool SaveSettings(IAppSettings settings, string name){}

   }

var settings = container.Resolve<IAppSettings>();

regards

# August 29, 2008 2:14 PM

Haim said:

Hi ,

Thanks you for the information in this article you really helped me to solve issues with unity and generic types.

I have a questions regarding objects that don't have empty constructors. Is it possible to map objects that gets parameters in the constructor?

Regards,

Haim

# September 15, 2008 1:37 PM

Gil Fink said:

Hi Haim,

Thanks for your comment.

For the question of empty constructor the answer is yes. It is possible to map objects that gets parameters in the constructor regarding objects that don't have empty constructors.

# September 17, 2008 2:58 PM