Ninject InSingletonScope 与 Web Api RC [英] Ninject InSingletonScope with Web Api RC

查看:26
本文介绍了Ninject InSingletonScope 与 Web Api RC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Ninject 的 InSingletonScope 绑定和 Web Api RC 时遇到了一些困难.无论我如何创建绑定,看起来 Web Api 可能正在处理范围/生命周期而不是 Ninject.

I'm having some difficulty using Ninject's InSingletonScope binding with Web Api RC. No matter how I create my binding, it looks like perhaps Web Api is handling scope/lifetime instead of Ninject.

我尝试了一些连接 Ninject 的变体.最常见的与这里的答案相同:ASP.NET Web API 与 ninject 的绑定

I've tried a few variations on wiring up Ninject. The most common is identical to the answer here: ASP.NET Web API binding with ninject

我也试过这个版本:http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/

在这两种情况下,我实际上都是在创建一个开箱即用的 Web Api 项目,然后按照任一帖子中的描述添加 Ninject 包.最后,我添加了 Resolver 和 Scope 类,例如 StackOverflow 版本的这个类:

In both, I'm literally creating an out of the box Web Api project, then adding the Ninject packages as described in either post. Finally, I'm adding the Resolver and Scope classes, such as this for the StackOverflow version:

public class NinjectDependencyScope : IDependencyScope
{
    private IResolutionRoot resolver;

    internal NinjectDependencyScope(IResolutionRoot resolver)
    {
        Contract.Assert(resolver != null);

        this.resolver = resolver;
    }

    public void Dispose()
    {
        IDisposable disposable = resolver as IDisposable;
        if (disposable != null)
            disposable.Dispose();

        resolver = null;
    }
    public object GetService(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");
        return resolver.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (resolver == null)
            throw new ObjectDisposedException("this", "This scope has already been disposed");
        return resolver.GetAll(serviceType);
    }
}

和:

 public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
    private IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        this.kernel = kernel;
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectDependencyScope(kernel.BeginBlock());
    }
}

然后,NinjectWebCommon 看起来像这样:

Then, NinjectWebCommon looks like this:

using System.Web.Http;
using MvcApplication2.Controllers;

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

namespace MvcApplication2.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>();

            // Register Dependencies
            RegisterServices(kernel);

            // Set Web API Resolver
            GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(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)
        {
            kernel.Bind<ILogger>().To<Logger>().InSingletonScope();
        }
    }
}

ILogger 和 Logger 对象没有做任何事情,但可以说明问题.Logger 执行 Debug.Writeline 以便我可以看到它何时被实例化.页面的每次刷新都表明它正在每次调用刷新,而不是我希望的单例.这是一个使用 Logger 的控制器:

The ILogger and Logger objects don't do anything, but illustrate the issue. Logger does Debug.Writeline so that I can see when it was instantiated. And each refresh of the page shows that it's being refreshed per call, rather than the singleton I'd hoped for. Here is a controller using the Logger:

public class ValuesController : ApiController
{
    private readonly ILogger _logger;
    public ValuesController(ILogger logger)
    {
        _logger = logger;
        _logger.Log("Logger created at " + System.DateTime.Now.ToLongTimeString());
    }
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }
    // POST api/values
    public void Post(string value)
    {
    }
    // PUT api/values/5
    public void Put(int id, string value)
    {
    }
    // DELETE api/values/5
    public void Delete(int id)
    {
    }
}

当我把trace信息放入内核的创建中时,似乎显示内核只创建了一次.所以……我没有看到什么?为什么单例没有持久化?

When I put trace information into the creation of the kernel, it seems to show that the kernel is only created once. So... what am I not seeing? Why isn't the singleton persisted?

推荐答案

使用

public IDependencyScope BeginScope()
{
    return new NinjectDependencyScope(kernel);
}

并且不要在NinjectDependencyScope

这篇关于Ninject InSingletonScope 与 Web Api RC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