How to make an instance globally acessible in C#? [duplicate] - c#

This question already has an answer here:
Global instances of class
(1 answer)
Closed 9 years ago.
So I have a class.
I then make an instance somewhere:
Class1 somesinstance = new Class1;
Now I want to access this instance anywhere, is that possible?

Ah, the elusive singleton pattern.
If you have a little spare time, I would highly recommend Jon Skeet's article on the subject: http://csharpindepth.com/Articles/General/Singleton.aspx
Here is a simple example:
public sealed class YourSingleton
{
private static readonly YourSingleton instance = new YourSingleton();
static YourSingleton() {}
private YourSingleton() { }
public static YourSingleton Instance
{
get { return instance ; }
}
}

If you only need a single instance, use the singleton pattern:
public class Class1
{
private Class1()
{
...
}
private static readonly Class1 _instance = new Class1();
public static Class1 Instance { get { return _instance; } }
}
And access the instance like this:
Class1.Instance
Otherwise, just expose it as a static property in a class.

You can the Singleton Pattern as follows:
public class MyClass
{
private static MyClass myClass;
public static MyClass MyClassInstance
{
get { return myClass ?? (myClass = new MyClass()); }
}
private MyClass()
{
//private constructor makes it where this class can only be created by itself
}
}
The instance can then be accessed globally like
MyClass.MyClassInstance

If your anywhere mean your solution - You can use a static class with a static property
public static class Shared
{
private static Class1 _myclass;
public static Class1 MyClass{
get
{
return _myclass??(_myclass=new Class1());
}
}
}

You could create a static class that contains shared instances accessible from every class in you application.
public static class SharedResources
{
public static Class1 obj1 {get; set;}
public static Class2 obj2 {get; set;}
// ...
}

Related

Derived class should always be singleton

I am trying to create a base class with some functionality shared between all derived classes. And all derived classes should be Singletons. Below a pseudo example.
class ExtensionSettings
{
public string GetConfigHtml()
{
// creat conifig html for all properties
}
public void SaveSettings()
{
// save stuff
}
}
class SettingsA : ExtensionSettings
{
private static SettingsA instance;
public static SettingsA Instance {get {return instance ?? (instance = new SettingsA());}}
public string setting1{get;set;}
public string setting2{get;set;}
}
class SettingsB : ExtensionSettings
{
private static SettingsB instance;
public static SettingsB Instance {get {return instance ?? (instance = new SettingsB());}}
public string setting1{get;set;}
public string setting2{get;set;}
}
static void Main(string[] args)
{
System.Console.WriteLine(SettingsA.Instance.setting1);
System.Console.WriteLine(SettingsB.Instance.setting2);
}
Is it possible to move the instancing part to the ExtensionSettings base class?
base class doesn't know about the rest of the object to be instantiated.
basically, when you derive from a base class, the extra logic added in derived class
is hidden from base class. therefore, doing instantiation in the base class is not
possible.

How can I implement a Singleton class that can be derived from in WPF?

