I am working on an MEF project to discover usage and implementation techniques. My first phase of discovery is to implement a dynamically configurable and centralized data controller. One way to customize behavior is to inherit a class I provide that enforces a singularity rule. While the Singleton pattern is much maligned in it's use, I may have found an implementation that could validate, to some degree, the pattern's struggling existence.
The Situation
Suppose a data control module (DataController) imported by the Host is intended to supply a common conduit to databases on request by sibling modules. I only need one DataController and to be composed as a module, DataController must implement IDataController. Implementation of DataProvider as the base class is purely optional; however, derivation from DataProvider will require some additional handling.
The Observations
Gathering the facts:
A static class cannot implement or
extend abstract classes or
interfaces. This fact alone
eliminates the use of a static class
to ensure a singular existence of a
DataController.
A DataController implementing the
Singleton pattern would ensure a
singular existence per application
domain. There is no restriction on
the DataController; allowed to inherit the
required interface to be imported and
composed in the Host.
Given derivation of DataController, the
standard implementation for the
Singleton pattern may prove to be
challenging in same cases. The
proposed data library provides both
publicly accessible classes:
IDataController, and an abstract
DataProvider. To ensure a single
instance of the derived DataController,
the implementation will require some
deviation from the norm.
The Solution
At this point, the solution seems clear. Implementation of the Singleton pattern by the DataHandler base class. I am not naive enough to think that there are other ways I could do this. But here is my rough expectations on how to implement the pattern:
// DataLibrary referenced by Host
public interface IDataController
{
IDataController Start();
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
public abstract class DataProvider
{
// singleton implementation
private static IDataController dcInstance;
protected static IDataController Instance
{
get{ return dcInstance; }
}
// ========================
abstract IDataController CreateController();
protected IDataController instanceController<TDataController>()
where TDataController : IDataController, new()
{
return new TDataController ();
}
}
// references DataLibrary
[Export(typeof(IDataController))]
public class DataController : DataProvider, IDataController
{
public IDataController Start()
{
return CreateController();
}
protected override IDataController CreateController()
{
return instanceController<DataController>();
}
public SqlConnection CreateConnection(params string[] args)
{
// instance and return new SqlConnection
}
}
Keep in mind that I have been working this out - read, theorizing - and have not completed the implementation. There will most likely be some updates as I debug any issues.
Obviously, this implementation is only enforced if the DataController module inherits the abstract base class, DataProvider. Therefore, it stands to reason that we should enforce a rule of singularity to avoid abuse or misuse if the developer opts to derive a DataController from DataProvider.
All that said, I am curious if there is a more acceptable, or practical implementation than what I have devised. And, I begin to question if the Singleton pattern is the right choice. With the Singleton pattern's much maligned existence (and, for the most part, rightfully so), I should, therefore, question my choice.
Is there a more practical implementation to meet my requirements?
*Is this the right implementation of the Singleton pattern in this case?*
Does this implementation actually lend any value to the pattern's existence?
See Question&Answers more detail:
os