I have an interface called IDataIO:
public interface IDataIO
{
event DataReceivedEvent DataReceived;
//.....more events,methods and properties
}
I also have multiple classes that implement this interface, namely UdpIO, TcpIO, SerialIO.
Now, I have an IO class that allows me to switch between different input/output hardware. Each instance of this class has a CurrentIODevice property, which could be one of SerialIO,UdpIO or TcpIO. When this property is assigned, i attach 1 or more handlers to the DataReceivedEvent so that my GUI is notified when incoming data is received, as well as other classes that need to be notified.
public class IO
{
IDataIO CurrentIODevice;
public IO()
{
SerialIO serial = new SerialIO();
TcpIO tcp = new TcpIO();
UdpIO udp = new UdpIO();
CurrentIODevice = serial;
}
}
I also have a IOManager class that holds multiple IO objects.
public class IOManager
{
List<IO> Ports = new List<IO>();
public IOManager()
{
Ports.Add(new IO());
Ports.Add(new IO());
}
Ports[0].CurrentIODevice = serial;
Ports[0].CurrentIODevice.DataReceivedHandler += MyGuiUpdate;
Ports[0].CurrentIODevice.DataReceivedHandler += MyDataProcessing;
}
My concern (its not an issue atm) is how I am going to change between different IDataIO interfaces at runtime.
What is the effect of, at runtime, performing the following statement:
//i know this is illegal but just to demonstrate
IOManager.Ports[0].CurrentIODevice = tcp;
Will the event handlers still be functioning (and correctly)?
Do i need to unassign the events before the CurrentIODevice is assigned, and then re-assign the handlers again after? If this is the case, I can see this approach getting quite messy, so if anyone has a better approach to this problem I'm all ears :)
No, your handlers will not work because they're attached to the old object. Interfaces provides...an interface to an object, see it as a kind of contract but they're not a different object themselves.
If you need to switch between different implementations of the interface (at run-time) and to keep all handlers working you have to have the same object reference for the interface itself, kind of strategy pattern (more or less).
In your case you may, for example, implement the IDataIO interface in a DataIO object. It'll expose a property (or a method, I think its intent is more clear) to switch between different implementations of that interface (serial, TCP or whatever). It'll be the only one object to attach an event handler to that interface (and it'll drop the handler when the concrete implementation will change). Users of that object will always see it, whatever it's the concrete implementation it's using.
Example
This is a small example to explain this concept. The generic interface is this:
interface IDataIO
{
void Write(byte[] data);
byte[] Read();
event EventHandler DataReceived;
}
This is the concrete implementation of IDataIO, other classes will use only this class directly:
sealed class DataIO : IDataIO
{
public void SetChannel(IDataIO concreteChannel)
{
if (_concreteChannel != null)
_concreteChannel.DataReceived -= OnDataReceived;
_concreteChannel = concreteChannel;
_concreteChannel.DataReceived += OnDataReceived;
}
public void Write(byte[] data)
{
_concreteChannel.Write(data);
}
public byte[] Read()
{
return _concreteChannel.Read();
}
public event EventHandler DataReceived;
private IDataIO _concreteChannel;
private void OnDataReceived(object sender, EventArgs e)
{
EventHandler dataReceived = DataReceived;
if (dataReceived != null)
dataReceived(this, e);
}
}
Finally some code for testing:
class Test
{
public Test()
{
_channel = new TcpIO();
_channel.DataReceived += OnDataReceived;
}
public void SetChannel(IDataIO channel)
{
_channel.SetChannel(channel);
// Nothing will change for this "user" of DataIO
// but now the channel used for transport will be
// the one defined here
}
private void OnDataReceived(object sender, EventArgs e)
{
// You can use this
byte[] data = ((IDataIO)sender).Read();
// Or this, the sender is always the concrete
// implementation that abstracts the strategy in use
data = _channel.Read();
}
private DataIO _channel;
}
Obviously you should consider the strategy pattern. I will post the code first and explain later:
public interface IDataIO
{
event DataReceivedEvent DataReceived;
//this the new added method that each IO type should implement.
void SetStrategy();
}
public class SerialIO : IDataIO
{
public void SetStrategy()
{
//put the code that related to the Serial IO.
this.DataReceivedHandler += MyGuiUpdate;
this.DataReceivedHandler += MyDataProcessing;
}
}
public class TcpIO : IDataIO
{
public void SetStrategy()
{
//put the code that related to the Tcp IO.
//I will not implement it because it is a demo.
}
}
public class UdpIO : IDataIO
{
public void SetStrategy()
{
//put the code that related to the Udp IO.
//I will not implement it because it is a demo.
}
}
public class IO
{
IDataIO port = new IDataIO();
public void SetIOType(IDataIO ioType)
{
this.port = ioType;
port.SetStrategy();
}
}
public class IOManager
{
List<IO> ports = new List<IO>();
SerialIO serial = new SerialIO();
TcpIO tcp = new TcpIO();
ports[0].SetIOType(serial);
ports[1].SetIOType(tcp);
}
The interface IDataIO define basics that the all the IO types should implement.
The SerialIO, TcpIO, UdpIO classes derived from IDataIO implement the method SetStrategy() to meet each of their own need.
The IO class owns a field(named port) refers to a IDataIO type, this field can be setted to a certain IO type during the runtime by calling the method SetIOType() defined in the IO
class. Once this method is being called, we know which type the 'port' field refers to, and
then call the SetStrategy() method, it will run the overrided method in one of the IO class.
The IOManager class is the client. when it needs a certain IO type, say SerialIO, it only need to new a IO class and call the SetIOType() method by passing a SerialIO class instance, and all the logic related to the SerialIO type will be setted automatically.
Hope my description can help you.
Related
I'm using a series of Template Pattern classes that represent different types of events.
internal abstract class DayEndingEvent : Event
{
internal void OnDayEnding(object? sender, DayEndingEventArgs e)
{
if (IsHooked) OnDayEndingImpl(sender, e);
}
protected abstract void OnDayEndingImpl(object? sender, DayEndingEventArgs e);
}
This pattern ensures that the implementation only runs if the event is "hooked", which allows other parts of the application to activate/deactivate the event by calling Hook and Unhook methods from the base Event class.
internal abstract class Event
{
public bool IsHooked {get; private set;}
public bool Hook() => !IsHooked && (IsHooked = true);
public bool Unhook() => IsHooked && !(IsHooked = false);
}
(Event is obviously more complex than this, but this is enough to get the picture).
My EventManager can instantiate one of every implementation of this pattern and hook their OnDayEnding to the appropriate handler in an external API.
This has worked fine for a while, but now I have a new requirement to add prioritization to these classes. The only way to do so (and this is a limitation of the external API) is by adding attribute [EventPriority] to the event callback. But obviously I can't annotate OnDayEnding with a priority since that would set the priority of all implementations, which defeats the whole purpose.
The attribute will have no effect anywhere else but on the callback. The only other solution I can see is to remove the Impl and just make the callback itself abstract. But that means I'd have to manually check the IsHooked flag on every implementation, which is what I want to avoid.
So question is, can anybody sugest an alternative to this pattern that would both 1) allow me to have different implementations of the callback, to which I can add priority attributes, and 2) enforce the check for IsHooked?
There are two possibilities I have come across recently when I encountered a similar problem:
Option one, have an entry method that has the required attributes:
public class SpecificImplementationClass1 : BaseClass, IInitializer
{
[SomeAttribute]
public void CallMeToInitiate(SomeType input)
{
ExecuteCommonCode(input);
}
protected override void ExecuteSpecificCode(object input)
{
var typedInput = (SomeType) input;
// ...execute whatever implementation-specific code here
}
}
public class BaseClass
{
protected void ExecuteCommonCode(object input)
{
// DoSomethingBefore(input);
ExecuteSpecificCode(input);
// DoSomethingAfter(input);
}
protected abstract void ExecuteSpecificCode(object input);
}
public interface IInitializer
{
void CallMeToInitialize(SomeType input);
}
// Get all IInitializers through dependency injection and call "CallMeToInitialize(new SomeType())" on each
Option two, use the template delegate pattern
I have two interfaces, unaware of each other.
public interface IListener
{
event SignalEventHandler SignalReceived;
}
public interface IDevice
{
Task HandleSignalAsync();
}
Rather than making each listener call a device directly or pass listeners into device implementations, I'd like to keep them decoupled and define the flow separately. For example:
public class MyApplicationFlow
{
private readonly IListener _listener;
private readonly IDevice _device;
public MyApplicationFlow(IListener listener, IDevice device)
{
_listener = listener;
_device = device;
_listener.SignalReceived += ListenerOnSignalReceived;
}
private async void ListenerOnSignalReceived(object sender, SignalEventArgs args)
{
try
{
await _device.HandleSignalAsync();
// do more stuff in real scenario
args.ProgressReporter.ReportComplete();
}
catch (Exception ex)
{
args.ProgressReporter.ReportError(ex);
}
}
}
There could be several IDevice and IListener implementations passed into the flow.
The listeners and devices seem to follow the Adaptor pattern. But what about MyApplicationFlow?
A Mediator defines the interactions between components, but here the objects are different types and unaware of the parent class.
A Facade encapsulates several subsystems, but here the subsystems are not hidden; they are injected into the constructor.
I'm not even sure if this would be a Behavioural or Structural pattern.
Is there a common name for a class that defines the flow between objects? Something I can use as a suffix for the class names that follow this pattern e.g. Manager, Coordinator, Connector (preferably something already used in the .NET framework).
Or, as I can't find anything, am I barking up the wrong tree? Is there a better way to achieve this decoupling?
For one thing, based on your names it seems like you have your listener and device backwards. Meaning, you seem to be listening to a signal sent from the listener and sending it to the device which seems backwards. Listeners imply listening to signals not sending signals in my opinion.
But otherwise I think what you have here is just a message passing system. Rather than directly communicating together you have a message dispatcher which receives messages from one component and sends them off to another. If you expand on what you have there rather than having a single device and a single listener you could establish any number of connections. You would then queue incoming messages and dispatch them to listeners based on those connections.
interface IListener {
void send(ISender sender, IMessage message);
}
interface ISender { }
interface IMessage { }
interface IPending {
ISender from;
IMessage message;
}
class Dispatcher {
private Queue<IPending> messages = new Queue<IPending>();
private Dictionary<ISender, List<IListener>> connections = new Dictionary<ISender, List<IListener>>();
public void connect(ISender sender, IListener listener) {
if (connections[sender] == null) {
connections[sender] = new List<IListener>();
}
connections[sender].add(listener);
}
public void remove(ISender sender, IListener listener) { ... } // removes connection from connections
public void send(ISender from, IMessage message) {
messages.push({ from, message });
}
public void next() { // called in a loop, perhaps in a background thread
if (messages.peek()) {
var message = messages.pop();
foreach(var listener in connections[message.from]) {
listener.send(sender, message);
}
}
}
}
My first thought was it sounds like a variant of the observer pattern, except in your case the observer isn't directly observing. I found this variant called Event / Emitter / Target that sounds pretty close. https://github.com/millermedeiros/js-signals/wiki/Comparison-between-different-Observer-Pattern-implementations
Edit--I've actually changed my mind. This is pub-sub messaging. The IDevice classes are sending, the middle class is receiving the messages and the IListener is subscribing.
How,does one should call an event declared by interface so that all the classes that has implemented that interface get notified??
For example in structure like this,
public delegate void myDel(int value);
interface IEventCaller{
event myDel myDelEventCall;
}
public Class One : IEventCaller {
public event myDel myDelEventCall;
}
public Class Two : IEventCaller {
public event myDel myDelEventCall;
}
I want both class One and Two to get notify and act as event gets called, I am feeling somewhere I am going wrong direction , is it possible to do?
Actually what you want doesn't involve events. Events would be used by an object implementing IEventCaller to notify some object holding a reference to that object of some change. To invoke something on the object implementing IEventCaller would just require a method, for example Hello();
First, you need code that informs all the objects that implement this interface. To make that possible, you somewhere need to store a list of instances that want to get notified.
One solution would be to create a class that manages that list. Let's say like this
private static List<IEventCaller> eventCallers = new List<IEventCaller>();
public static void AddEventCaller(IEventCaller c)
{
eventCallers.Add(c);
}
public static void RemoveEventCaller(IEventCaller c)
{
eventCallers.Remove(c);
}
public static IEventCaller[] EventCallers
{
get { return eventCallers.ToArray() }
}
Of course this code needs to be thread safe, etc. I'd put all this into a singleton to be globally available.
Then, all objects that implement IEventCallers need to register/unregister accordingly. Thus, I'd also have them Implement IDisposable so that in the constructor you can do
public EventCallable()
{
Singleton.Instance.AddEventCaller(this);
}
and in the Dispose method you can do this:
public void Dispose(bool disposing)
{
Singleton.Instance.RemoveEventCaller(this);
}
Now the code that should notify every instance could just do this:
public void NotifyAll()
{
foreach (IEventCaller caller in Singleton.Instance.EventCallers)
caller.Hello();
}
I think you might be looking at this the other one around.
With events, you want to have an object which is the publisher, which is responsible for publishing the event and saying "hey guys, something just occurred and you should know about it", and you have your subscribers, which are the guys who say "Yo dawg, let me know when that thing occurs, so i can act on it".
What you can do is have the object which is responsible for the event occurring implement your interface:
public class Publisher : IEventCaller
{
public event MyDel MyDeleteEvent;
public void OnDeleteOccured()
{
var myDeleteEvent = MyDeleteEvent;
if (myDeleteEvent != null)
{
MyDeleteEvent(1);
}
}
}
And then have your One and Two objects register to that event occurring, where they pass a method which signature matches the delegate type of MyDel:
public class SubscriberOne
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
public class SubscriberTwo
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
And the registration goes:
void Main()
{
var publisher = new Publisher();
var subscriberOne = new SubscriberOne();
var subscriberTwo = new SubscriberTwo();
publisher.MyDeleteEvent += subscriberOne.OnSomethingOccured;
publisher.MyDeleteEvent += subscriberTwo.OnSomethingOccured;
}
I have multiple classes that do lengthy tasks in threads and want them to output some kind of progress, so i can display it to a progress bar or a counter.
I could use an event or a delegate, defined in an interface, but it seems for every implementation I will need to write the exact same FireEvent code to check if the event is null and raise it, if it's not.
Using an abstract class seems bad too, since functionality like that does not belong in the top most class, which means I have to implement it at different places again.
How do I do that in the most reusable way, without duplicate code everywhere?
If you're using a BackgroundWorker for your other threads, you can use the ReportProgress method, which will raise the ProgressChanged event.
http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx
I usually reverse the relationship between the view and the model so that the view knows about the model. In this example the progress dialog would have a reference to a IProgress interface. It then hooks up to a ProgressChanged event and the view can thus update itself when it needs to. The main advantage of this is the code inside the various classes are not duplicated - Only the code that tells how much is left is inside those classes. This way it is also very easy to clamp progress updates of classes that emit progress status very often.
Just to give you an idea what I usually do:
interface IProgress
{
event EventHandler ProgressChanged;
int ProgressTarget { get; }
int CurrentProgress { get; }
}
And a implementing class. I don't even know if it works as it should - It's just to give an impression on how to implement this interface.
class StreamCopier: IProgress
{
private Stream _source;
private Stream _destination;
public StreamCopier(Stream source, Stream destination)
{
_source = source;
_destination = destination;
}
public void WriteAll()
{
int b;
while ((b = _source.ReadByte()) != -1)
{
_destination.WriteByte((byte)b);
EventRaiser.Raise(ProgressChanged, this); // Just one call here! Can't be less
}
}
public event EventHandler ProgressChanged;
public int ProgressTarget {
get { return (int)_source.Length; }
}
public int CurrentProgress {
get { return (int)_destination.Position; }
}
}
And then the EventRaiser class. Note how the handler reference is passed on the parameter stack, and therefor no thread-safe copy to a 'tmp' is necessary! :)
static class EventRaiser
{
public static void Raise(EventHandler handler, object sender, EventArgs args)
{
handler(sender, args);
}
public static void Raise(EventHandler handler, object sender)
{
Raise(handler, sender, EventArgs.Empty);
}
}
I put "volatile" because it's only vaguely so.
I have a class which has a property called StopRequested. This flag can be set by other threads at any time, and needs to indicate to my code that it should stop what it's doing and exit (this is a Windows Service based process, and when Stop is called, all processing needs to clean up and stop).
I wish to create some other classes to do the actual brunt of the processing work, however these classes also have to be aware of the "stop" flag. You can't just pass the flag because it will pass a copy, and you can't pass properties as ref types.
So how do you propagate a property that might change at any time into other classes?
The only thing I can think of is to pass a reference to the parent class, but I dislike coupling the worker classes to the parent for one flag. Any suggestions would be appreciated.
EDIT:
Here's a basic example:
public class A
{
public bool StopRequested { get; set; }
private Worker = new Worker();
public void DoWork();
{
worker.DoWork();
}
}
public class Worker
{
public void DoWork()
{
while(!StopRequested)
{
....
}
}
}
You could have each of your worker classes have their own StopRequest property and then just set that whenever StopRequest is flagged.
private List<IStopable> WorkerClasses = new List< IStopable > ()
public Bool StopRequest{
get
{
return _stopRequest;
}
set
{
_stopReqest = value;
foreach (var child in WorkerClasses)
child.StopRequest = value;
}
}
Like Rubens said, use an event. What you described basically defines event to a T:
Propagate a property change to other classes.
There is actually a facility in .NET that provides this already, albeit in a generic way: INotifyPropertyChanged. This interface provides a single event, PropertyChanged, that allows a class to notify any listeners of any property change.
In your case, you could easily provide your own interface that is more specific:
interface IStopNotifier
{
event EventHandler StopRequested;
}
This interface would be implemented by your main work manager (whatever it is), and could propagate itself like so:
class WorkManager: IStopNotifier
{
public event EventHandler StopRequested;
protected void OnStopRequested()
{
if (StopRequested != null) StopRequested(this, new EventArgs());
}
public void StopAllWorkers()
{
OnStopRequested();
}
public Worker CreateWorker<T>()
where T: Worker
{
var worker = new T(this);
return worker;
}
}
class abstract Worker: IDisposable
{
public Worker(IStopNotifier stopNotifier)
{
stopNotofier.StopRequested += HandleStopRequested;
}
private IStopNotifier m_stopNotifier;
private bool m_stopRequested = false;
internal void HandleStopRequested(object sender, EventArgs e)
{
m_stopRequested = true;
}
public void Dispose()
{
m_stopNotifier.StopRequested -= HandleStopRequested;
}
}
Why don't to create an event to handle stop requests?