2010-04-05 11 views
9

मैं .NET 3.5 ढांचे के लिए निनजेक्ट 2.0 का उपयोग कर रहा हूं। मुझे सिंगलटन बाध्यकारी में कठिनाई हो रही है।निंजा: सिंगलटन बाध्यकारी वाक्यविन्यास?

मैं एक वर्ग UserInputReader जो IInputReader लागू करता है। मैं केवल इस वर्ग के एक उदाहरण को कभी भी बनाना चाहता हूं।

public class MasterEngineModule : NinjectModule 
    { 
     public override void Load() 
     { 
      // using this line and not the other two makes it work 
      //Bind<IInputReader>().ToMethod(context => new UserInputReader(Constants.DEFAULT_KEY_MAPPING)); 

      Bind<IInputReader>().To<UserInputReader>(); 
      Bind<UserInputReader>().ToSelf().InSingletonScope(); 
     } 
    } 

     static void Main(string[] args) 
     { 
      IKernel ninject = new StandardKernel(new MasterEngineModule()); 
      MasterEngine game = ninject.Get<MasterEngine>(); 
      game.Run(); 
     } 

public sealed class UserInputReader : IInputReader 
    { 
     public static readonly IInputReader Instance = new UserInputReader(Constants.DEFAULT_KEY_MAPPING); 

     // ... 

     public UserInputReader(IDictionary<ActionInputType, Keys> keyMapping) 
     { 
      this.keyMapping = keyMapping; 
     } 
} 

यदि मैं उस निर्माता को निजी बनाता हूं, तो यह टूट जाता है। मुझसे यहां क्या गलत हो रहा है?

+0

एकमात्र पर कुछ रोचक विविधताओं: http: IDictionary<ActionInputType, Keys>UserInputReader के निर्माता में उपयोग करने के लिए निर्दिष्ट करने के लिए, आप WithConstructorArgument विधि का उपयोग कर सकते हैं // w ww.yoda.arachsys.com/csharp/singleton.html – mcliedtk

+0

यदि वे एक ही असेंबली में हैं तो आप निजी के बजाय कन्स्ट्रक्टर आंतरिक बना सकते हैं। शायद उस विज्ञापन को थोड़ी सी सुरक्षा दें यदि आप उस कन्स्ट्रक्टर तक पहुंचने वाले अन्य असेंबली से कोड के बारे में चिंतित हैं। – jpierson

+1

'बाइंड ()। () में। InSingletonScope()' – Jaider

उत्तर

18

बेशक यह टूट जाता है यदि आप कन्स्ट्रक्टर को निजी बनाते हैं। आप अपनी कक्षा के बाहर से निजी रचनाकारों को कॉल नहीं कर सकते!

तुम क्या कर रहे हैं आप क्या करना चाहिए रहे हैं वास्तव में क्या है। इसका परीक्षण करें:

var reader1 = ninject.Get<IInputReader>(); 
var reader2 = ninject.Get<IInputReader>(); 
Assert.AreSame(reader1, reader2); 

आपको आवृत्ति सिंगलटन प्राप्त करने के लिए स्थिर क्षेत्र की आवश्यकता नहीं है। यदि आप एक आईओसी कंटेनर का उपयोग कर रहे हैं, तो आपको कंटेनर के माध्यम से अपने सभी उदाहरण मिलना चाहिए।

आप कर तो जनता स्थिर क्षेत्र चाहते हैं (यकीन नहीं करता है, तो उसके लिए एक अच्छा कारण है), तो आप इस तरह, अपने मूल्य के लिए बाध्य कर सकते हैं प्रकार:

Bind<UserInputReader>().ToConstant(UserInputReader.Instance); 

संपादित:

Bind<UserInputReader>().ToSelf() 
    .WithConstructorArgument("keyMapping", Constants.DEFAULT_KEY_MAPPING) 
    .InSingletonScope(); 
+0

ठीक है, ठंडा। लेकिन UserInputReader के निर्माता को 'IDictionary ' की आवश्यकता होती है। मैं निनजेक्ट में इसे कैसे निर्दिष्ट कर सकता हूं? –

+0

@Rosarch: या तो आप शब्दकोश के चारों ओर एक मार्कर रैपर बनाते हैं, इसे 'IActionKeyMap' या कुछ कहते हैं, और इसका उपयोग करें, या आप अपनी टिप्पणी में विधि दृष्टिकोण का उपयोग करते हैं, या आप ctor पैरामीटर निर्दिष्ट करने के लिए सुविधाओं का उपयोग करते हैं (याद नहीं कर सकते । ("keyMapping"/* जो कुछ भी * /) '.WithConstructorArgument;' –

+1

समझ गया। जैसे ओपी 'UserInputReader.Instance.DoSomething() 'के साथ करना चाहता था –

0

IInputReader उदाहरण क्षेत्र घोषित नहीं करता है और न ही कर सकते हैं यह है, क्योंकि इंटरफेस क्षेत्र या स्थिर क्षेत्र या यहां तक ​​कि स्थिर गुण (या स्थिर विधि) नहीं हो सकता।

बाइंड वर्ग में पता नहीं कर सकते हैं यह उदाहरण क्षेत्र खोजने के लिए (जब तक यह प्रतिबिंब का उपयोग करता है) है।

संबंधित मुद्दे