2009-08-21 17 views
7

वहां बहुत सारे फ्लुएंट कार्यान्वयन हैं जो लैम्बदास के साथ काम करते हैं जो काफी साफ हैं। मैं अपने दिमाग को इसके चारों ओर लपेटना चाहता हूं ताकि मैं इनमें से कुछ चीजों को बनाना शुरू कर सकूं, लेकिन मुझे अभी तक एक स्पष्टीकरण नहीं मिला है कि मेरा दिमाग समझता है।लैम्ब्डा फनक <> और फ्लुएंट

एक व्यक्ति सत्यापनकर्ता

public class PersonValidator : IValidator<Person> 
{ 
    public PersonValidator() 
    { 
      AddRule(p => p.FirstName).CannotBeNull().CannotBeBlank(); 
      AddRule(p => p.LastName).CannotBeNull().CannotBeBlank(); 
    } 

    public List<ValidationResult> Validate(Person p) 
    { 
     // pseudo... 
     apply all rules specified in constructor, return results 
    } 
} 

मैं इस इस तरह मेरी सत्यापनकर्ता पर एक विधि का उपयोग कर काम करने का सभी का हिस्सा पाने में कामयाब रहे है ...

public ValidationResult<T,TProp> AddRule<T,TProp>(Func<T,TProp> property) 
{ 
    ... not sure what to do here. This method gives me the ability to use the lambda 
    ... for specifying which properties i want to validate 
} 

मैं की इस सरल उदाहरण पर विचार करें फिर विस्तार विधियां बना सकते हैं जो कैनोटबेनुल और कैनोटबेई के उद्देश्यों के लिए IValidator को बढ़ाते हैं।

तो ऐसा लगता है कि मेरे पास पहली छमाही और समस्या का दूसरा आधा है लेकिन मुझे यकीन नहीं है कि उन्हें एक साथ कैसे लाया जाए।

एक सार्थक स्पष्टीकरण की तलाश में है ... मैं इसे "प्राप्त करना" चाहता हूं। :)

+0

अपने उदाहरण मतलब नहीं है, जब आप कर AddRule()। CannotBeNull()। CannotBeBlank() आप कह रहे हैं आप अपनी मान्यता नियमों में उन नियमों जोड़ सकते हैं और बाद में उन्हें लागू करने के लिए करना चाहते हैं? –

+0

हां, ठीक है। मैं किसी भी प्रकार की जंजीर विधियों के बाद AddRule का उपयोग करने में सक्षम होना चाहता हूं जो कक्षा की किसी दिए गए संपत्ति पर सत्यापन लागू करता है। मेरी चुनौती यह है कि मुझे नहीं पता कि "AddRule" के अंदर क्या करना है। मुझे पता है कि मुझे वैधता में उन लोगों को जारी रखने की ज़रूरत है, लेकिन मुझे नहीं पता कि यह कैसे करना है? – ctorx

उत्तर

5

धाराप्रवाह इंटरफेस की कुंजी यह है कि कैनोटबेनुल() और कैनोटबेब्लैंक() जैसे विधियां वर्तमान उदाहरण (यानी यह) लौटाती हैं। यदि आप अपनी AddRule विधि को "धाराप्रवाह" होना चाहते हैं, तो ValidationResult को वापस करने के बजाय, आपको IValidator के वर्तमान उदाहरण को वापस करने की आवश्यकता है। आपके विस्तार विधियों को वे विस्तारित करने वाले IValidator के उदाहरण को वापस करने की भी आवश्यकता होगी।

मुझे लगता है कि आपके सटीक कार्यान्वयन को थोड़ा और जटिल होना आवश्यक हो सकता है, और उम्मीद है कि नीचे दिया गया उदाहरण कुछ अंतर्दृष्टि प्रदान करेगा।

interface IValidator<T> 
{ 
    IValidatorRule<T, TProp> AddRule<TProp>(Func<T, TProp> property); 
} 

interface IValidatorRule<T> 
{ 
    T instance { get; } 
    string PropertyName { get; } 

    ValidationResult Apply(T instance); 
} 

public static IValidatorAugmentorExtensions 
{ 
    public static IValidatorRule<T> CannotBeNull(this IValidatorRule<T> rule) 
    { 
     // ... 

     return rule; 
    } 

    public static IValidatorRule<T> CannotBeBlank(this IValidatorRule<T> rule) 
    { 
     // ... 

     return rule; 
    } 
} 

