2012-10-08 12 views
9

के रूप में काम नहीं कर रहा है, मैं अपने वेब एपीआई एप्लिकेशन के साथ ninject mvc3 प्लगइन का उपयोग कर रहा हूं। मैं एक बाध्यकारी है कि तरह लग रहा है:सिंगलटन स्कोप बाइंडिंग

kernel.Bind<IFoo>().To<Foo>().InSingletonScope();

यह मेरी व्याख्या यह है कि kernal Foo के ठीक एक उदाहरण बना सकते हैं और यह उचित रूप से पुन: उपयोग होगा। Foo के निर्माता में ब्रेकपॉइंट डालने से, मैं स्पष्ट रूप से देख सकता हूं कि इसे प्रति अनुरोध एक बार बुलाया जा रहा है, और मैं क्यों समझा नहीं सकता।

मेरी केवल अनुमान है कि किसी भी तरह एक नया कर्नेल अनुरोध के अनुसार बनाया जा रहा है है, लेकिन उस के रूप में CreateKernel विधि है जो वैश्विक निर्भरता समाधानकर्ता सेट केवल आवेदन जीवनकाल में एक बार चलाने के हो रही है, मामला हो प्रतीत नहीं होता है।

public class NinjectResolver : NinjectScope, IDependencyResolver 
{ 
    private readonly IKernel _kernel; 
    public NinjectResolver(IKernel kernel) 
     : base(kernel) 
    { 
     _kernel = kernel; 
    } 
    public IDependencyScope BeginScope() 
    { 
     return new NinjectScope(_kernel.BeginBlock()); 
    } 
} 

मैं क्या कर रहा हूँ:

मैं क्योंकि ढांचे में परिवर्तन की MVC 4. साथ अच्छा खेलने Ninject बनाने के लिए this post से लिया कुछ कोड का उपयोग कर रहा है, मैं एक अतिरिक्त आवरण है कि मैं GlobalConfiguration.Configuration.DependencyResolver को असाइन करना था गलत?

+2

शायद से संबंधित नहीं कैप्टनक्रिग का मुद्दा, लेकिन शीर्षक के लिए प्रासंगिक है। मुझे एक ही समस्या थी और यह पता चला कि मैं गलती से इंटरफ़ेस की बजाय मेरी वस्तुओं में से एक में कार्यान्वयन इंजेक्शन दे रहा था। तो कन्स्ट्रक्टर में मैंने गलती से इफू के बजाय फू रखा था। उम्मीद है कि यह किसी को वहां मदद करता है ... –

उत्तर

5

मैं मिल सकता है कभी नहीं यह ठीक से काम करने के लिए, और मुझे यकीन नहीं है क्यों। मेरा अनुमान है कि इस समय एमवीसी 4 एकीकरण थोड़ा अपरिपक्व होने के साथ कुछ करना है।

एक वैकल्पिक मैं उपयोग कर रहा हूँ के रूप में:

kernel.Bind<IFoo>().ToConstant(new Foo());

यह काम करने के लिए लगता है, लेकिन मैं इसके साथ बहुत खुश नहीं हूँ।

+1

http://stackoverflow.com/questions/11356864/ninject-insingletonscope-with-web-api-rc – BlakeH

1

नोट: मैंने ninject & ninject.web.mvc स्थापित करने के लिए nuget का उपयोग किया (जो मुझे यकीन है कि आपने भी किया है)।

मैं आपके बाकी कोड को देखने में सक्षम नहीं हूं, लेकिन यहां मेरे "NinjectDependencyScope" कक्षा में मेरे पास क्या है। (मुझे लगता है कि तुम्हारा बस NinjectScope कहा जाता है, अपने कोड के साथ कुछ अन्य नामकरण विसंगतियों हो सकता है)

public class NinjectDependencyScope : IDependencyScope 
{ 
    private IResolutionRoot _resolver; 

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

