Search code examples
c#asp.net-web-apininject

Multiple Web API 2 apps in one solution, both using Ninject


I have two Web API 2 projects, ProjectA and ProjectB inside one solution.

They are independent projects. I want to use ninject in both, but these lines are causing problems.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ProjectA.App_Start.NinjectWebCommon), "Start")]

and

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ProjectB.App_Start.NinjectWebCommon), "Start")] 

Even if I have only ProjectA as the startup project, both NinjectWebCommon classes will execute. And whichever runs last (usually ProjectB) overwrites what was done by the first.

The exception:

When calling bootstrapper.Initialize(CreateKernel) in the ProjectB I get -

"Sequence contains no elements"

How can I have two projects, either of which, or both, could be startup projects in the one solution using ninject?

The Code

This is my NinjectWebCommon, it is almost identical for ProjectA and ProjectB, just the registered services differ.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ProjectA.WebApi.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(ProjectA.WebApi.App_Start.NinjectWebCommon), "Stop")]

namespace ProjectA.WebApi.App_Start
{

    public static class NinjectWebCommon
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);

                GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            var mapper = AutoMapperConfig.SetupMappings();
            kernel.Bind<IMapper>().ToConstant(mapper);

            kernel.Bind<IFoo>().To<Foo>();
        }        
    }
}

Solution

  • This seems to have been one of those unfortunate cases where Visual Studio 2015 was holding on to some old version(s) of dlls and executing the wrong code in the debugger. I am not 100% sure of this but fairly certain.

    In a new solution I created two Web API projects, added ninject to both, registered some services, set both as startup project and everything worked without a problem.

    Back in the damaged solution I noticed that that debugger was executing lines of code from classes in a project that was unloaded! I tried deleting cached versions of dlls from many places on the hard disk, but this didn't help.

    To resolve the problem Looks like my Visual Studio 2015 (Update 2) is not deleting temporary files correctly. I manually deleted files in -

    c:\Users\bryan\AppData\Local\Temp\Temporary ASP.NET Files\vs

    and

    c:\Users\bryan\AppData\Local\Temp\Temporary ASP.NET Files\root