Is it possible to configure ms Unity container from an xml document and NOT from a file?

Apr 7, 2009 at 10:42 PM
I want to manage the configuration in sql and read the data into an xmldocument and then populate the container.

THX.
Apr 16, 2009 at 11:24 PM
The Unity configuration file support is built on top of the .NET System.Configuration namespace. If you can figure out how to get it to read from an XmlDocument, then you can do this. I have no idea how you do that, though.

There's nothing special about our configuration schema - everything is turned into calls on the public API. So it's not hard if you wanted to come up with your own configuration system that reads from a database and makes similar calls on the container.
Apr 16, 2009 at 11:30 PM
Edited Apr 16, 2009 at 11:31 PM

Thank you for replying, I ended up doing for now, generating this dynamically as XElement shamefully saving this as a temp file and reading from file into the container. I have found out that the  System.Configuration  does not support reading in memory xml document.

Maybe in a refactoring cycle I will write parser to the xml in memory and configure the container with the OM.

Maybe it's a good v.5 improvement for Unity.

Cheers, Gil.

 

Dec 22, 2009 at 4:49 PM
Edited Dec 22, 2009 at 4:49 PM
gilstav wrote:

Thank you for replying, I ended up doing for now, generating this dynamically as XElement shamefully saving this as a temp file and reading from file into the container. I have found out that the  System.Configuration  does not support reading in memory xml document.

Maybe in a refactoring cycle I will write parser to the xml in memory and configure the container with the OM.

Maybe it's a good v.5 improvement for Unity.

Cheers, Gil.

 

Yeah it still sucks that for some reason the System.Configuration assembly still assumes that everyone likes config files. A Hugh Smeg-Up IMHO considering that everything ultimately boils down to an XmlReader object so why the hell not allow me to supply it manually? My only thinking is that too many peeps on the BCL team think that obviously with such power we'll run off and and go crazy and shoot ourselves in the foot [roll eyes].

One of the sleazy ways I believe you can get around this is actually by subclassing the UnityConfigurationSection type (thank goodness it wasn't sealed and has a visible constructor). This allows you access to the protected method DeserializeSection() on the ConfigurationSection class. It would appear that you should be able to provide a public operation wherein you can supply the XmlReader (you need to have a few small requirements met such as supplying an XmlReader initially positioned at an XmlElement but that's minor) and have it call into the protected operations for you. I see this probably best as being a static factory method to return a UnityConfigurationSection type. From there you should be able to leverage the Configure(IUnityContainer) method on the UnityContainerElement you have deserialized. Some warnings I should point out is that this will not return the same instance of the UnityConfigurationSection class as you get from the Configuration subsystem so treat it as read only or you're going to have a bad day. If you wanted to "merge" these newly deserialized configuration elements you should be able to add them individually to the UnityContainerElementCollection you get back from the configuration manager. Fortunately the int32 indexer is get/set-able. I personally haven't tried this process out on Unity but have haxx0red my way into other libraries from P&P in a similar fashion so the theory is sound.

It should be pointed out this will ONLY work on the core CLR and not in SL as there's NO CONFIGURATION SUBSYSTEM present in that version.

The P&P team really needs to take a look at the way the Castle Team handles this type of situation quite elegantly. They have the entire concept of an IResource which can simply be anything you want. By default they have support for manually supplied content as well as configuration file derived content. It's not rocket science, just good design and logical support for proper testing practices (such as avoiding the testing anti pattern of XML config file in test harness == EPIC FAIL).

Hope this helps out!

 

-jz

Jan 6, 2010 at 10:22 AM
ctavares wrote:
The Unity configuration file support is built on top of the .NET System.Configuration namespace. If you can figure out how to get it to read from an XmlDocument, then you can do this. I have no idea how you do that, though.

There's nothing special about our configuration schema - everything is turned into calls on the public API. So it's not hard if you wanted to come up with your own configuration system that reads from a database and makes similar calls on the container.

Hi,

I saw that you managed to work round the problem, but I thought I'd post here anyway with an example of how to read a different configuration file; just incase someone finds it useful.

I have a project that uses Unity with Mono on Linux. As part of this project the main process could run mulitple times with different configurations so I needed to take in the configuration file on the command line. As part or the UnityContainer creation this is what I did:

        protected override IUnityContainer CreateContainer()
        {
            Microsoft.Practices.Unity.IUnityContainer container = base.CreateContainer();

            ConfigurationSection configSection = null;
            if (this.configFilename != string.Empty)
            {
                ExeConfigurationFileMap mappedExeConfig = new ExeConfigurationFileMap();
                mappedExeConfig.ExeConfigFilename = this.configFilename;
                Configuration alternateConfig = ConfigurationManager.OpenMappedExeConfiguration(mappedExeConfig, ConfigurationUserLevel.None);
                configSection = alternateConfig.GetSection("unity");
            }
            else
            {
                configSection = (ConfigurationSection)ConfigurationManager.GetSection("unity");
            }

            UnityConfigurationSection section = (UnityConfigurationSection)configSection;
            section.Containers.Default.Configure(container);

            return container;
        }

As you can see the trick is to use ExeConfigurationFileMap. I hope this helps.

Regards.