我目前正在开展一个项目,我将开发预编译的视图,并将成为我无法控制的外部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应用程序中初始化(假设他们正在使用这种方法)。所以我不需要做所有初始化所有我需要做的就是用当前的Kernal注册我的依赖项。
类似的东西:
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%这是正确的解决方案,但似乎有用吗?
答案 0 :(得分:3)
我知道你在Global.asax
这样的地方添加绑定
不一定。您最近是否在新的MVC应用程序中安装了Ninject.MVC3
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)
{
}
}
}
请注意WebActivator的PreApplicationStartMethod
和ApplicationShutdownMethodAttribute
程序集属性,这些属性允许您插入在ASP.NET应用程序分别启动和关闭时执行的代码。
好的,现在只需将此代码放入您的库中,并使用RegisterServices
方法配置您的内核。