2011-06-02 20 views
6

मैं एक अमूर्त वर्ग है:Ninject: एक सामान्य वर्ग के लिए डिफ़ॉल्ट और विशिष्ट बाइंडिंग

public abstract class Validator<T> : IValidator 

और वर्गों है कि विशिष्ट प्रयोजनों के लिए इस वर्ग को लागू की एक जोड़ी है, उदा

public sealed class NewsValidator : Validator<News> 

अब Ninject का उपयोग कर मैं निम्नलिखित की तरह निर्भरता इंजेक्शन क्या करना चाहते हैं (इस विशेष कोड काम नहीं कर रहा):

Bind<Validator<News>>().To<NewsValidator>(); 
Bind(typeof(Validator<>)).To(typeof(NullValidator<>)); 

तो क्या मैं हासिल करना चाहते हैं कि

Validator<News> 

है कक्षा "न्यूज वैलिडेटेटर" से बंधे रहना चाहिए, लेकिन यदि इस वर्ग के किसी भी अन्य बाध्य संस्करण का अनुरोध नहीं किया गया है, तो

कहें 0
Validator<Article> 
Validator<SomethingElse> 

जो एक डिफ़ॉल्ट कक्षा (NullValidator) से बंधे होना चाहिए। उपरोक्त इस्तेमाल किए गए कोड का उपयोग एक अपवाद फेंकता है, हालांकि, क्योंकि यह वैलिडेटर < समाचार> दोनों को न्यूज़ वैलिडेटर के साथ-साथ नलवैलिएटर से जोड़ता है।

मैं इसे कैसे कार्यान्वित कर सकता हूं? सामान्य वर्ग के विशेष प्रकार व्यक्तिगत वर्गों के लिए बाध्य होना चाहिए। जेनेरिक वर्ग के अन्य सभी प्रकार जिन्हें स्पष्ट रूप से बाध्य नहीं किया गया था, उन्हें डिफ़ॉल्ट कक्षा से बंधना चाहिए।

कुछ सुझावों के बारे में वास्तव में खुश होंगे! धन्यवाद!

उत्तर

9

आप IMissingBindingResolver का एक कस्टम कार्यान्वयन बना सकते हैं।

जब भी गिरी विफल रहता है एक अनुरोध किया सेवा यह HandleMissingBinding विधि के प्रतिनिधियों के लिए एक बाध्यकारी हल करने (इस KernelBase से प्राप्त किसी भी गिरी के लिए सच है)। हैंडलमेनिंग बाइंडिंग विधि प्रत्येक लापता बाध्यकारी रिज़ॉल्वर से पूछेगी कि क्या यह अनुरोधित सेवा के लिए बाध्यकारी बना सकती है। संकल्पकर्ताओं द्वारा लौटाई गई बाइंडिंग, अगर कोई है, तो कर्नेल में जोड़ दी जाएगी।

ध्यान दें कि किसी लापता बाध्यकारी रिज़ॉल्वर द्वारा बनाए गए किसी बाध्यकारी को कर्नेल में एक अंतर्निहित बाध्यकारी के रूप में जोड़ा जाएगा। यह आपके आवेदन पर निहितार्थ हो सकता है। उदाहरण के लिए, यदि आपके पास सेवा के लिए स्पष्ट और निहित बाइंडिंग का मिश्रण है, तो इन बाइंडिंग को हल करना, यानी kernel.GetAll<TService>(), केवल स्पष्ट बाइंडिंग का समाधान करता है। हालांकि, अगर सभी बाइंडिंग अंतर्निहित हैं तो वे सभी हल हो जाएंगे।

के अशक्त प्रमाणकों के लिए एक कस्टम रिसोल्वर लागू करते हैं:

Ninject IMissingBindingResolver के दो मानक कार्यान्वयन है।

public class MissingValidatorResolver : NinjectComponent, IMissingBindingResolver 
{ 
    public IEnumerable<IBinding> Resolve(
     Multimap<Type, IBinding> bindings, IRequest request) 
    { 
     var service = request.Service; 
     if (!typeof(IValidator).IsAssignableFrom(service)) 
     { 
      return Enumerable.Empty<IBinding>(); 
     } 

     var type = service.GetGenericArguments()[0]; 
     var validatorType = typeof(NullValidator<>).MakeGenericType(type); 

     var binding = new Binding(service) 
     { 
      ProviderCallback = StandardProvider.GetCreationCallback(validatorType) 
     }; 

     return new[] { binding }; 
    } 
} 

अब निम्नलिखित परीक्षण (xUnit.net का प्रयोग करके) से गुजरता है।

[Fact] 
public void ShouldResolveNonBoundValidatorDerivedFromValidatorAsNullValidator() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Components.Add<IMissingBindingResolver, MissingValidatorResolver>(); 

    var validator = kernel.Get<Validator<Article>>(); 
    Assert.IsType<NullValidator<Article>>(validator); 
} 
+0

व्हाओ :) अविश्वसनीय, वह एक आकर्षण की तरह काम कर रहा है। आप कैसे जानते हैं?! "IMissingBindingResolver" की खोज करते समय भी Google को वास्तव में बहुत कुछ नहीं मिलता है।वैसे भी, यह बिल्कुल सही है, बहुत बहुत धन्यवाद !! – Oliver

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