I was reading this article by Jon Skeet.
In one the samples, he talks about using Lazy<T> to implement singleton pattern.
This is how the code looks:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
He does mention at the end
It also allows you to check whether or not the instance has been created yet with the IsValueCreated property, if you need that.
IsValueCreated indicates whether the lazy object is initialized or not.
I am wondering to ensure this class remains Singleton (only one insteace is created), where and how I would use IsValueCreated property ?
Lazy<T> ensures that only a single instance is ever created, and that instance will be returned when accessing the Value property - however, the creation of such instance is delayed until the first call to Value.
That means, for the given code sample you do not need to check if the instance has already been initialized - this is what Lazy does for you.
However, you have the ability to check so, which could be useful when dealing with a T of IDisposable (or anything that implements this interface). In that case, you can check for IsValueCreated in the dispose method, before trying to call Dispose() on that object (which would in turn uselessly force the creation of the lazy).
Related
I implement a generic singleton class as follows:
public sealed class Lazy<YourClass>
where YourClass : new()
{
static private System.Lazy<YourClass> _Instance = new System.Lazy<YourClass>();
static public YourClass Instance
{
get
{
return _Instance.Value;
}
}
static Lazy(){ } /*'cuz in "Instance" body, "_Instance" is accessed, so it will be initialized before being accessed, and its value will be ensured not to be null. If so, can I remove this static constructor from my code?*/
}
I then can use that in any other class that is intended as singleton. For example:
public class MySingleton{
static public MySingleton Singleton{
get{
return Lazy<MySingleton>.Instance; // will this be null in some circumstances if I remove the static constructro from the above "Lazy" class?
}
}
}
If not implemented correctly, NullReferenceException might be thrown as I used to encounter. The NullReference might be the "Lazy.Instance" or the "_Instance.Value" in the "Instance" get accessor body (I'm not sure about this).
So my question is:
implemented as above (with the static constructor remained in the code), can I be assured that the "Instance" will never be null whenever(even in the typeInitialization of other classes) I access it?
can I remove the static constructor while keeping the #1 assurance?
Thanks!
The static constructor isn't required to ensure that Instance is non-null. However, it is required for actual laziness to be guaranteed, in terms of type initialization.
With the static constructor in place, your type initializer (that creates an instance of System.Lazy<T>) won't be executed unless and until something accesses the Instance property within your Lazy<T> class. (As Peter said in comments, it would be much better to rename the class.)
Without the static constructor present, the type initializer can be executed at any time before the first field access, which means it might happen when a method which conditionally refers to it is JIT-compiled, even if the condition is never satisfied.
In your case, that probably won't make a significant difference, as you wouldn't access the Lazy<T>.Value property. But if you changed your code to create an instance of the class directly, then the static constructor is required to make sure it's genuinely lazy.
So, with the brand new C# 6 we got those neat auto-property initializers. I thought I might as well take advantage of these to make more concise singletons than ever. Apparently someone else got that idea, too.
public sealed class Singleton
{
public static Singleton Instance { get; } = new Singleton();
private Singleton() { /* some initialization code */ }
}
My questions are:
How thread-safe it is?
How lazy it is, or when the instance is actually created? (not a priority, but it would be good for future reference)
Is it a good idea overall?
(it might look similar to this question, but it's not)
Your code will be expanded to the following:
public sealed class Singleton
{
private static readonly Singleton <Instance>k__BackingField = new Singleton();
public static Singleton Instance { get { return <Instance>k__BackingField; } }
private Singleton() { /* some initialization code */ }
}
(<Instance>k__BackingField is the unspeakable name of the compiler-generated field.)
So, the properties of your code will be exactly the same as of the code above. Namely, this pattern is thread-safe and it can be a good idea, depending on circumstances.
Assuming you're not accessing any other static members of this type before accessing Instance, then the exact degree of laziness is up to the runtime. Commonly, it will be something like "the instance is created the first time a method that could access Instance is JIT-compiled", but you don't have any guarantee about this.
If you want to make sure that the instance is created just before Instance is accessed for the first time, add an empty static constructor to your class. (This can have a small negative effect on performance, but that probably won't matter to you.)
Since most of this is not really specific to C# 6, a good source of further information would be Jon Skeet's articles about singletons and static constructors/type initializers.
I was researching on the singleton pattern for C# I found this example from the msdn website.
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Because the Singleton instance is
referenced by a private static member
variable, the instantiation does not
occur until the class is first
referenced by a call to the Instance
property. This solution therefore
implements a form of the lazy
instantiation property, as in the
Design Patterns form of Singleton.
I am not pretty sure when will the memory will get allocated to
private static readonly Singleton instance
1)Will it happen when the Instance property is called or even before it?
2) I need to force the class to create a new memory sometimes to purge its content. Is it safe to do so using set ?
set
{
instance = null;
}
In the example code you provided, the singleton instance will be created at the time of the first access to the class. This means for your example at the time when Instance gets called for the first time.
More insight you can find in Jon Skeet's article Implementing the Singleton Pattern in C#, see Method 4.
Basically, in order to achieve truly lazy behaviour something like
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
static Singleton(){}
private Singleton(){}
public static Singleton Instance
{
get { return instance; }
}
}
is enough.
(But anyway, the full and much better overview can be found in the mentioned article.)
EDIT
Actually, as it follows from the mentioned article, the instance is not guaranteed to be created at the first access, because of BeforeFiledInit mark. You need to add an empty static constructor, this way it's guaranteed to be lazy. Otherwise the instance will get created at some unspecified time between the program start and first access. (.NET runtime 2.0 is known to have more eager strategy, so you'll probably not get the lazy behaviour.)
Quoting from the said article:
The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called beforefieldinit. Unfortunately, the C# compiler [...] marks all types which don't have a static constructor [...] as beforefieldinit.
EDIT 2
If you want the singleton object to clean up, you should include this functionality into the class Singleton itself.
Removing the property value will effectively make your class not a singleton any more! Imagine that someone accesses the singleton and gets the singleton instance. After that you set the property to null. The existing object of the Singleton class won't disappear, because there's still a reference to it! So the next time you access the Instance property, yet another instance of the Singleton class would be created. So you lost two things: your object is not a singleton any more (because you have got 2 instances existing at the same time), and the memory hasn't been cleared either.
The singleton instance will be loaded into memory when the class itself is loaded which is when the method which could call it begins execution. The actual line that calls into the class doesn't have to actually execute. This is a very slight distinction but can create hard-to-debug problems when a static constructor or static field initializer can throw an error (which you don't have here).
This is fixed in .NET 4 with the new Lazy<T> implementation.
http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
http://csharpindepth.com/Articles/General/Singleton.aspx
The C# specification says:
10.5.5.1 Static field initialization
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
i.e. They only guarantee you get is that it happens before the instance field is read. But it can happen much earlier.
If you want to guarantee that it that it doesn't run earlier than the first access of the property you'll need to add a static constructor(potentially empty):
The static constructor for a closed class type executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
· An instance of the class type is created.
· Any of the static members of the class type are referenced.
As a side node: I noticed that when using DI it is rarely necessary to use an actual singleton. Simply telling DI that it should create a single instance is enough. This is very nice if you decide at a later point that you want more than one instance, since then the fact that it's a singleton isn't baked into all the code using it.
It says in the quote you posted:
the instantiation does not occur until
the class is first referenced by a
call to the Instance property
So... Whenever you call .Instance, or at some point before.
Static members are initialized before the static member is accessed for the first time, and before the static constructor, if any is called.
Read more on MSDN
In a web app, I need to have only one instance of a class called ProcessManager. One way is to make it a singleton. The other way is to use the HttpApplicationState to make sure I always access the same instance, like this:
public static ProcessManager ProcessManager
{
get
{
HttpApplicationState applicationState = HttpContext.Current.Application;
if (applicationState["ProcessManager"] == null)
{
applicationState["ProcessManager"] = new ProcessManager();
}
return (ProcessManager)applicationState["ProcessManager"];
}
}
Which method is better and why?
Based on the limited description you've given, I would choose a Singleton, because then it doesn't have a dependency on HttpContext.Current, and can be used outside of the ASP.Net pipeline (for example, when you want to write unit tests.)
(As an aside, when you set something into ApplicationState, you also need to first call Lock() on it, and then Unlock() it after you're done writing to it, to make sure it's thread safe.)
Alternately, allow injection of an HttpContext when you create your ProcessManager, such that you can use it with a mocked HttpContext.
if you plan to implement it as singleton,as per Jon Skeet (a.k.a C# guru),he personally prefers the code below
public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
(I'm assuming your ProcessManager constructor is private.)
Making it an actual singleton would be best, because such an approach would make it structurally impossible for other programmers that are maintaining your code to accidentally create multiple instances. There's nothing stopping a consumer from accessing the HttpApplicationState directly and removing and replacing the ProcessManager instance. So you must rely on convention to protect the instance of ProcessManager in HttpApplicationState.
Only if there is an actual use case for multiple instances of the class to exist does it make sense to allow multiple instantiations while relying on convention to protect the instance in HttpApplicationState.
As an exercise, I'm translating parts of our large and battle-hardened Delphi-framework to C#.
Included in this framework is a generic singleton parent class. Of course, implementing a singleton in C# is fairly easy (there is even a Jon Skeet article, so what more could I wish for), but our Delphi singleton has a slightly different take on the pattern: as opposed to publishing an 'instance' property/method, it has a "fake" constructor that always returns the same instance. The essential characteristic of this approach is that the user of the singleton class doesn't know that he is dealing with a singleton:
as far as they know, they just construct any old class and request some information from it.
I want to accomplish the same thing in C# (as an exercise, so it doesn't have to be production-quality code, evil hackery is fine), but so far I've failed.
Any suggestion to make a simple myInstance = new MyClass(); always return the same instance is most welcome!
Additional info
We are talking a convenience-implementation of the singleton pattern, as offered by the framework. It doesn't necessarely have to be a parent-class, but it does have to assist the developers in creating their own singletons as well. Requiring them to manually redirect all their method calls to the single-instance will not make them overflow with joy. :-)
I'm not really interested in debating whether or not this is the right way to deal with singletons, for now I'm just interested in the finer art of c#-tweaking.
You would do a Proxy (Edit: As Tom points out below, the proper design pattern is Monostate):
public class MyClass {
MyActualClass _actual;
public MyClass() {
_actual = MyActualClass. Instance;
}
public DoStuff() {
_actual.DoStuff();
}
}
internal class MyActualClass {
private MyActualClass {
}
public DoStuff() {
...
}
MyActualClass _instance;
public static Instance {
get {
if(_instance == null)
_instance = new MyActualClass()
return _instance;
}
}
}
....
public static void Main() {
var my1 = new MyClass();
var my2 = new MyClass();
}
my1 != my2 but my1.DoStuff() calls the same instance of the method as my2.DoStuff()
This would be simplified even further if you programmed of an interface only.
Edit: The equality problem could partially be solved by making _actual protected internal and overwriting MyClass.Equals(object obj) to check whether this._actual == obj._actual
I believe the Monostate pattern will give you what you need:
"The Monostate gives us the singularity of state that we so treasure in the Singleton, but without all of the static headaches that come along with it."
More here:
http://jeremyjarrell.com/archive/2008/04/21/88.aspx
As far as I know, this cannot be done for real because of how C# handles object instances. In order for a constructor to be called, the instance has to actually be created, and you can't just "return" another object from a constructor.
The best thing I can come up with (other than using a factory method) is to treat the class internally as a Singleton, and create "dummy" instances that all just point back to that original instance, when created. So for example, in your constructor you would check to see if the singleton has been initialized, and if not, would initialize it, then you would basically just proxy each instance's methods and properties back to the singleton.
In this implementation, the singleton needn't even be necessarily the same class, but you could if you wanted to keep things contained.
Update: One drawback of this approach is that although each instance would behave as a singleton, it would still have its own object reference and therefore you might also want to override Equals() for equality comparisons.
I think you could possibly roll something with Remoting.
Update:
A better way would be to wrap a proper singleton class in a struct or lightweight class.
Create the singleton as a static member and make all methods access the single static instance.
class SingletonWrapper {
private static RealSingleton instance = new RealSingleton();
public void methodA() {
instance.methodA();
}
public String getA() {
return instance.getA();
}
}
(This is actually Java code but C# is similar enough, I think. :)
I don't see how you can, as constructors don't use a return statement. You could clone all of the relevant links to the singleton, but it would have local copies of local variables, and be very messy.
Instead have the constructor check if the singleton is instantiated, and if it has been already, throw an exception, or log a warning to the developer who is using the old style code.
How about using a static function to return an object insted of using the new keyword.
static private m_obj my_obj;
static private bool my_new_obj;
static public m_obj create_m_obj()
{
if (my_new_obj == false)
{
my_new_obj = true;
my_obj = new my_obj();
}
return my_obj;
}
Then you have easy full controle over the creation of the object, if I an not mistaken.