Для доступа к нестатическому члену вам нужно создать экземпляр класса во время выполнения. У меня есть обходной путь для этого. Если вы хотите использовать экземпляр определенного класса, вы можете создать экземпляр нового экземпляра на основе указанного типа, перечисленного или представленного в виде перечисления.
Я использовал для этого Фабричный паттерн, Стратегический паттерн и Технику отражения. Стратегический шаблон должен реализовывать различные алгоритмы с упаковкой каждого класса в тип перечисления, в то время как фабричный класс должен отвечать за регистрацию всех типов реализованных классов и создание подходящего во время выполнения на основе определенного атрибута. Это может быть сложно в начале, однако стало очевидно, что позже. Вот практический пример:
Вот все типы проверки, представленные в перечислении
[Flags]
public enum AlgorithmTypes
{
None = 0,
All = 1,
AtLeastOne = 2
}
Теперь оберните их все в шаблон стратегии:
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);
}
Теперь вот шаблон Factory, который отвечает за создание нужного вам экземпляра:
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");
}
}
Теперь атрибут валидации может использоваться над классами, конструктор принимает 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);
}
}