Some time ago I learned of the Singleton implementation that only permits a single instance of a class object by hiding the class initializer and using a private static reference of the object within itself, and a public GETTER that references that private reference -
public class Foo : IDisposable{
private static Foo _Instance;
public static Foo Instance{ get{ return Foo._Instance ?? new Foo(); }
private Foo(){ Foo._Instance = this; }
public void Dispose(){ Foo._Instance = null; }
}
I love this quite a lot - it is especially nice for windows that I want accessible application wide.
One thing that I would really like is to be able to implement a generic sort of Singleton Window class upon which a real window could be built and then accessed like this - Is this possible? My thinking was something like -
public class SingletonWindow : Window {
private static SingletonWindow _Instance;
public static SingletonWindow Instance{ get{ return SingletonWindow._Instance ?? new SingletonWindow(); } }
private SingletonWindow(){ SingletonWindow._Instance = this; }
private sealed override void OnClosed(EventArgs E){ SingletonWindow._Instance = null; }
}
But... something inside me that I can't quite voice tells me that this will absolutely positively fail miserably. Can someone tell me why this would fail (if, indeed it will fail), if it is possible to achieve what I am attempting to achieve here, and how I might go about doing so if it is possible?
Personally, I'm not a fan of singletons.
That said, if you want a generic class, make it a generic class. You will have to have a static constructor on your derived class that will provide a route to the private constructor to your generic class, but that's about it.
public abstract class Singleton<T> where T : Window, Singleton<T>
{
protected static Func<T> create;
private static T instance;
public static T Instance { get { return instance ?? (instance = create()); } }
private sealed override void OnClosed(EventArgs e)
{
instance = null;
}
}
public class MyWindow : Singleton<MyWindow>
{
static MyWindow()
{
create = () => new MyWindow();
}
private MyWindow() { }
}
Then you can access the instance on your derived class as if it was a normal singleton.
var myWindow = MyWindow.Instance;

Create inherited Class from BaseClass

I'm trying to instantiate an inherited class from a Base class.
I have tried with this code:
public class BasicClass
{
private static BasicClass instance;
private BasicClass() { }
public static BasicClass Instance
{
get
{
if (instance == null)
{
var dataType = MethodBase.GetCurrentMethod().DeclaringType;
instance = (BasicClass)Activator.CreateInstance(dataType);
}
return instance;
}
}
}
public class MyClass1 : BasicClass
{
}
public class MyClass2 : BasicClass
{
}
And then call it :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var o = MyClass2.Instance;
Text = o.GetType().Name;
}
}
I my small demo I've used a WinForm application but that's just for testing.
My problem is that I get an instance of BasicClass not MyClass2 Can I some how get MyClass2
Can I some how get MyClass2?
No, at least not with the approach that you took. GetCurrentMethod() will not get you the method in the caller, it will give you the method that implements the getter property.
Moreover, consider this declaration:
private static BasicClass instance;
There's only one instance in your program, no matter how many subclasses you create. The problem is that if MyClass2 creates an instance and stores it in BasicClass.instance, there's no place for MyClass1's instance to go.
One approach that you could take would be using a dictionary that maps subtypes to instances, and a generic method for accessing them, like this:
private static IDictionary<Type,BasicClass> instances = new Dictionary<Type,BasicClass>();
...
public static T GetInstance<T>() where T : BasicClass {
BasicClass res;
if (!instances.TryGetValue(typeof(T), out res)) {
res = (BasicClass)Activator.CreateInstance(typeof(T));
instances.Add(typeof(T), res);
}
return (T)res;
}
...
var o = MyClass2.GetInstance<MyClass2>();
You can create a templated base class:
public abstract class Singleton<T> where T : class
{
private static readonly Lazy<T> instance = new Lazy<T>(() => CreateInstance());
public static T Instance { get { return instance.Value; } }
private static T CreateInstance()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
And then inherit it:
public class MyClass1 : Singleton<MyClass1>
{
}
Short answer is: Singleton pattern cannot be inherited. This is because static fields (Instance, for ex.) are declared in special so-called Type Object? which in your case is BaseType and so they no nothing about their children
What do you want to achieve?
You can implement a wrapper like this:
public class Singleton<T>
where T:class, new()
{
private static readonly Lazy<T> _instance = new Lazy<T>(()=>new T());
public static T Instance
{
get { return _instance.Value; }
}
}
See answer below, which provides cool implementation of Singleton wrapper

How do I call a non-static method from a static method in C#?

I have the following code, I want to call data1() from data2(). Is this possible in C#? If so, how?
private void data1()
{
}
private static void data2()
{
data1(); //generates error
}
You'll need to create an instance of the class and invoke the method on it.
public class Foo
{
public void Data1()
{
}
public static void Data2()
{
Foo foo = new Foo();
foo.Data1();
}
}
Perhaps what you are looking for is the Singleton pattern?
public class Singleton
{
private Singleton() {}
public void DoWork()
{
// do something
}
// You can call this static method which calls the singleton instance method.
public static void DoSomeWork()
{
Instance.DoWork();
}
public static Singleton Instance
{
get { return instance; }
}
private static Singleton instance = new Singleton();
}
You still have to create an instance of the class but you ensure there is only one instance.
You have to create an instance of that class within the static method and then call it.
For example like this:
public class MyClass
{
private void data1()
{
}
private static void data2()
{
MyClass c = new MyClass();
c.data1();
}
}
You can't call a non-static method without first creating an instance of its parent class.
So from the static method, you would have to instantiate a new object...
Vehicle myCar = new Vehicle();
... and then call the non-static method.
myCar.Drive();
You just need to provide object reference . Please provide your class name in the position.
private static void data2()
{
<classname> c1 = new <classname>();
c1. data1();
}
Apologized to post answer for very old thread but i believe my answer may help other.
With the help of delegate the same thing can be achieved.
public class MyClass
{
private static Action NonStaticDelegate;
public void NonStaticMethod()
{
Console.WriteLine("Non-Static!");
}
public static void CaptureDelegate()
{
MyClass temp = new MyClass();
MyClass.NonStaticDelegate = new Action(temp.NonStaticMethod);
}
public static void RunNonStaticMethod()
{
if (MyClass.NonStaticDelegate != null)
{
// This will run the non-static method.
// Note that you still needed to create an instance beforehand
MyClass.NonStaticDelegate();
}
}
}
You can use call method by like this : Foo.Data2()
public class Foo
{
private static Foo _Instance;
private Foo()
{
}
public static Foo GetInstance()
{
if (_Instance == null)
_Instance = new Foo();
return _Instance;
}
protected void Data1()
{
}
public static void Data2()
{
GetInstance().Data1();
}
}
new Foo();
Foo.StaticMethod();
class Foo
{
private static Foo foo;
public Foo()
{
foo = this;
}
private void PrintHello()
{
Console.WriteLine("Hello");
}
public static void StaticMethod()
{
foo.PrintHello();
}
}
Please I think the response to your question could be :
public class <Classname> {
static method() {
(new <Classname>)->non-static();
}
non-static method(){ ...; }
~<Classname>(){...;}
};
When a data member is declared as static, only one copy of the data is maintained for all objects of the class. A static member has or handles a permanent storage.
for C++ and probably C#, when new operator is used, it allocates memory for a class object, the object constructor is called after the memory is allocated. Thus, as a static member is called preceded by it belonging classname, the same way the non-static member is called. Thus, the use of (new Classname) seems like a call of a member with predefined permanent storage like a static data member.
therefore, this method has an inconvenience: the memory allocated to call the non-static method can't be freed because the access to it is not saved; every time the static method which needs that non-static method is called, the memory is allocated with no access to be freed at the end of it process.
To resolve this inconvenience, the class must have a destructor to free memory allocated after each process. You could also use finalizers.
References
https://learn.microsoft.com/en-us/cpp/cpp/static-members-cpp?view=msvc-170
https://learn.microsoft.com/en-us/cpp/cpp/new-operator-cpp?view=msvc-170
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/finalizers
I hope these details will help you.
Static method never allows a non-static method call directly.
Reason: Static method belongs to its class only, and to nay object or any instance.
So, whenever you try to access any non-static method from static method inside the same class: you will receive:
"An object reference is required for the non-static field, method or property".
Solution: Just declare a reference like:
public class <classname>
{
static method()
{
new <classname>.non-static();
}
non-static method()
{
}
}
Assuming that both data1() and data2() are in the same class, then another alternative is to make data1() static.
private static void data1()
{
}
private static void data2()
{
data1();
}

What's a good threadsafe singleton generic template pattern in C#

I have the following C# singleton pattern, is there any way of improving it?
public class Singleton<T> where T : class, new()
{
private static object _syncobj = new object();
private static volatile T _instance = null;
public static T Instance
{
get
{
if (_instance == null)
{
lock (_syncobj)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
public Singleton()
{ }
}
Preferred usage example:
class Foo : Singleton<Foo>
{
}
Related:
An obvious singleton implementation for .NET?
According to Jon Skeet in Implementing the Singleton Pattern in C# the code you posted is actually considered as bad code, because it appears broken when checked against the ECMA CLI standard.
Also watch out: everytime you instantiate your object with a new type of T, it becomes another instance; it doesn't get reflected in your original singleton.
This code won't compile, you need "class" constraint on T.
Also, this code requires public constructor on target class, which is not good for singleton, because you can't control at compile time that you obtain (single) instance only via Instance property (or field). If you don't have any other static members except Instance, you are ok to go with just this:
class Foo
{
public static readonly Instance = new Foo();
private Foo() {}
static Foo() {}
}
It is thread safe (guaranteed by CLR) and lazy (instance is created with first access to type). For more discussion about BeforeFieldInit and why we need static constructor here, see https://csharpindepth.com/articles/BeforeFieldInit.
If you want to have other public static members on type, but create object only on access to Instance, you may create nested type, like in https://csharpindepth.com/articles/Singleton
Courtesy of Judith Bishop, http://patterns.cs.up.ac.za/
This singleton pattern implementation ensures lazy initialisation.
// Singleton PatternJudith Bishop Nov 2007
// Generic version
public class Singleton<T> where T : class, new()
{
Singleton() { }
class SingletonCreator
{
static SingletonCreator() { }
// Private object instantiated with private constructor
internal static readonly T instance = new T();
}
public static T UniqueInstance
{
get { return SingletonCreator.instance; }
}
}
This is my point using .NET 4
public class Singleton<T> where T : class, new()
{
Singleton (){}
private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());
public static T Instance { get { return instance.Value; } }
}
I don't think that you really want to "burn your base class" so that you can save 2 lines of code. You don't really need a base class to implement singleton.
Whenever you need a singleton, just do this:
class MyConcreteClass
{
#region Singleton Implementation
public static readonly Instance = new MyConcreteClass();
private MyConcreteClass(){}
#endregion
/// ...
}
More details on this answer on a different thread : How to implement a singleton in C#?
However the thread doesn't use generic.
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
There's no ambiguity in .NET around initialization order; but this raises threading issues.
:/ The generic "singleton" pattern by Judith Bishop seems kinda flawed, its always possible to create several instances of type T as the constructor must be public to use it in this "pattern". In my opinion it has absolutely nothing to do with singleton, its just a kind of factory, which always returns the same object, but doesn't make it singleton... as long as there can be more than one instance of a class it can't be a singleton. Any reason this pattern is top-rated?
public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();
private Singleton()
{
}
public static Singleton Instance
{
get
{
return _instance;
}
}
}
Static initializers are considered thread-safe.. I don't know but you shouldn't use idioms of singleton at all, if you wrap my code above its not more than 3 lines... and inheriting from a singleton doesn't make any sense either.
I was looking for a better Singleton pattern and liked this one. So ported it to VB.NET, can be useful for others:
Public MustInherit Class Singleton(Of T As {Class, New})
Public Sub New()
End Sub
Private Class SingletonCreator
Shared Sub New()
End Sub
Friend Shared ReadOnly Instance As New T
End Class
Public Shared ReadOnly Property Instance() As T
Get
Return SingletonCreator.Instance
End Get
End Property
End Class
As requested, cross posting from my original answer to another question.
My version uses Reflection, works with non-public constructors in the derived class, is threadsafe (obviously) with lazy instantiation (according to the article I found linked below):
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;
}
I picked this up a few years ago, not sure how much is mine, but googling on the code might find the original source of the technique if it wasn't me.
This is the oldest source of the code that I can find that was not me posting it.
Try this generic Singleton class implementing the Singleton design pattern in a thread safe and lazy way (thx to wcell).
public abstract class Singleton<T> where T : class
{
/// <summary>
/// Returns the singleton instance.
/// </summary>
public static T Instance
{
get
{
return SingletonAllocator.instance;
}
}
internal static class SingletonAllocator
{
internal static T instance;
static SingletonAllocator()
{
CreateInstance(typeof(T));
}
public static T CreateInstance(Type type)
{
ConstructorInfo[] ctorsPublic = type.GetConstructors(
BindingFlags.Instance | BindingFlags.Public);
if (ctorsPublic.Length > 0)
throw new Exception(
type.FullName + " has one or more public constructors so the property cannot be enforced.");
ConstructorInfo ctorNonPublic = type.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]);
if (ctorNonPublic == null)
{
throw new Exception(
type.FullName + " doesn't have a private/protected constructor so the property cannot be enforced.");
}
try
{
return instance = (T)ctorNonPublic.Invoke(new object[0]);
}
catch (Exception e)
{
throw new Exception(
"The Singleton couldnt be constructed, check if " + type.FullName + " has a default constructor", e);
}
}
}
}
The Double-Check Locking [Lea99] idiom provided by Microsoft here is amazingly similar to your provided code, unfortunately, this fails the ECMA CLI standard for a puritan view of thread-safe code and may not work correctly in all situations.
In a multi-threaded program, different threads could try to instantiate a class simultaneously. For this reason, a Singleton implementation that relies on an if statement to check whether the instance is null will not be thread-safe. Don't write code like that!
A simple, yet effective means of creating a thread-safe singleton is to use a nested class to instantiate it. The following is an example of a lazy instantiation singleton:
public sealed class Singleton
{
private Singleton() { }
public static Singleton Instance
{
get
{
return SingletonCreator.instance;
}
}
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly Singleton instance = new Singleton();
}
}
Usage:
Singleton s1 = Singleton.Instance;
Singleton s2 = Singleton.Instance;
if (s1.Equals(s2))
{
Console.WriteLine("Thread-Safe Singleton objects are the same");
}
Generic Solution:
public class Singleton<T>
where T : class, new()
{
private Singleton() { }
public static T Instance
{
get
{
return SingletonCreator.instance;
}
}
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T instance = new T();
}
}
Usage:
class TestClass { }
Singleton s1 = Singleton<TestClass>.Instance;
Singleton s2 = Singleton<TestClass>.Instance;
if (s1.Equals(s2))
{
Console.WriteLine("Thread-Safe Generic Singleton objects are the same");
}
Lastly, here is a somewhat releated and usefull suggestion - to help avoid deadlocks that can be caused by using the lock keyword, consider adding the following attribute to help protect code in only public static methods:
using System.Runtime.CompilerServices;
[MethodImpl (MethodImplOptions.Synchronized)]
public static void MySynchronizedMethod()
{
}
References:
C# Cookbook (O'Reilly), Jay Hilyard & Stephen Teilhet
C# 3.0 Design Patterns (O'Reilly), Judith Bishop
CSharp-Online.Net - Singleton design pattern: Thread-safe Singleton
I quite liked your original answer - the only thing missing (according to the link posted by blowdart) is to make the _instance variable volatile, to make sure it has actually been set in the lock.
I actually use blowdarts solution when I have to use a singleton, but I dont have any need to late-instantiate etc.
My contribution for ensuring on demand creation of instance data:
/// <summary>Abstract base class for thread-safe singleton objects</summary>
/// <typeparam name="T">Instance type</typeparam>
public abstract class SingletonOnDemand<T> {
private static object __SYNC = new object();
private static volatile bool _IsInstanceCreated = false;
private static T _Instance = default(T);
/// <summary>Instance data</summary>
public static T Instance {
get {
if (!_IsInstanceCreated)
lock (__SYNC)
if (!_IsInstanceCreated)
_Instance = Activator.CreateInstance<T>();
return _Instance;
}
}
}
pff... again... :)
My contribution for ensuring on demand creation of instance data:
/// <summary>Abstract base class for thread-safe singleton objects</summary>
/// <typeparam name="T">Instance type</typeparam>
public abstract class SingletonOnDemand<T> {
private static object __SYNC = new object();
private static volatile bool _IsInstanceCreated = false;
private static T _Instance = default(T);
/// <summary>Instance data</summary>
public static T Instance {
get {
if (!_IsInstanceCreated)
lock (__SYNC)
if (!_IsInstanceCreated) {
_Instance = Activator.CreateInstance<T>();
_IsInstanceCreated = true;
}
return _Instance;
}
}
}
public static class LazyGlobal<T> where T : new()
{
public static T Instance
{
get { return TType.Instance; }
}
private static class TType
{
public static readonly T Instance = new T();
}
}
// user code:
{
LazyGlobal<Foo>.Instance.Bar();
}
Or:
public delegate T Func<T>();
public static class CustomGlobalActivator<T>
{
public static Func<T> CreateInstance { get; set; }
}
public static class LazyGlobal<T>
{
public static T Instance
{
get { return TType.Instance; }
}
private static class TType
{
public static readonly T Instance = CustomGlobalActivator<T>.CreateInstance();
}
}
{
// setup code:
// CustomGlobalActivator<Foo>.CreateInstance = () => new Foo(instanceOf_SL_or_IoC.DoSomeMagicReturning<FooDependencies>());
CustomGlobalActivator<Foo>.CreateInstance = () => instanceOf_SL_or_IoC.PleaseResolve<Foo>();
// ...
// user code:
LazyGlobal<Foo>.Instance.Bar();
}
Saw one a while ago which uses reflection to access a private (or public) default constructor:
public static class Singleton<T>
{
private static object lockVar = new object();
private static bool made;
private static T _singleton = default(T);
/// <summary>
/// Get The Singleton
/// </summary>
public static T Get
{
get
{
if (!made)
{
lock (lockVar)
{
if (!made)
{
ConstructorInfo cInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);
if (cInfo != null)
_singleton = (T)cInfo.Invoke(new object[0]);
else
throw new ArgumentException("Type Does Not Have A Default Constructor.");
made = true;
}
}
}
return _singleton;
}
}
}
I submit this to the group. It seems to be thread-safe, generic and follows the pattern. You can inherit from it. This is cobbled together from what others have said.
public class Singleton<T> where T : class
{
class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic,
null, null, null) as T;
}
public static T Instance
{
get { return SingletonCreator.Instance; }
}
}
Intended implementation:
public class Foo: Singleton<Foo>
{
private Foo() { }
}
Then:
Foo.Instance.SomeMethod();
As in wikipedia:
the singleton pattern is a design pattern that restricts the
instantiation of a class to one object
I beleave that there is no guaranteed way to do it using generics, if you have restricted the instantiation of the singleton itself, how to restrict the instantiation of the main class, I think it is not possible to do that, and implementing this simple pattern is not that hard, take this way using the static constructor and private set:
public class MyClass
{
private MyClass()
{
}
static MyClass()
{
Instance = new MyClass();
}
public static MyClass Instance { get; private set; }
}
OR:
public class MyClass
{
private MyClass()
{
}
static MyClass()
{
Instance = new MyClass();
}
private static MyClass instance;
public static MyClass Instance
{
get
{
return instance;
}
private set
{
instance = value;
}
}
}
This works for me:
public static class Singleton<T>
{
private static readonly object Sync = new object();
public static T GetSingleton(ref T singletonMember, Func<T> initializer)
{
if (singletonMember == null)
{
lock (Sync)
{
if (singletonMember == null)
singletonMember = initializer();
}
}
return singletonMember;
}
}
Usage:
private static MyType _current;
public static MyType Current = Singleton<MyType>.GetSingleton(ref _current, () => new MyType());
Consume the singleton:
MyType.Current. ...
No Matter which exmaple you choose, always check for concurrency using Parallel.For!
( loop in which iterations may run in parallel)
put in Singleton C'tor :
private Singleton ()
{
Console.WriteLine("usage of the Singleton for the first time");
}
put in Main :
Parallel.For(0, 10,
index => {
Thread tt = new Thread(new ThreadStart(Singleton.Instance.SomePrintMethod));
tt.Start();
});
In many solutions today, people use service lifetime of singleton with dependency injection, as .NET offers this out of the box. If you still want to create a generic singleton pattern in your code where you might also consider initializing the type T to a initialized singleton object, 'settable once' and thread safe, here is a possible way to do it.
public sealed class Singleton<T> where T : class, new()
{
private static Lazy<T> InstanceProxy
{
get
{
if (_instanceObj?.IsValueCreated != true)
{
_instanceObj = new Lazy<T>(() => new T());
}
return _instanceObj;
}
}
private static Lazy<T>? _instanceObj;
public static T Instance { get { return InstanceProxy.Value; } }
public static void Init(Lazy<T> instance)
{
if (_instanceObj?.IsValueCreated == true)
{
throw new ArgumentException($"A Singleton for the type <T> is already set");
}
_instanceObj = instance ?? throw new ArgumentNullException(nameof(instance));
}
private Singleton()
{
}
}
The class is sealed and with a private constructor, it accepts types which are classes and must offer a public parameterless constructor 'new'. It uses the Lazy to achieve built in thread safety. You can init also the type T Singleton object for convenience. It is only allowed if a Singleton is not first set. Obviously, you should only init a Singleton of type T early on in your program, such as when the application or service / API starts up. The code will throw an ArgumentException if the Init method is called twice or more times for the type T.
You can use it like this :
Some model class :
public class Aeroplane
{
public string? Model { get; set; }
public string? Manufacturer { get; set; }
public int YearBuilt { get; set; }
public int PassengerCount { get; set; }
}
Usage sample :
var aeroplane = new Aeroplane
{
Manufacturer = "Boeing",
Model = "747",
PassengerCount = 350,
YearBuilt = 2005
};
var aeroPlane3 = Singleton<Aeroplane>.Instance;
var aeroPlane4 = Singleton<Aeroplane>.Instance;
Console.WriteLine($"Aeroplane3 and aeroplane4 is same object? {Object.ReferenceEquals(aeroPlane3, aeroPlane4)}");
Outputs 'true'.
Trying to re-init type T Singleton to another object fails :
var aeroplane2 = new Aeroplane
{
Manufacturer = "Sopwith Aviation Company",
Model = "Sophwith Camel",
PassengerCount = 1,
YearBuilt = 1917
};
Singleton<Aeroplane>.Init(new Lazy<Aeroplane>(aeroplane2));
You can of course just access the Singleton with initing it - it will call the default public constructor. Possible you could have a way of setting a custom constructor here instead of passing an object as a sort of 'factory pattern'.
var aeroplaneDefaultInstantiated = Singleton<Aeroplane>.Instance;
Default instantiation - calls the parameterless public constructor of type T.
You don't need all that, C# already has a good singleton pattern built-in.
static class Foo
If you need anything more interesting than that, chances are your new singleton is going to be just different enough that your generic pattern is going to be useless.
EDIT: By "anything more interesting" I'm including inheritance. If you can inherit from a singleton, it isn't a singleton any more.

Categories