【问题标题】:WebAPI with Ninject带有 Ninject 的 WebAPI
【发布时间】:2012-10-21 09:17:52
【问题描述】:

我遇到了麻烦,让 Ninject 和 WebAPI.All 一起工作。我会更具体:
首先,我使用了 WebApi.All 包,看起来它对我来说很好用。
其次,我在Global.asax下一行添加到RegisterRoutes

routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));

所以最后的结果是:


public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

}

一切似乎都很好,但是当我尝试将用户重定向到特定操作时,例如:

return RedirectToAction("Index", "Home");

浏览器中的网址是localhost:789/api/contacts?action=Index&controller=Home 这不好。我在RegisterRoute 中换了行,现在看起来:


public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
            routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));
            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

        }

现在重定向工作正常,但是当我尝试访问我的 API 操作时,我收到错误消息告诉我 Ninject couldn't return controller "api" 这绝对合乎逻辑,我没有这样的控制器。

我确实搜索了一些如何使 Ninject 与 WebApi 一起工作的信息,但我发现的所有内容都仅适用于 MVC4 或 .Net 4.5。由于技术问题,我无法将我的项目转移到新平台,所以我需要为这个版本找到一个可行的解决方案。

This answer 看起来像是一个可行的解决方案,但是当我尝试启动项目时,我遇到了编译器错误

CreateInstance = (serviceType, context, request) => kernel.Get(serviceType);

告诉我:

System.Net.Http.HttpRequestMessage is defined in an assembly that is not referenced

以及关于在程序集中添加引用

System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

我不知道下一步该做什么,我在 .NET 4 和 MVC3 上找不到任何关于 ninject 和 webapi 的有用信息。任何帮助将不胜感激。

【问题讨论】:

  • 首先,当它是 WCF WebApi 的一部分时,其他帖子与 WebApi 的预发布版本相关(现在它被移动到 MVC4 WebApi 更改其整个模型)..您正在使用最终版本WebApi,对吧?
  • 是的,我正在使用当前版本:AspNetWebApi 4.0.20710.0
  • 你确定吗?因为 ServiceRoute 是 System.ServiceModel 的一部分,它是 WCF 的一部分 .. 你确定没有混淆吗?
  • 不,我真的不确定。我已经多次混合 dll 和包。感谢下面的回答,我设法解决了很多问题。
  • 是的,我也遇到过同样的情况。 Darin 的解决方案应该可以工作,但只需摆脱 System.ServiceModel DLL 并清理您的解决方案,否则您会遇到混淆,这会困扰您,您仍然可以使用 wcf 中不适用的东西(如 UriTemplates、ServiceOperation 属性和就像你为新 ServiceRoute 设置的这条线).. 这很痛苦,但值得早点而不是晚点做

标签: c# asp.net-mvc-3 .net-4.0 ninject


【解决方案1】:

以下是我为您编译的几个步骤,可以帮助您入门:

  1. 使用 Internet 模板创建一个新的 ASP.NET MVC 3 项目
  2. 安装以下 2 个 NuGet:Microsoft.AspNet.WebApiNinject.MVC3
  3. 定义一个接口:

    public interface IRepository
    {
        string GetData();
    }
    
  4. 还有一个实现:

    public class InMemoryRepository : IRepository
    {
        public string GetData()
        {
            return "this is the data";
        }
    }
    
  5. 添加 API 控制器:

    public class ValuesController : ApiController
    {
        private readonly IRepository _repo;
        public ValuesController(IRepository repo)
        {
            _repo = repo;
        }
    
        public string Get()
        {
            return _repo.GetData();
        }
    }
    
  6. 在您的Application_Start 中注册一个 API 路由:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        GlobalConfiguration.Configuration.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    
        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
    
  7. 使用 Ninject 添加自定义 Web API 依赖解析器:

    public class LocalNinjectDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
    {
        private readonly IKernel _kernel;
    
        public LocalNinjectDependencyResolver(IKernel kernel)
        {
            _kernel = kernel;
        }
    
        public System.Web.Http.Dependencies.IDependencyScope BeginScope()
        {
            return this;
        }
    
        public object GetService(Type serviceType)
        {
            return _kernel.TryGet(serviceType);
        }
    
        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _kernel.GetAll(serviceType);
            }
            catch (Exception)
            {
                return new List<object>();
            }
        }
    
        public void Dispose()
        {
        }
    }
    
  8. Create方法(~/App_Start/NinjectWebCommon.cs)中注册自定义依赖解析器:

    /// <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 LocalNinjectDependencyResolver(kernel); 
        return kernel;
    }
    
  9. RegisterServices方法内配置内核(~/App_Start/NinjectWebCommon.cs):

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IRepository>().To<InMemoryRepository>();
    }        
    
  10. 运行应用程序并导航到/api/values

【讨论】:

  • 谢谢。它确实适用于单独的项目。现在我正在尝试将所有这些代码导入我的工作项目中。只有一个问题:我应该对我的 NinjectControllerFactory 做些什么吗?我应该离开它,还是使用 NinjectWebCommon 来代替存储库绑定?
  • 您简单易懂的说明帮助很大,谢谢!
  • LocalNinjectDependencyResolver 是解决我问题的关键。谢谢!
猜你喜欢
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 2013-08-08
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多