I want to pack standard aspect operations like: value conversion, validation, logging etc in object which semantically behaves like a property. I don't want to use IoC, DI containers and etc. The question is: Is it a good pattern to implement properties as an objects? Below is my solution (it's not ideal, just for example). Is there any open source frameworks with the same approach?
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person["Age"].Value = 30;
person["BankAccountId"].Value = 178259;
Console.WriteLine(person);
Console.ReadLine();
}
}
// I use this abstract class to be able to create lists of template
// classes of different types.
public abstract class ExtendedProperty : INotifyPropertyChanged
{
protected string name;
public string Name => name;
public abstract object Value { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// The main reason for this class is to pack
/// standard operations like conversion, validation and logging
/// in a "property". I don't want to use IoC, DI containers.
/// </summary>
/// <typeparam name="T">primitive</typeparam>
public class ExtendedProperty<T> : ExtendedProperty
where T : struct
{
private readonly bool mutable;
T _value;
public ExtendedProperty(string name, bool mutable, T initialValue)
{
this.name = name;
this.mutable = mutable;
_value = initialValue;
}
private void setValue(T value)
{
if (mutable)
{
{/* possible conversion logic */ }
{/* possible validation logic */ }
if (!(_value.Equals(value)))
{
_value = value;
{/* possible logging logic */}
OnPropertyChanged(nameof(Value));
}
}
}
private T getValue()
{
{/* possible conversion logic */ }
return _value;
}
public override object Value
{
get
{
return getValue();
}
set
{
setValue((T)value);
}
}
public void Undo() { /* not implemented yet */ }
public void Redo() { /* not implemented yet */ }
}
public class Person
{
private List<ExtendedProperty> extProperties = new List<ExtendedProperty>();
public Person()
{
extProperties.Add(new ExtendedProperty<int>("Age", true, 0));
extProperties.Add(new ExtendedProperty<int>("BankAccountId", true, 0));
}
public ExtendedProperty this[string propertyName]
{
get
{
ExtendedProperty ret = null;
foreach (var extendedProperty in extProperties)
{
if (extendedProperty.Name == propertyName)
{
ret = extendedProperty;
break;
}
}
Debug.Assert(ret != null);
return ret;
}
}
public override string ToString()
{
return $"Age: {this["Age"].Value}, BankAccountId: {this["BankAccountId"].Value}";
}
}
Aucun commentaire:
Enregistrer un commentaire