I have a class which facilitates the discovery of HID
devices, when a device is detected an event
is raised and subsequently detected by another class which will be ultimately responsible for the creation of an object
to represent the HID
device. The creation class
raises an event
of its own with the newly created HID
object.
With this in mind I have a couple of design queries:
1) I have done some research into the "best practices" with regards to the creation of an unknown number or type of object at runtime for which the
Abstract Factory
design pattern features frequently in the results. Does theAbstract Factory
design pattern fit the scenario I have, or is there something else I should be doing?2) The
HidFinder
class raises an event to notify those interested (mostly theHidCreator
class) that a device has been discovered. TheHidCreator
class then raises an event containing the newly createdHID
device. This seems like the correct method, however, confirmation either way would be appreciated.
Below is a dumbed down example of the code in question.
public class HidFinder
{
public event EventHandler<HidFoundArgs> HidFoundHandler;
private void DeviceAdded(object sender, EventArrivedEventArgs e)
{
OnHidFoundHandler(new HidFoundArgs());
}
protected virtual void OnHidFoundHandler(HidFoundArgs e)
{
EventHandler<HidFoundArgs> handler = this.HidFoundHandler;
if (handler != null)
{
handler(this, e);
}
}
}
public class HidCreator
{
private readonly HidFinder hidFinder;
public event EventHandler<IHidDevice> HidDeviceCreatedHandler;
public HidCreator(HidFinder hidFinder)
{
this.hidFinder = hidFinder;
this.hidFinder.HidFoundHandler += HidFinderOnHidFoundHandler;
}
private void HidFinderOnHidFoundHandler(object sender, HidFoundArgs hidFoundArgs)
{
// Create a new HID
var newHidDevice = Factory.CreateMethod();
OnHidDeviceCreatedHandler(newHidDevice);
}
protected virtual void OnHidDeviceCreatedHandler(IHidDevice e)
{
EventHandler<IHidDevice> handler = this.HidDeviceCreatedHandler;
if (handler != null)
{
handler(this, e);
}
}
}
It generally looks as good design, but I would make two changes:
Factory
seems like some global object, it would be better to use Dependency Injection, for better unit testing for example.Factory.CreateMethod
to use parameters, as we don't know what exact implementation of IHidDevice
will be created and if we won't need some additional info from HidFoundArgs
Code after changes:
public class HidCreator
{
private readonly HidFinder hidFinder;
private readonly IHidDeviceFactory factory;
public event EventHandler<IHidDevice> HidDeviceCreatedHandler;
public HidCreator(IHidDeviceFactory factory, HidFinder hidFinder)
{
this.factory = factory;
this.hidFinder = hidFinder;
this.hidFinder.HidFoundHandler += HidFinderOnHidFoundHandler;
}
private void HidFinderOnHidFoundHandler(object sender, HidFoundArgs hidFoundArgs)
{
// Create a new HID
var newHidDevice = factory.Create(HidFoundArgs.ToCreationParameters(hidFoundArgs));
OnHidDeviceCreatedHandler(newHidDevice);
}
protected virtual void OnHidDeviceCreatedHandler(IHidDevice e)
{
EventHandler<IHidDevice> handler = this.HidDeviceCreatedHandler;
if (handler != null)
{
handler(this, e);
}
}
}
public interface IHidDeviceFactory
{
IHidDevice Create(HidCreationParameters parameters);
...
}
public class HidCreationParameters
{
...
}
public class HidFoundArgs
{
public static HidCreationParameters ToCreationParameters(HidFoundArgs args)
{
...
}
}