asp.net-mvc - 静态容器已经有一个与之关联的内核!当部署到虚拟应用程序时

标签 asp.net-mvc azure dependency-injection asp.net-web-api ninject

我正在尝试让 ninject 在生产环境中工作。

我的解决方案由以下项目组成

  • 数据
  • 型号
  • WebApi2
  • MVC5

一切都作为 webrole 部署到 azure。

我的 api 设置为 mvc 站点下的虚拟应用程序。我的应用程序是一个 Multi-Tenancy 应用程序,因此我希望用户能够以与应用程序相同的方式访问 api,例如

https://theirbusiness.mydomain.com/api/api-call

对于我的本地开发,我使用 2 个站点而不是虚拟应用程序,因为我在尝试与 azure 进行斗争以使其在本地运行时遇到了许多问题。因此,我的服务定义为本地工作创建了 2 个站点。在本地我没有问题

我的网站和 API 都引用了 ninject,但我的数据和模型没有。

当我部署并尝试访问 api 时,出现错误

The static container already has a kernel associated with it!

该网站没有任何问题,它似乎只是 api 的问题。我使用 nuget 添加了 ninject

堆栈跟踪

[NotSupportedException: The static container already has a kernel associated with it!] Ninject.Web.KernelContainer.set_Kernel(IKernel value) +193 Ninject.Web.NinjectWebHttpApplicationPlugin.Start() +82 Ninject.Web.Common.Bootstrapper.b__0(INinjectHttpApplicationPlugin c) +89 Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable1 series, Action1 action) +283 Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) +410 MyNameSpace.Application.Api.App_Start.NinjectWebCommon.Start() +362

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +417
 System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +35
 WebActivator.BaseActivationMethodAttribute.InvokeMethod() +761
 WebActivator.ActivationManager.RunActivationMethods() +1177
 WebActivator.ActivationManager.RunPreStartMethods() +75
 WebActivator.ActivationManager.Run() +97

[InvalidOperationException: The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 methods, Func`1 setHostingEnvironmentCultures) +888
System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) +137
System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded) +160
System.Web.Compilation.BuildManager.ExecutePreAppStart() +142
System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +838

[HttpException (0x80004005): The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +452
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +99
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +1017

我的 NinjectWebCommon.cs

using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using MyNameSpace.Application.Api.App_Start;
using MyNameSpace.Application.Api.Interface;
using MyNameSpace.Application.Api.Repository;

[assembly: WebActivator.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]


namespace MyNameSpace.Application.Api.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();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
                  kernel.Bind<IBusinessRepository>().ToConstant(new BusinessRepository());
                  kernel.Bind<IEmployeeRepository>().ToConstant(new EmployeeRepository());

    }
}

}

我的依赖范围

public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;

internal NinjectDependencyScope(IResolutionRoot resolver)
{
    Contract.Assert(resolver != null);

    this.resolver = resolver;
}

public void Dispose()
{
    IDisposable disposable = resolver as IDisposable;
    if (disposable != null)
        disposable.Dispose();

    resolver = null;
}

public object GetService(Type serviceType)
{
    if (resolver == null)
        throw new ObjectDisposedException("this", "This scope has already been disposed");

    return resolver.TryGet(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
    if (resolver == null)
        throw new ObjectDisposedException("this", "This scope has already been disposed");

    return resolver.GetAll(serviceType);
}
}

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;

public NinjectDependencyResolver(IKernel kernel)
    : base(kernel)
{
    this.kernel = kernel;
}

public IDependencyScope BeginScope()
{
    return new NinjectDependencyScope(kernel.BeginBlock());
}
}

如果我在本地调试。将 api 设置为我的启动项目,我可以在部署应用程序后立即运行该应用程序,没有任何问题,但它失败了。我远程登录到 azure webrole 并删除了 mvc 站点,仅保留 api 站点作为根站点。这对解决问题没有帮助。

我的上述设置看起来有问题吗?

最佳答案

我相信你的问题和我的一样。问题是您的生产环境中存在重复的 Ninject.dll 或来自 Ninject 的任何 dll。在再次部署之前,您必须清理所有现有文件。在这里查看我的解决方案:

The static container already has a kernel associated with it

关于asp.net-mvc - 静态容器已经有一个与之关联的内核!当部署到虚拟应用程序时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19625449/

相关文章:

在另一个 Service 中 Spring 注入(inject) Service

html - 中心导航栏 (ASP.NET MVC)

asp.net-mvc - Windows Server 2008 上的 ASP.Net MVC 应用程序使用静态文件处理程序

asp.net-mvc - ActionFilter 的 Order 属性,从最低到最高,反之亦然?

Azure 服务总线主题订阅到期日期

PHP 依赖注入(inject) - Pimple 等。 - 为什么使用关联数组与 getter?

Java - 使用注解自动实现服务定位器模式

c# - 将 ExecuteReader 转换为 XML HTTP 响应

azure - Azure Blob 存储是否支持服务器端加密

asp.net-mvc - Azure 将 blob 下载到用户计算机