How to Reorganize Duplicate Event Processing Code

I have the following class that allows some objects to subscribe to a change event. The problem is that I also have classes B and C that need this functionality to allow objects to subscribe to the same thing. Of course, we do not want to copy and paste this behavior.

We examined inheritance from a common base class, but all of our classes, including A, B, and C, already inherit from a common BaseClass. And we do not want to add this behavior to BaseClass, because our other classes E, F, G, which inherit from BaseClass, do not need this behavior.

Is there a better solution?

public class A : BaseClass { /*other properties and code */ public event EventHandler OnChange; private bool _hasChanged; public bool HasChanged { get { return _hasChanged; } set { _hasChanged = value; //only need to notify when we've changed. if (value) { if (OnChange != null) OnChange(this, EventArgs.Empty); } } } } 
+4
source share
4 answers

What if we don’t inherit for some time?

1 Suppose, instead of inheriting from a common base class, create your own client class, which requires an event mechanism with an object that implements an event mechanism.

Assume our class

  public class EventNotifier { public event EventHandler OnChange; private bool _hasChanged; public bool HasChanged { get { return _hasChanged; } set { _hasChanged = value; //only need to notify when we've changed. if (value) { if (OnChange != null) OnChange(this, EventArgs.Empty); } } } } 

2 -

  public class A { private EventNotifier eventNotifier; public EventNotifier MyEventNotifier { get { return eventNotifier; } } public A() { eventNotifier = new EventNotifier(); } } 

3 Now your class A users (class, inherited / composed class A)

it is for if B contains A

  public class b { A obj ; public b() { obj = new A(); obj.MyEventNotifier.OnChange += new EventHandler(delegate { Console.WriteLine("Hi"); }); obj. MyEventNotifier.HasChanged = true; } } 
+2
source

Consider an aspect-oriented programming approach similar to the one used in this PostSharp example . This will allow you to enter such code using attributes.

If you created an appropriate aspect, you could have code like:

 public class A : BaseClass { public event EventHandler OnChanged; [ChangedNotify("OnChanged")] public bool HasChanged { get; set; } } 

or, if the idea is to have one OnChange event for multiple properties, you could just hardcode this into an aspect, reducing the code to

 public class A : BaseClass { [NotifyOnChanged] public bool HasChanged { get; set; } } 
+4
source

You might consider introducing an intermediate class between BaseClass and A, B, C, which contains common behavior. Thus, you will not pollute E, F, G, which do not need behavior.

  BaseClass ----------------------------- | | ----- NotifyBaseClass E,F,G | ----- A,B,C 

NB Although AOP looks yummy, I had serious problems trying to get Postsharp to work with other technologies, for example. MS and MSBuild code analysis.

+1
source

Having a subclass for notified objects can be a way, but it can be tricky with aspects that multiply this path by a wide range of different classes. Another way is to include it in your base class and define an interface for it, then you can just bind the interface to the corresponding classes.

At startup, you simply check if it is attached (or something else) and only connects to the event, and then

0
source

All Articles