How to register the same type with different constructors using xml configuration

Aug 5, 2009 at 1:10 AM

Hi,

I'm trying wire my objects/components together through xml configuration only.

 

IUnityContainer myContainer = new UnityContainer();
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Containers.Default.Configure(myContainer);

var magic = myContainer.Resolve<BroadcastMagic>();
magic.BroadcastMessage("Magic!!");


The code which describes the BroadcastMagic component is as follows:
public interface IA
    {
        string ID { get; }
        void Log(string message);
    }

    public class A1 : IA
    {
        private Guid Guid;

        public A1()
        {
            Guid = Guid.NewGuid();
        }

        public string ID
        {
            get { return Guid.ToString(); }
        }

        public void Log(string message)
        {
            Console.WriteLine("A1: "+ message + ". ID: " + ID);
        }
    }

    public class A2 : IA
    {
        private Guid Guid;

        public A2()
        {
            Guid = Guid.NewGuid();
        }

        public string ID
        {
            get
            {
                return Guid.ToString();
            }
        }

        public void Log(string message)
        {
            Console.WriteLine("A2: " + message + ". ID: " + ID);
        }        
    }

    public class NeedsIA : IGetMessages
    {
        private readonly IA a;

        public NeedsIA(IA a)
        {
            this.a = a;
        }

        public void RecieveMessage(string message)
        {
            a.Log(message);
        }
    }

    public class BroadcastMagic
    {
        private IGetMessages[] listeners;

        public BroadcastMagic(IGetMessages[] listeners)
        {
            this.listeners = listeners;
        }

        public void BroadcastMessage(string message)
        {
            foreach (var listener in listeners)
            {
                listener.RecieveMessage(message);
            }
        }
    }

    public interface IGetMessages
    {
        void RecieveMessage(string message);
    }

BroadcastMagic takes in a list of IGetMessages. NeedsIA implements IGetMessages, so for the moment the list being passed into the constructor of BroadcastMagic is a list of NeedsIA. The difference between each NeedsIA, is the different contructor taken in by the NeedsIA Contructor.
One NeedsIA will take in A1, and the second will take in A2. So I'm trying to resolve two NeedsIA which take in two different constructors. I am getting this error:

"System.TypeLoadException was unhandled
  Message="Could not load type 'UnitySpike.NeedsIA' from assembly 'Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."
  Source="mscorlib"
  TypeName="UnitySpike.NeedsIA"

If I comment out "subsystemB" and the reference to it in the BroadcastMagic type within the XML, no exceptions are thrown.

Is what I'm asking achievable? Have a missed something very basic??

The xml configuration code looks as follows

 

 

<containers>
      <container>
        <types>
          <type name="A1"
                type ="UnitySpike.IA, UnitySpike"
                mapTo="UnitySpike.A1, UnitySpike">
            <lifetime type="singleton" />
          </type>
          <type name="A2"
                type ="UnitySpike.IA, UnitySpike"
                mapTo="UnitySpike.A2, UnitySpike">
            <lifetime type="singleton" />
          </type>

          <type name ="subsystemA" 
                type="UnitySpike.IGetMessages, UnitySpike"
                mapTo="UnitySpike.NeedsIA, UnitySpike">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="a" parameterType="UnitySpike.IA, UnitySpike">
                  <dependency name="A1"/>
                </param>
              </constructor>
            </typeConfig>
            <lifetime type="singleton" />
          </type>

          <type name ="subsystemB"
                type="UnitySpike.IGetMessages, UnitySpike"
                mapTo="UnitySpike.NeedsIA">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="a" parameterType="UnitySpike.IA, UnitySpike">
                  <dependency name="A2"/>
                </param>
              </constructor>
            </typeConfig>
            <lifetime type="singleton" />
          </type>

          <type type="UnitySpike.BroadcastMagic, UnitySpike"
                mapTo="UnitySpike.BroadcastMagic, UnitySpike">
            <lifetime type="singleton" />
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                      Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="listeners" parameterType="UnitySpike.IGetMessages[], UnitySpike">
                  <array>
                    <dependency name="subsystemA"/>
                    <dependency name="subsystemB"/>
                  </array>
                </param>
              </constructor>
            </typeConfig>
          </type>
        </types>
        <instances>
        </instances>
     </container>
</containers>

 

Thanks in advance
V

 

Aug 5, 2009 at 1:15 AM
Edited Aug 5, 2009 at 1:16 AM

Well, after spending ages trying to work that out, I find out why it wasnt working....in "subsytemB" the concrete class was not fully qualified. It should look as follows:

 

           <type name ="subsystemB"
type="UnitySpike.IGetMessages, UnitySpike"
mapTo="UnitySpike.NeedsIA, UnitySpike">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="a" parameterType="UnitySpike.IA, UnitySpike">
<dependency name="A2"/>
</param>
</constructor>
</typeConfig>
<lifetime type="singleton" />
</type>