Ninject InSingletonScope with Web Api RC

情到浓时终转凉″ 提交于 2019-11-27 19:08:07

use

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

and don't dispose the kernel in the NinjectDependencyScope

@Remo Gloor When I run your code in InMemoryHost of WebAPI and run Integration tests everything works fine and I do have singleton. If I run WebAPI solution inside VS Cassini web server first run is successful and when I click refresh I receive exception : Error loading Ninject component ICache No such component has been registered in the kernel's component container.

If I return old code with BeginBlock it works in Cassini but IsSingleton not working anymore in integration tests.

Instead of not disposing the kernel (which will not call the internal dispose) you can simply implement your own singleton:

public static class NinjectSingletonExtension
{
    public static CustomSingletonKernelModel<T> SingletonBind<T>(this IKernel i_KernelInstance)
    {
        return new CustomSingletonKernelModel<T>(i_KernelInstance);
    }
}

public class CustomSingletonKernelModel<T>
{
    private const string k_ConstantInjectionName = "Implementation";
    private readonly IKernel _kernel;
    private T _concreteInstance;


    public CustomSingletonKernelModel(IKernel i_KernelInstance)
    {
        this._kernel = i_KernelInstance;
    }

    public IBindingInNamedWithOrOnSyntax<T> To<TImplement>(TImplement i_Constant = null) where TImplement : class, T
    {
        _kernel.Bind<T>().To<TImplement>().Named(k_ConstantInjectionName);
        var toReturn =
            _kernel.Bind<T>().ToMethod(x =>
                                       {
                                           if (i_Constant != null)
                                           {
                                               return i_Constant;
                                           }

                                           if (_concreteInstance == null)
                                           {
                                               _concreteInstance = _kernel.Get<T>(k_ConstantInjectionName);
                                           }

                                           return _concreteInstance;
                                       }).When(x => true);

        return toReturn;
    }
}

And then simply use:

i_Kernel.SingletonBind<T>().To<TImplement>();

Rather then

i_Kernel.Bind<T>().To<TImplement>().InSingletonScope();


note: although it is only matters for the first request, this implementation is not thread safe.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!