NInject Load modules after the runtime is done

2019-08-18 01:53发布

问题:

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.