Conditional Load Of Services

May 29, 2008 at 8:03 AM
Edited May 29, 2008 at 8:16 AM

Hi,

 

I hope you can help?  Can you conditionally load services with the same interface. 

 

For example two separate services exist which implement the same interface, when compiled one goes into the bin folder of the web site another goes into a sub directory of the bin folder.  Under normal loading the service in the web site bin folder is loaded and used, then when needed the original service is removed and the one existing in the sub directory is loaded as the concrete implementation.

The above scenario is only an example the exact details can change to fit, as long as I can unload one concrete implementation for another at will. 


I hope this makes sense, I think my answer lies in the object builder part of the framework but it’s not coming to light yet.

 

Thank you for any help you can offer.

 

Christopher Myhill

Coordinator
May 29, 2008 at 11:21 PM
Complete unloading of a type is not supported (without killing and restarting an app domain).  However, I think the rest of your scenario should work.  Here's how and why:

The Type Mapping implementation we use is very simple: You can map an interface to a concrete type for the container.  You can set things up so all your modules use an interface (say ILogger), and via the type registration have Module1 use a DatabaseLogger and have Module2 use a TraceLogger.  I would do this in each Module's ModuleInitializer in the Load method by calling container.RegisterTypeMapping<DatabaseLogger, ILogger>(); .  Via a small bit of work with the Load method in the ModuleInitializer for a module, this mapping could be read from config and done via reflection without a reference to the derived type.  The type mapping for in interface could be changed on the fly (at least the API supports the call to overwrite a mapping), however I have not tried that, but it should work.

I hope that helps,
Michael Puleio - patterns & practices
Blog -- http://blogs.msdn.com/mpuleio
Jun 12, 2008 at 6:36 PM

The way I have tried to load services dynamically is as follows(of course, the credit goes to Michael - you gave me the pointer about it long time ago)

  [InjectionConstructor]
        public TesController([ServiceDependency] ICompositionContainer cContainer)
        {
            _cContainter = cContainer;
            
            //Remove the default implementation of ITestDAO from the module container.
            if (_cContainter.Services.Get<ITestDAO>() != null)
            {
                _cContainter.Services.Remove<ITestDAO>();
            }

            //Based on current moduleType value , inject the corresponding concreate class into the container.
            ModuleType module = GetModuleType();

            switch (module)
            {
                case ModuleType.Test:
                    _cContainter.Services.AddNew<TestDAO, ITestDAO>();
                    break;
                case ModuleType.Tes1:
                    _cContainter.Services.AddNew<Test1DAO, ITestDAO>();
                    break;
                case ModuleType.Test2:
                    _cContainter.Services.AddNew<Test2DAO, ITestDAO>();
                    break;
                default:
                    _cContainter.Services.AddNew<TestDAO, ITestDAO>();
                    break;
            }

        }

}

Hope it helps!

Chandra