     _resolver = resolver; 
    } 

    #region IDependencyScope Members 

    public void Dispose() 
    { 
     var 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); 
    } 

    #endregion 
} 

और यहाँ मेरी NinjectWebCommon वर्ग (App_Start फ़ोल्डर में स्थित) है:

using System; 
using System.Web; 
using System.Web.Http; 
using Microsoft.Web.Infrastructure.DynamicModuleHelper; 
using Ninject; 
using Ninject.Modules; 
using Ninject.Web.Common; 

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

namespace ABCD.Project.Web.App_Start 
{ 
public static class NinjectWebCommon 
{ 
    private static readonly Bootstrapper Bootstrap = new Bootstrapper(); 

    /// <summary> 
    /// Starts the application 
    /// </summary> 
    public static void Start() 
    { 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
     DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 
     Bootstrap.Initialize(CreateKernel); 
    } 

    /// <summary> 
    /// Stops the application. 
    /// </summary> 
    public static void Stop() 
    { 
     Bootstrap.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>(); 

     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) 
    { 
     //var modules = new INinjectModule[] { new NinjectBindingModule(), }; 
     //kernel.Load(modules); 
     Here's where you would load your modules or define your bindings manually... 
    }   
} 
} 
+0

मेरे नियंत्रक को 'आईबार' की आवश्यकता होती है जो कि कन्स्ट्रक्टर में 'IFoo' लेती है। मेरे साथ – captncraig

+0

भालू जबकि मुझे लगता है कि इस्तेमाल किया Ninject ... अपने कोड नमूना कुछ हद तक मैं क्या किया था के लिए परिचित लग रहा है मेरे पुराने MVC 4 जाल एपीआई एप्लिकेशन पर गति अप करने के लिए वापस पाने के ... – BlakeH

+0

मैं शायद कुछ अजीब हो रहा है लगता है। आपका कोड मेरा बहुत समान दिखता है, सिवाय इसके कि आप '_resolver.TryGet' का उपयोग कर रहे हैं और मैं' _resolver.Resolve' का उपयोग कर रहा हूं। 'TryGet' विधियां 'IResolutionRoot' के मेरे संस्करण पर मौजूद नहीं हैं। क्या आप mvc3 प्लगइन का उपयोग कर रहे हैं? – captncraig

3

जैसा कि पहले उल्लेख किया गया है, यह एक बग की तरह दिखता है।

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 static object padlock = new Object(); 

    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) 
         { 
         lock (padlock) 
         { 
         if (_concreteInstance == null) 
         { 
          _concreteInstance = _kernel.Get<T>(k_ConstantInjectionName); 
         } 
          } 
         } 


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

     return toReturn; 
    } 
} 

और फिर बस का उपयोग करें::

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

बल्कि तो

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


3

निश्चित रूप से देर से पहुंचने
एक विकल्प के लिए बस एक सिंगलटन विस्तार विधि अपने आप को लागू करने के लिए है इस धागे के लिए लेकिन यह सिर्फ एक Windows सेवा वेब एपीआई नियंत्रकों के लिए Owin होस्टिंग और Ninject, InSingletonScope() के साथ निर्भरता को हल करने से काम नहीं कर रहा था जब तक मैंने किया था के साथ मुझे क्या हुआ है:

var kernel = new StandardKernel(); 
... 
kernel.Bind<Foo>().ToSelf().InSingletonScope(); 
kernel.Bind<IFoo>().ToMethod(context => context.Kernel.Get<Foo>()); 
... 

// Controllers ask for the dependency as usual... 
public class SomeController : ApiController 
{ 
    readonly IFoo _foo; 

    public SomeController(IFoo foo) 
    { 
     _foo = foo; 
    } 
... 

आशा इस मदद करता है

+0

धन्यवाद यह वेबएपीआई नियंत्रकों के साथ इसके अलावा मेरे मुद्दे को हल, तो किसी को एक स्पष्ट विवरण क्यों .. मैं में दिलचस्पी रखता हूँ है ! – bAN