Doubleton Pattern Implementation
I'm leveraging the Doubleto开发者_C百科n Pattern from the Doubleton Design Pattern on Code Project in my own code. I think it makes things a lot easier since the Singleton only provides one instance, but I get two with this pattern. I was wondering if it would make sense to have it implement an interface so I can inject it into my domain layer.
Despite the usefulness and cleverness of such design, it is not possible. You can't define a static member in an interface.
public interface IDoubleton
{
static IDoubleton Instance { get; } // Can't be done
}
@Pierreten, If you use instance methods, imagine this:
IDoubleton firstInstance;
// Construct firstInstance,
// do some stuff...
// Now comes trouble.
IDoubleton secondInstance = firstInstance.Instance; // what does it mean?
IDoubleton anotherInstance = secondInstance.Instance.Instance.Instance; // what now?
EDIT: As @Roger Pate rightfully pointed out, my 2nd answer should be merged within this one. As he already had done it, I deleted the other one.
Clarification on this answer: This doesn't exactly address the question asked, but the implementation that was linked to above is horribly coded. Perhaps the implementation below would be thread safe.
I'm not 100% sure that this is thread safe because I did not test it (and I can't come up with any real world use of this "pattern" because I think it is confusing), but it is a more correct Singleton-like implementation of what you linked to above and might work to accomplish what you wanted. Good luck.
Sorry about the Console.WriteLine()
calls, I used Snippet Compiler to make this.
/// <summary>
/// Doubleton
/// </summary>
public sealed class Doubleton
{
const int MaxInstances = 2;
static volatile Hashtable instances = new Hashtable();
static volatile int PreviousInstanceNumber = MaxInstances;
#region Constructor
Doubleton()
{
}
#endregion
#region Properties
/// <summary>
/// Get 1 of 2 instances of a Doubleton
/// </summary>
public static Doubleton Instance
{
get
{
lock (instances.SyncRoot)
{
int instanceNumber = PreviousInstanceNumber == MaxInstances ? 1 : ++PreviousInstanceNumber;
// if it doesn't exist, create it
if (instances[instanceNumber] == null)
{
instances[instanceNumber] = new Doubleton();
}
PreviousInstanceNumber = instanceNumber;
return (Doubleton)instances[instanceNumber];
}
}
}
#endregion
/// <summary>
/// Get the index of the Doubleton
/// </summary>
/// <returns></returns>
public int GetInstanceIndex()
{
lock (instances.SyncRoot)
{
for (int i = 1; i <= MaxInstances; i++)
{
if (instances[i] != null && instances[i].Equals(this))
{
return i;
}
}
}
return -1;
}
}
You could then use the following code:
var instance1 = Doubleton.Instance;
var instance2 = Doubleton.Instance;
var instance1Again = Doubleton.Instance;
var instance2Again = Doubleton.Instance;
Console.WriteLine("The following 2 lines should be true:");
Console.WriteLine(instance1.Equals(instance1Again));
Console.WriteLine(instance2.Equals(instance2Again));
Console.WriteLine("---");
Console.WriteLine("The next 50 lines should alternate instances:");
for (int i = 0; i < 50; i++)
{
var instance = Doubleton.Instance;
Console.WriteLine("I have instance # " + instance.GetInstanceIndex());
}
I think it is difficult to see the use of such a class, however, I have a generic class I use for Singleton - I imagine it could be modified/extended - you get some of the benefits of an interface:
public class SingletonBase<T> where T : class
{
static SingletonBase()
{
}
public static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic,
null, null, null) as T;
}
精彩评论