Wednesday, August 5, 2009

How to build a collection of Interfaces

Here’s the problem: we have some files and some devices which operate with signals. As a signal is one of our main objects, we want to return a collection of signals when opening a file or beginning a communication with a device:

But of course, we want to handle each signal the same, so a signal from an EDF-file should be from the same class as a signal from a device. We could define a signal-class in the Main-library like this:

But this constructs a circular reference. We could create a converter for each special signal and build a collection in the main-library of all signals:

Ouch – ugly. For every signal-type we need one converter. What happens when DeviceSignal changes? Hopefully, we update the corresponding DeviceSignalConverter... Here’s my solution:

We implement all interfaces a signal could be loaded / imported from in the main-signal-class and use generics to simulate a factory. A EDF-dll could have:


public interface ISignal {
int SamplesPerRecord { get; set; }
}

public class SignalReader where T : ISignal, new() {
public override ICollection GetSignals() {
List signals = new List();
var signal = new T();
signal.SamplesPerRecord = 3;
signals.Add(signal);
return signals;
}
}

The signal in the main-library implements that interface:


public class Signal : ISignal {
public int SamplesPerRecord { get; set; }
}

We can now call the SignalReader and it returns us a collection of signals we can use:


public ICollection GetSignals() {
SignalReader reader = new SignalReader();
return reader.GetSignals();
}

We can implement further signal-readers just by implementing the necessary interfaces into the main-signal-class. In fact, for each reader we created from Signal inherited classes implementing the interface the reader defines. With that construct, we can work without circular references and get a collection of objects we can work with.