1

我目前正在开发一个项目,我将开发将被预编译的视图,并将成为我无法控制的外部 MVC 3.0 Web 解决方案的一部分。

我的部分要求是我需要访问底层数据库才能获取一些数据。我想根据需要使用 Ninject(我被告知这是外部解决方案使用的)将数据库实例注入我的控制器。

我知道您在 Global.asax 这样的地方添加了绑定,但是我无权访问它,因为这是我无法控制的外部解决方案的一部分。

无论如何,我是否可以在包含预编译视图等的项目中创建此依赖注入,并确保在外部项目加载我们的控制器时解决它?

如果这太模糊,请告诉我,我会尝试提供更多信息。

编辑:最初在接受达林的建议后,我得到了以下例外:

System.InvalidOperationException crossed a native/managed boundary
  Message=Sequence contains no elements
  Source=System.Core
  StackTrace:
       at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
       at Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:line 53
       at Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:line 52
       at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:line 32
       at Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:line 52
       at MyApp.App_Start.NinjectWebCommon.Start() in C:\App\NinjectWebCommon.cs:line 28
  InnerException:

然而,考虑到这一点,引导程序应该已经在我们的外部 MVC 应用程序中初始化(假设他们正在使用我猜的这种方法)。所以我不需要做所有的初始化,我需要做的就是用当前的内核注册我的依赖项。

就像是:

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

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start()
    {
        RegisterServices(bootstrapper.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<IDataContext>().To<ApiDataContext>();
    } 
}

当这样做时,我现在得到注入的项目。但是我不是 100% 这是正确的解决方案,但它似乎有效?

4

1 回答 1

3

我知道您在 Global.asax 这样的地方添加了绑定

不必要。您最近是否Ninject.MVC3在新的 MVC 应用程序中安装了 NuGet?如果你还没有,我现在邀请你这样做。只需使用 Visual Studio 中的 Internet 应用程序模板创建一个新的 ASP.NET MVC 3 项目并安装此 NuGet。准备好?

完成此操作后,您会注意到在App_Start项目的文件夹中创建了 NuGet 包。一点都没碰Global.asax。现在让我们检查NinjectWebCommon.cs添加到此文件夹中的文件的内容:

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

namespace MvcApplication1.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    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);
            return kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
        }        
    }
}

请注意 WebActivatorPreApplicationStartMethodApplicationShutdownMethodAttribute程序集的属性,它们允许您插入分别在 ASP.NET 应用程序启动和关闭时执行的代码。

好的,现在只需将此代码放入您的库中并在RegisterServices方法中配置您的内核。

于 2012-07-10T06:25:48.847 回答