hELLO !
Here i have a simple class example with three fields of type class B and some other stuff. As you can see im listening on every child object change. Since i could need alot of properties of type class B i wonder if there is a way of shrinking the code. Creating a listener + a method for each seems like i will have ALOT of code. How would i fix this ... using a dictionary or something similar? I have been told that IoC could fix this, but im not sure where to start.
public class A : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int _id;
public int Id
{
get { return _id; }
set
{
if (_id == value)
{
return;
}
_id = value;
OnPropertyChanged("Id");
}
}
public string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value)
{
return;
}
_name = value;
OnPropertyChanged("Name");
}
}
public B _firstB;
public B FirstB
{
get { return _firstB; }
set
{
if (_firstB == value)
{
return;
}
if (_firstB != null)
{
FirstB.PropertyChanged -= firstObjectB_Listener;
}
_firstB = value;
if (_firstB != null)
FirstB.PropertyChanged += new PropertyChangedEventHandler(firstObjectB_Listener);
OnPropertyChanged("FirstB");
}
}
public B _secondB;
public B SecondB
{
get { return _secondB; }
set
{
if (_secondB == value)
{
return;
}
if (_secondB != null)
{
FirstB.PropertyChanged -= secondObjectB_Listener;
}
_secondB = value;
if (_secondB != null)
SecondB.PropertyChanged += new PropertyChangedEventHandler(secondObjectB_Listener);
OnPropertyChanged("FirstB");
}
}
public B _thirdB;
public B ThirdB
{
get { return _thirdB; }
set
{
if (_thirdB == value)
{
return;
}
if (_thirdB != null)
{
ThirdB.PropertyChanged -= thirdObjectB_Listener;
}
_thirdB = value;
if (_thirdB != null)
ThirdB.PropertyChanged += new PropertyChangedEventHandler(thirdObjectB_Listener);
OnPropertyChanged("ThirdB");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
void firstObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on first object B");
}
void secondObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on second object B");
}
void thirdObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on third object B");
}
}
The most elegant way I know of is to use Aspect Oriented Programming (AOP) with a tool such as PostSharp. I found INotifyPropertyChanged implementation examples here and here. These allow you to decorate your properties with an attribute and PostSharp then implements INotifyPropertyChanged for you when the code is built.
It looks like you are setting up a dependency chain. None of the AOP or static analysis solutions are going to handle this properly. Check out Update Controls, which uses dependency tracking to discover dependency chains at runtime.
Here's what your example becomes:
public class B
{
private Independent<string> _someProperty = new Independent<string>();
public string SomeProperty
{
get { return _someProperty; }
set { _someProperty.Value = value; }
}
}
public class A
{
private Dependent<string> _dependentProperty;
public A()
{
_dependentProperty = new Dependent<string>(() =>
FirstB.SomeProperty + ", " + SecondB.SomeProperty + ", " + ThirdB.SomeProperty);
}
public string DependentProperty
{
get { return _dependentProperty; }
}
private Independent<int> _id = new Independent<int>();
public int Id
{
get { return _id; }
set { _id.Value = value; }
}
private Independent<string> _name = new Independent<string>();
public string Name
{
get { return _name; }
set { _name.Value = value; }
}
private Independent<B> _firstB = new Independent<B>();
public B FirstB
{
get { return _firstB; }
set { _firstB.Value = value; }
}
private Independent<B> _secondB = new Independent<B>();
public B SecondB
{
get { return _secondB; }
set { _secondB.Value = value; }
}
private Independent<B> _thirdB = new Independent<B>();
public B ThirdB
{
get { return _thirdB; }
set { _thirdB.Value = value; }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With