Currently there is an IModule interface that allows modules to be programmatically added via the Admin | Modules section (the Calendar and Update module are currently functional). The problem is these modules have to be compiled into the application otherwise there are issues that MEF is here to eliminate.
The "dynamic instantiation" of the applicable class requires that the module/assembly be loaded in memory prior to the CreateInstance statement - MEF modules must be loaded prior to the ASP.NET Page_Init(). Currently this is accomplished in the IHttpModule.Page_Init() method.
This forced me to modify the MEFContrib project so that MEF objects were composed prior to the pages Page_Init(). Since all controls are not added until after Page_Init(), reference second arrow in Figure B, this means those dynamically modules cannot have MEF Imports/Exports.
Below we see that when we hit the breakpoint in Page_Init (figure b) that we have both a reference to the IUnityContainer and MEFModule - breakpoint watch window follows:
using System;
using System.ComponentModel.Composition;
using System.Web;
using MEFContrib.Library.Web.Unity;
using Microsoft.Practices.Unity;
namespace MEFContrib.Library.Web.UI {
public class MEFHttpApplication : HttpApplication {
protected IUnityContainer Container
{
get { return HttpContext.Current
.Application.GetContainer(); }
}
protected void Application_Start(object sender, EventArgs e)
{
Container
.AddNewExtension<MEFContainerExtension>();
var catalog =
new DirectoryPartCatalog("bin", "*.dll", false);
Container
.RegisterInstance<ComposablePartCatalog>(catalog);
ApplicationStart(sender, e);
}
protected void Application_End(object sender, EventArgs e)
{
ApplicationEnd(sender, e);
Container.Dispose();
}
protected void Application_BeginRequest(
object sender, EventArgs e)
{
var catalog = Container.Resolve<ComposablePartCatalog>();
CompositionContainer compositionContainer =
new CompositionContainer(catalog);
Container.RegisterInstance<ICompositionService>(
compositionContainer);
ApplicationBeginRequest(sender, e);
}
protected void Application_EndRequest(
object sender, EventArgs e)
{
ApplicationEndRequest(sender, e);
}
protected void Application_Error(
object sender, EventArgs e)
{
ApplicationError(sender, e);
}
protected virtual void ApplicationStart(
object sender, EventArgs e) { }
protected virtual void ApplicationEnd(
object sender, EventArgs e) { }
protected virtual void ApplicationBeginRequest(
object sender, EventArgs e) { }
protected virtual void ApplicationEndRequest(
object sender, EventArgs e) { }
protected virtual void ApplicationError(
object sender, EventArgs e) { }
}
}