ऊपर इतना की तरह इस्तेमाल किया जा सकता है:: वही सामान्य नियम, हालांकि ... वापसी "इस" एक धाराप्रवाह इंटरफ़ेस बनाने के लिए

public class PersonValidator: IValidator<Person> 
{ 
    public PersonValidator() 
    { 
     AddRule(p => p.FirstName).CannotBeNull().CannotBeEmpty(); 
     AddRule(p => p.LastName).CannotBeNull().CannotBeEmpty(); 
    }  

    public List<ValidationResult> Validate(Person p) 
    { 
     List<ValidationResult> results = new List<ValidationResult>(); 

     foreach (IValidatorRule<Person> rule in rules) // don't know where rules is, or what the AddRule method adds to...you'll need to figure that out 
     { 
      results = rule.Apply(p); 
     } 

     return results; 
    } 
} 

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

+0

+1 जो मैं लिखने जा रहा था, लेकिन आपने मुझे इसे हराया। तो मैंने एक अलग दृष्टिकोण लिया। –

+0

उन्हें मुख्य आवश्यकता है, "नियम" के साथ क्या होता है। स्थानीय सूची कैसी दिखती है और इसका उपयोग कैसे किया जाता है? – ctorx

+0

नियमों का स्थानीय समाधान होना चाहिए सबसे आसान समाधान >।AddRule विधि को IValidatorRule बनाना चाहिए और उसे उस संग्रह में जोड़ना चाहिए, और विस्तार विधियों का उपयोग उस आवृत्ति को धाराप्रवाह इंटरफ़ेस के माध्यम से संशोधित करने के लिए किया जा सकता है। सब कुछ एक तरफ, मुझे फिर से तनाव की जरूरत है कि मुझे लगता है कि आप बहुत कम लाभ के लिए बहुत प्रयास कर रहे हैं। यदि आप वास्तव में एक धाराप्रवाह इंटरफेस के लाभों का एहसास करना चाहते हैं, तो मैं आपके सत्यापन ढांचे पर पुनर्विचार करूंगा। कंक्रीट वैधकर्ता (यानी व्यक्ति सत्यापनकर्ता) प्रदान करने के बजाय, सत्यापन करने वाले लोगों के लिए एक धाराप्रवाह इंटरफ़ेस प्रदान करें। – jrista

1

जिस्टिस्ट का जवाब सही है। यहां एक अलग दृष्टिकोण के लिए यह है कि मैंने इसे कैसे पूरा किया।

public class PersonValidator : IValidator<Person> 
    { 
     List<Func<Person,bool>> validationRules = new List<Func<Person,bool>>(); 

    public PersonValidator() 
    { 
     AddRule(p => IsNullOrEmpty(p.FirstName)).AddRule(p1 => CheckLength(p1.FirstName)); 
    } 

    PersonValidator AddRule(Func<Person,bool> rule) 
    { 
     this.validationRules.Add(rule); 
     return this; 
    } 

    private bool IsNullOrEmpty(String stringToCheck) 
    { 
     return String.IsNullOrEmpty(stringToCheck); 
    } 

    private bool CheckLength(String stringToCheck) 
    { 
     return (String.IsNullOrEmpty(stringToCheck) ? false : stringToCheck.Length < 3); 
    } 

    #region IValidator<Person> Members 

    public bool Validate(Person obj) 
    { 
     return validationRules.Select(x => x(obj)).All(result => result == false); 
    } 

    #endregion 
} 



     Person test = new Person() { FirstName = null }; 
     Person test1 = new Person() { FirstName = "St" }; 
     Person valid = new Person() { FirstName = "John" }; 

     PersonValidator validator = new PersonValidator(); 
     Console.WriteLine("{0} {1} {2}", validator.Validate(test), validator.Validate(test1), validator.Validate(valid)); 
+0

मुझे नहीं पता कि यह उदाहरण इस उपयोग को कैसे सुविधाजनक बनाएगा ... AddRule (x => x.FirstName) IsNullOrEmpty(); – ctorx

+1

ऐसा नहीं होगा क्योंकि यह एक अलग दृष्टिकोण है, मैं बस इसे भूलने के बजाय अपना कोड समाप्त करना चाहता था क्योंकि किसी और ने मेरे सामने जवाब दिया था। –

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