【问题标题】:Ninject working with WCF Web API Preview 5Ninject 使用 WCF Web API Preview 5
【发布时间】:2011-09-29 19:19:58
【问题描述】:

谁能指出我让 Ninject 使用 WCF Web API Preview 5 的正确方向?我在我的 ASP.NET MVC 3 项目以及另一个使用 Ninject.Extensions.Wcf 库的内部 WCF 服务中成功启动并运行了它。但是,在创建新的 MVC 3 项目并从 NuGet 获取 WebApi.All 库时,我无法让它工作。

我查看了此 stackoverflow 帖子 Setting up Ninject with the new WCF Web API,但无法使其正常工作,我认为这可能与最新版本中的一些更改有关。

我也不确定除了主要的 Ninject 库之外还可以引用哪些 Ninject 库。我是否使用 Ninject.MVC3、Ninject.Extensions.Wcf。

对此的任何帮助将不胜感激。

****更新**

我使用的代码来自上述问题的答案。我在它自己的类文件中有这个。

   public class NinjectResourceFactory : IResourceFactory
    {
        private readonly IKernel _kernel;

        public NinjectResourceFactory(IKernel kernel)
        {
            _kernel = kernel;
        }

        public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
        {
            return _kernel.Get(serviceType);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object service)
        {
            // no op
        }
    }

我的 global.asax 中有这个:

var configuration = HttpConfiguration.Create().SetResourceFactory(new NinjectResourceFactory());
RouteTable.Routes.MapServiceRoute<myResource>("resource", configuration);

我遇到的问题是 IResourceFactory 接口无法识别并且 HttpConfiguration.Create() 不再存在,因此我需要设置 SetResourceFactory 一些我尝试使用 HttpConfiguration().CreateInstance 的其他方式方法但没有快乐。

【问题讨论】:

  • @Alexander 已按要求发布了包含代码的更新。

标签: ninject wcf-web-api


【解决方案1】:

以下是我使用 Ninject 和 WebApi 编写的代码,它可以正常工作。 创建一个继承自 WebApiConfiguration 的类

public class NinjectWebApiConfiguration : WebApiConfiguration {
    private IKernel kernel = new StandardKernel();

    public NinjectWebApiConfiguration() {
        AddBindings();
        CreateInstance = (serviceType, context, request) => kernel.Get(serviceType);
    }

    private void AddBindings() {
        kernel.Bind<IProductRepository>().To<MockProductRepository>();
    }

}

并在 RegisterRoutes 中使用 NinjectWebApiConfiguration

public static void RegisterRoutes(RouteCollection routes) {

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    var config = new NinjectWebApiConfiguration() { 
        EnableTestClient = true
    };

    routes.MapServiceRoute<ContactsApi>("api/contacts", config);
}

【讨论】:

  • 我使用这种方法让 Ninject 绑定使用 WebApi 发布版本与 HttpSelfHostServer 一起工作。 CreateInstance 方法替换为 DependencyResolver = new NinjectDependencyResolver(kernel);
【解决方案2】:

在 P5 中,您必须从 WebApiConfiguration 派生并使用派生的配置:

public class NinjectConfiguration : WebApiConfiguration
    {
        public NinjectConfiguration(IKernel kernel)
        {
            CreateInstance((t, i, m) =>
            {
                return kernel.Get(t);
            }); 
        }
    }

【讨论】:

  • 谢谢 Alexander,但是 SetServiceInstanceProvider 是从哪里形成的,因为 VS 说它无法解决它?我错过了命名空间吗?我的项目是否需要 MVC/WCF ninject 扩展。我创建了一个名为 NinjectConfiguration 的新类文件并添加了您提供的代码。另外,我将在什么时候加载我的 Ninject Serivce 模块。在我的一个标准 WCF 服务中,我这样称呼它: IKernel kernel = new StandardKernel(new NinjectServiceModule());非常感谢。
  • 对不起,我的错误。我指的是 CodePlex 的错误版本的 Web API。它现在称为 CreateInstance - 更新了上面的代码。
【解决方案3】:

这里的问题有很好的答案,但我想向您展示默认 WebApi 配置的方式:

    protected void Application_Start(object sender, EventArgs e) {

        RouteTable.Routes.SetDefaultHttpConfiguration(new Microsoft.ApplicationServer.Http.WebApiConfiguration() { 
            CreateInstance = (serviceType, context, request) => GetKernel().Get(serviceType)
        });

        RouteTable.Routes.MapServiceRoute<People.PeopleApi>("Api/People");
    }

    private IKernel GetKernel() { 

        IKernel kernel = new StandardKernel();

        kernel.Bind<People.Infrastructure.IPeopleRepository>().
            To<People.Models.PeopleRepository>();

        return kernel;
    }

下面的博客文章稍微介绍了 WCF Web API 上的 Ninject 集成:

http://www.tugberkugurlu.com/archive/introduction-to-wcf-web-api-new-rest-face-ofnet

【讨论】:

  • 这个解决方案看起来不错;关键是使用 HttpConfiguration 的 CreateInstance 委托属性(或派生的 WebApiConfiguration,就像您正在使用的那样)。但是,我认为您的解决方案将更新一个 Ninject 内核并将每个请求的绑定设置为该服务类型!可能更好的是新建 Ninject 并在 Application_Start 中设置绑定,将引用存储在私有静态字段中,使用它来创建服务类型,并在 Application_End 中处理它。
  • @AndrewWebb 感谢您的建议。你能提供一个你试图解释的样本吗?你可以评论我的帖子:tugberkugurlu.com/archive/… 或这里。
  • 我尝试在新答案中添加完整示例,但格式很垃圾。无论如何,在 Global.asax.cs 的类中,添加这个字段:private static IKernel _ninKernel;在 Application_Start 中新建一个标准内核并将 ref 存储在该字段中,并设置您的绑定。在Application_End中处理这个内核对象:- _ninKernel.Dispose();设置 Http 配置时使用此字段更新服务实例:- CreateInstance = (serviceType, context, request) => _ninKernel.Get (serviceType),
  • 对我有用的只是将 NinjectWebApiConfiguration 类的一个实例传递给 RouteTable.Routes.SetDefaultHttpConfiguration():RouteTable.Routes.SetDefaultHttpConfiguration(new NinjectWebApiConfiguration()); 不需要 GetKernel 函数,它每次都会创建一个新的 StandardKernel 对象与路由匹配的url到达。
  • @dfjacobs 我通常也这样做,但为了简单起见,我举了一个最简单的例子。
猜你喜欢
  • 2011-08-19
  • 1970-01-01
  • 2023-03-10
  • 2011-03-28
  • 2015-04-17
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
相关资源
最近更新 更多