使用Ninject与Asp.NET Web API Beta ApiController

11
我卡住了。我正在使用这里概述的方法来处理wcf web api p6 Ninject working with WCF Web API Preview 5,但是在beta版中mvc实现有很大区别。这里有一篇好文章http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver,讲述了如何构建自定义依赖项解析器,但是我想要使用相同的实现方式来处理我的mvc视图控制器...例如Ninject。我也尝试过基于文章中IoC Unity示例的一些尝试,但是还没有找到最终方法。如果可以指点我正确的方向将不胜感激。我会继续自己查找。提前致谢!

这就是我的情况。我曾经使用WebActivator引导代码,但现在我已经放弃了它,转而使用Application_Start()函数,以消除其他干扰因素。

    protected void Application_Start()
    {
        var kernel = new StandardKernel(new MyNinjectModule());
        GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
    }

我收到了以下错误:
类型“Ninject.Web.Mvc.NinjectDependencyResolver”似乎没有实现“Microsoft.Practices.ServiceLocation.IServiceLocator”。
参数名称:commonServiceLocator

找到解决方案
也许会有更加优雅的方式,但现在这个对我来说可以工作了。我也在这里添加我的自定义消息处理程序。

[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart.ApiBootstrapper), "Start")]
namespace MyApp.AppStart
{
    public class ApiBootstrapper
    {
        public static void Start()
        {
            var kernel = new StandardKernel(new MyNinjectModule());
            var resolver = new NinjectDependencyResolver(kernel);
            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(resolver.GetService, resolver.GetServices);
            GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiAuthHandler());
        }
    }
}

这是一个相当不错的解决方案:http://haacked.com/archive/2012/03/11/itrsquos-the-little-things-about-asp-net-mvc-4.aspx - Luke Belbina
如果您想要同时使用两种类型的控制器,也可以查看@Remo Gloor的软件包。您可以在github上找到它,并从nuget安装它。 - Chris Kirby
5个回答

3

2
这实际上是我尝试过的事情之一,但不幸的是没有成功。例如ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel))会产生以下错误:_Ninject.Web.Mvc.NinjectDependencyResolver似乎并未实现Microsoft.Practices.ServiceLocation.IServiceLocator_。 - Chris Kirby
最终的解决方案是使用ninjectdepencencyresolver类,我只需要在setresolver上使用另一种方法签名即可。感谢您的答案! - Chris Kirby

1

我找到了答案,并在上面更新了我的问题,附上了解决方案。解决方案本身在使用Web API依赖项解析器文章中或多或少地存在,我只是不断地为Ninject进行微调。两个答案都帮助我快速缩小了范围,所以感谢@Remo和@James。


1
你能否给出一些代码示例,展示如何在一个文件中同时编写绑定和适配器的其余部分? - Shawn Mclean
1
@ShawnMclean,不太确定是否理解您的意思。在我的解决方案中,我使用了WebActivator NuGet包来注册Ninject依赖项解析器与WebAPI(在一个派生自NinjectModule的单独类中定义我的绑定)。您也可以将相同的方法代码放入全局.asax文件的Application_Start()方法中,我只是更喜欢这种引导方法。还有一个回复提到了Phil Haack的解决方案,它基本上允许您为mvc和web api使用相同的绑定。但是,目前我更喜欢我的方法。 - Chris Kirby

0
可能听起来有些傻,但您确定已经引用了CommonServiceLocator / CommonServiceLocator.NinjectAdapter NuGet包或相关的程序集吗?您的NinjectDependencyResolver可能无法解析对IServiceLocator的引用。

我安装了这两个包,但是还是没有成功。你可以看到ninect.mvc包是如何通过一个自定义的启动器使用webactivator来进行自动装配的... 但是它必须在apicontroller请求生命周期之外,因为请求实际上并不直接发送到控制器... 而是由框架为你创建的。 - Chris Kirby
问题在于,我的代码解析成了这个方法签名http://msdn.microsoft.com/en-us/library/hh835505(v=vs.108).aspx,而我以为它使用的是这个http://msdn.microsoft.com/en-us/library/hh835218(v=vs.108).aspx。谢天谢地,有第三个选项可以避开类型问题。感谢 Hamaze 的回答! - Chris Kirby

0

相同的代码将适用于MVC和WebApi,但是由于WebApi受到MVC的启发,并且不必引用MVC程序集即可使用WebApi(反之亦然),因此两个框架之间存在相当多的代码重复。如果您想使用MVC,则依赖项将来自System.Web.Mvc,如果要使用WebApi,则将使用System.Web.Http。如果您想同时使用两者,则必须在代码中区分何时使用哪个,使用更明确的命名空间解析。

在您的情况下,您的问题是MVC先出现,而NinjectDependancyResolver类继承自System.Web.Mvc.IDependencyResolver。您需要创建一个完全相同的NinjectDependancyResolver类,而是继承自System.Web.Http.IDependencyResolver。使用此类设置您的IoC,您就可以开始了。


感谢您的回复!这基本上就是我在上面的答案中所做的,因为您描述的重复问题。但是,由于此重载存在于setresolver http://msdn.microsoft.com/en-us/library/hh834083(v=vs.108).aspx中,我能够避免创建一个实现system.web.http接口的重复ninject依赖项解析器。不过,我真的希望他们能想出更好的处理方式。我应该能够同时使用相同的依赖项解析器。 - Chris Kirby

0

我在这里找到了一个不错的解决方案here

如果您已经在使用Ninject CommonServiceLocator / Bootstrapper,那么这很容易:

private static IKernel CreateKernel() {
   var kernel = new StandardKernel();
   RegisterServices(kernel);

   GlobalConfiguration.Configuration.ServiceResolver
      .SetResolver(new NinjectServiceLocator(kernel));
   return kernel; 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接