एक गैर स्थैतिक सदस्य तक पहुंचने के उद्देश्य के लिए आपको रनटाइम पर कक्षा को तुरंत चालू करने की आवश्यकता है। मुझे इसके लिए एक समाधान मिला है। यदि आप विशिष्ट वर्ग के उदाहरण का उपयोग करना चाहते हैं तो आप एक विशिष्ट उदाहरण के आधार पर सूचीबद्ध या विशिष्ट गणना के आधार पर एक नया उदाहरण तत्काल प्रबंधित कर सकते हैं।
मैंने ऐसा करने के लिए फैक्टरी पैटर्न, रणनीति पैटर्न और प्रतिबिंब तकनीक का उपयोग किया। रणनीति पैटर्न प्रत्येक वर्ग को गणना प्रकार के साथ लपेटने के साथ विभिन्न एल्गोरिदम लागू करना है, जबकि कारखाने वर्ग सभी प्रकार के कार्यान्वित वर्गों को पंजीकृत करने के लिए जिम्मेदार होना चाहिए और निर्धारित विशेषता के आधार पर रनटाइम पर उपयुक्त एक बनाना चाहिए। शुरुआत में यह जटिल हो सकता है हालांकि बाद में इसे प्राप्त करना स्पष्ट हो गया।
public class NoneValidationMode : RequiredValidationMode
{
public NoneValidationMode() { }
public override bool IsValid(string properties, object value)
{
//validation code here
}
}
public class AllValidationMode: RequiredValidationMode
{
public override bool IsValid(string properties,object value)
{
//validation code here
}
}
public class AtLeastOneValidationMode : RequiredValidationMode
{
public override bool IsValid(string properties, object value)
{
//validation code here
}
}
public abstract class RequiredValidationMode
{
public abstract bool IsValid(string properties, object value);
}
अब यहाँ:
यहाँ सब सत्यापन प्रकार एक गणन
[Flags]
public enum AlgorithmTypes
{
None = 0,
All = 1,
AtLeastOne = 2
}
अब एक रणनीति पैटर्न में उन सभी को लपेट में प्रतिनिधित्व कर रहे हैं: यहाँ एक व्यावहारिक उदाहरण है फैक्टरी पैटर्न है जो आपके लिए सही उदाहरण बनाने के लिए ज़िम्मेदार है:
public class AlgorithmStrategyFactory
{
private static ArrayList _registeredImplementations;
static AlgorithmStrategyFactory()
{
_registeredImplementations = new ArrayList();
RegisterClass(typeof(NoneValidationMode));
RegisterClass(typeof(AllValidationMode));
RegisterClass(typeof(AtLeastOneValidationMode));
}
public static void RegisterClass(Type requestStrategyImpl)
{
if (!requestStrategyImpl.IsSubclassOf(typeof(RequiredValidationMode)))
throw new Exception("requestStrategyImpl must inherit from class RequiredValidationMode");
_registeredImplementations.Add(requestStrategyImpl);
}
public static RequiredValidationMode Create(AlgorithmTypes algorithmType)
{
// loop thru all registered implementations
foreach (Type impl in _registeredImplementations)
{
// get attributes for this type
object[] attrlist = impl.GetCustomAttributes(true);
// loop thru all attributes for this class
foreach (object attr in attrlist)
{
if (attr is AlgorithmAttribute)
{
if (((AlgorithmAttribute)attr).AlgorithmType.Equals(algorithmType))
{
return (RequiredValidationMode)System.Activator.CreateInstance(impl);
}
}
}
}
throw new Exception("Could not find a RequiredValidationMode implementation for this AlgorithmType");
}
}
अब कक्षाओं में सत्यापन विशेषता का उपयोग किया जा सकता है, कन्स्ट्रक्टर एक एल्गोरिदम टाइप स्वीकार कर रहा है जो बाद में निर्दिष्ट करने जा रहा है कि एल्गोरिदम को किस प्रकार उठाया जाना चाहिए और बुलाया जाना चाहिए।
[AttributeUsage(AttributeTargets.Class, AllowMultiple =false)]
public class MyAttribute : ValidationAttribute
{
AlgorithmTypes AlgorithmType;
public MyAttribute(AlgorithmTypes algorithm = AlgorithmTypes.None)
{
AlgorithmType = algorithm;
}
public override bool IsValid(object value)
{
return (AlgorithmStrategyFactory.Create(AlgorithmType)).IsValid(Properties, value);
}
}
वहाँ वर्ग उदाहरण या विधि के लिए विशेषता से डेटा पारित करने के लिए एक तरीका है? (उदाहरण के लिए एक विशेषता प्रमाणीकरण कर सकती है और प्रमाणीकृत उपयोगकर्ता को विधि में पास कर सकती है?) –
और यह कुल सीमा है, अब तक की सबसे बड़ी सी #/.NET सीमाओं में से एक है। बहुत निराश। – liang