How to create object instances via config?

Feb 5, 2009 at 4:38 PM
Hello,

I would like to specify object instantiations via configuration, and I am not sure how to do this.

Let's say I have an object of type ObjectType which takes a string parameter in its constructor:

    class ObjectType
    {
        string Name { get; set; }

        public ObjectType(string name)
        {
            Name = name;
        }
    }

I declare the following types:

          <type type="ObjectType" name="ObjectType1">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="name" parameterType="string">
                  <value name="Object1" />
                </param>
              </constructor>
            </typeConfig>
          </type>
          <type type="ObjectType" name="ObjectType2">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="name" parameterType="string">
                  <value name="Object2" />
                </param>
              </constructor>
            </typeConfig>
          </type>

How do I then declare my instances in the "instances" configuration node?

        <instances>
          <add name="MyObject1" type="ObjectType" value="???"/>
        </instances>

The value attribute of instances/add seems irrelevant in my case, as I want Unity to resolve the instances/add/type to the type I declared.
Do I need to write a TypeConverter that will resolve based on the type passed in instances/add/value? Is there a generic implementation of it somewhere?

Thanks,
Thomas

Feb 6, 2009 at 8:55 AM
Yes, you would need a TypeConverter.  I believe there is no generic implementation which you can use.  If you didn't specify a typeconverter, it is assumed to already be of string type.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Feb 6, 2009 at 6:00 PM
Hang a second. Let's take a step back here and look at what the container is doing.

So you set up the container to properly build the objects in question. And then you want to register the instances in the container? Why?

From the API, you're trying to do the equivalent of:

container.RegisterType<ObjectType>("ObjectType1", new InjectionConstructor("Object1"))
    .RegisterType<ObjectType>("ObjectType2", new InjectionConstructor("Object2"));

And now you want to do this?

container.RegisterInstance("ObjectType1", container.Resolve<ObjectType>("ObjectType1"));

That doesn't make any sense. The container will resolve your objects already, there's no need to go back and register the instances in the container.

The instances section is for objects that you want created outside the container, and want available to be resolved by other objects. If you're already setting up the type, you don't have to do anything else.

The only thing you might want to tweak is to change the lifetime of your objects if you always want the same instance back - use the ContainerControlledLifetimeManager to do that. There are tons of examples in the docs on how to do this.

Hope this helps,

-Chris
Feb 9, 2009 at 7:24 PM
Hi Chris,

Yes, I think it makes sense, but I still have some misunderstanding.

I would like to create the instance of my object via configuration, so that I can choose Object1 or Object2 without recompiling.

Maybe another way to put my question is: what is the equivalent of container.Resolve<ObjectType>("ObjectType1") from the configuration, knowing that my object is not a dependency of any other object?

Thanks!


Feb 9, 2009 at 8:12 PM
There is no way to do a Resolve from the configuration. But I'm still not sure why you feel you need to do this up front? Why not just configure the type - at resolve time you'll get the configured object automatically, and you can change which object you get by changing which types are registered in the config file.

I guess I'm not sure what you want to do that is different from what the container does now. Could you give a more concrete example of what you're trying to do?

Feb 9, 2009 at 9:56 PM
Yes, let me try to be clearer.

I have an assembly that implements different messaging (MSMQ, Tcp...) under one messaging interface.
I also have an class that send messages thru that interface, another class that receives, a third that echoes messages from one interface to another...
I want to create applications that will instantiate either a sender, or a receiver or...
Rather than creating 3 different applications, I thought I could have one application and have Unity do the wiring for me and create my instance for me depending on my configuration.

Right now, I achieve this via a class that I called Bootstrap:

    class Bootstrap
    {
        object service;

        public Bootstrap(object service)
        {
            this.service = service;
        }
    }

And my config looks like:

          <type type="Bootstrap">
            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
                                     Microsoft.Practices.Unity.Configuration">
              <constructor>
                <param name="service" parameterType="Sender">
                  <dependency />
                </param>
              </constructor>
            </typeConfig>
          </type>

But this solution doesn't look very elegant to me.
I hope I make more sense now...
Thanks for your replies.