I would like to load module in asp.net mvc dynamically after the runtime is realized. So I follow many tutorials and different ways to do it. Finally I found the solution from http://www.squarewidget.com/pluggable-architecture-in-asp.net-mvc-4. I follow the code described and I try to load the assembly later. I use the class NInjectWebCommon.cs All lib have been loaded from the bin path project. I add the plugin.dll : it's the module and when I try to browse the index page from the module it works.
private static void RegisterServices(IKernel kernel)
{
//Func http://msdn.microsoft.com/fr-fr/library/vstudio/bb549151(v=vs.110).aspx
//Action
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin");
kernel.Bind(a => a.FromAssembliesInPath(path).SelectAllClasses().BindDefaultInterface());
}
I try to remove the plugin.dll and add an action on the home controller permitting to call one more time RegisterServices, a second method a little bit modified permitting to load the dll from another bin => bin2 where I put plugin.dll.
public static void RegisterServicesSpecific()
{
//Func http://msdn.microsoft.com/fr-fr/library/vstudio/bb549151(v=vs.110).aspx
//Action
var path = @"C:\temp\PluginASPNET\PlugMvc4\PlugMvc4\bin2";
kernel.Bind(a => a.FromAssembliesInPath(path).SelectAllClasses().BindDefaultInterface());
}
I notice the method is called, but I notice the plugin is not really loaded because my break point related to the AreaRegistration is not called. I'm new in ninject.
[20130112]
I continu to search, I add the method CallMeAfterAppStart and try to load later the dll from the bin3. I obtain the sequence doesn't contain elements....
[assembly: WebActivator.PreApplicationStartMethod(typeof(PlugMvc4.App_Start.NinjectWebCommon), "Start")]
//[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(PlugMvc4.App_Start.NinjectWebCommon), "Stop")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(PlugMvc4.App_Start.NinjectWebCommon), "CallMeAfterAppStart")]
namespace PlugMvc4.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using System.IO;
using Ninject.Extensions.Conventions;
using Ninject.Extensions.Conventions.Syntax;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
private static StandardKernel kernel = new StandardKernel();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateTest);
}
private static IKernel CreateTest()
{
kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
//var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin3");
//kernel.Bind(a => a.FromAssembliesInPath(path).SelectAllClasses().BindDefaultInterface());
return kernel;
}
public static void CallMeAfterAppStart()
{
bootstrapper.Initialize(CallMeAfterAppStart2);
}
private static IKernel CallMeAfterAppStart2()
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin3");
kernel.Bind(a => a.FromAssembliesInPath(path).SelectAllClasses().BindDefaultInterface());
return kernel;
}
[20140121] I add the source code from ninject and Ninject.Extensions.Conventions and attempt to debug.
I notice the instruction [assembly: WebActivator.PostApplicationStartMethod(typeof(PlugMvc4.App_Start.NinjectWebCommon), "CallMeAfterAppStart")] is called and I can see the dll from the plugin is found by to call a=>FromAssembliesInPath. So I can notice Plugin.dll is loaded in the appdomain. But after I can't have access to the page, it seems the dll is loaded but ASP.NET MVC doesn't know how to work with it. I try to move AreaRegistration.RegisterAllAreas(); to launch outside the global.asax, no effect.
Can you help me.