The main idea of the Unity Framework is to give us the ability to quickly replace different parts of big application without having to recompile or re-factor our code. Ideally that means adding another assembly to the bin folder or GAC, and certainly that is the right way to add new providers or class implementations. But sometimes you may want to quickly script a provider in order to test a new idea on your staging server or debug a problem without having to deal with all the hassle of adding a new assembly.
Well, the first idea that comes to my mind is to use a class defined in the App_Code folder. The class will be recompiled each time there is a change in the source file so this seems as a perfect candidate for a quick test. But there is one problem. The assemblies for the classes in App_Code folder are dynamic and so we don't know what their name is, and because of that we cannot set the right class reference in the configuration file.
Here I want to propose one solution of that problem. Instead of configuring your container with code that is something like this:
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
if (section != null)
{
var current = section.Containers["WebApp"];
if (current != null)
{
current.Configure(_container);
}
}
You can use this code:
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
if (section != null)
{
var current = section.Containers["WebApp"];
if (current != null)
{
Configure(current, _container);
}
}
And the Configure method follows:
private static void Configure(UnityContainerElement current, IUnityContainer container)
{
foreach (UnityContainerExtensionElement extension in current.Extensions)
{
extension.Configure(container);
}
foreach (UnityTypeElement typeElement in current.Types)
{
var name = typeElement.MapToName.Replace(" ", "").Trim();
if (name.EndsWith(",App_Code"))
{
name = name.Replace(",App_Code", "");
var t = BuildManager.GetType(name, true);
if(t != null)
{
container.RegisterType(typeElement.Type, t, typeElement.Lifetime.CreateLifetimeManager());
}
}
else
{
typeElement.Configure(container);
}
}
foreach (UnityInstanceElement instanceElement in current.Instances)
{
instanceElement.Configure(container);
}
foreach (IContainerConfigurationCommand command in current.ExtensionConfig)
{
command.Configure(container);
}
}
This code should be placed in a static constructor of a class so it gets called each time the application is reset, and the
application will be reset anytime you make a change to a class in the App_Config folder.
If you are concerned about the loss of session you can check the following blog entry that offers one possible solution to that
http://blog.bodurov.com/Session-Recovery.
Of course there are other solutions you may choose instead.
You will notice that I use System.Web.Compilation.BuildManager to retrieve the type of the class with source located in the App_Config folder.
Now this class must be declared in the web.config so to end with “,App_Code”, for example:
<type type="IInterface" mapTo="WebApp.App_Code.ClassName, App_Code" ...
And once again I want to emphasize that I do not encourage to use the App_Code folder for your providers and stable code. For that you should use separate assemblies. The solution I propose is only for quick tests, debugging or experiments.