I wrote static singleton and add class inside the Singleton class.
However, it seem like it broke the pattern.
any advice why?
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public int MyProperty { get; set; } = 10;
static Singleton() { }
private Singleton() { }
public static Singleton Instance {get { return instance; } }
public class SecondSingleton
{
public Singleton secondInstance;
public SecondSingleton()
{
secondInstance = new Singleton();
secondInstance.MyProperty = 20;
}
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.Instance;
Singleton.SecondSingleton s2 = new Singleton.SecondSingleton();
Console.WriteLine($"s1.MyProperty = {s1.MyProperty}");
Console.WriteLine($"s2.MyProperty = {s2.secondInstance.MyProperty}");
Console.ReadLine();
}
}
Asper WIKI : Singleton restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.
The moment you say "SecondInstance", then it is broke the pattern.
You are creating new Singleton in SecondSingleton constructor, which means secondInstance != Singleton.Instance. Instead, you should get the Instance, i.e: secondInstance = Singleton.Instance;
Related
In my site, I call a third party API. To avoid hitting its rate limit, I need to define a global variable to enqueue requests. (I'm using RateLimiter any better solution?)
namespace MySite.App_Start
{
public static class Global
{
public static int MaxCount { get; set; } = 30;
public static TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(1);
private static TimeLimiter rateLimiter;
public static TimeLimiter RateLimiter
{
get
{
if (rateLimiter == null)
rateLimiter = TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval);
return rateLimiter;
}
}
}
}
Then I'll use RateLimiter property. But I've read a lot that having a global variable is not a good idea. Considering my site has a lot of requests per second, is my code safe to use? Thanks.
Your code isn't 100% safe since it could create multiple instances of TimeLimiter in the beginning and depending on surrounding code, it could be a problem. I'm guessing it wouldn't be a big problem, but it's better to write the code properly to begin with.
This is something an IoC container handles nicely, but if you don't want to use one, you could use Lazy:
private static TimeLimiter rateLimiter = new Lazy(() =>
TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval));
public static TimeLimiter RateLimiter => rateLimiter.Value;
Maybe, you can make it thread-safe by using lock statement.
public static class Global
{
public static int MaxCount { get; set; } = 30;
public static TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(1);
private static object _lockObject = new object();
private static TimeLimiter rateLimiter;
public static TimeLimiter RateLimiter
{
get
{
lock (_lockObject)
{
if (rateLimiter == null)
rateLimiter = TimeLimiter.GetFromMaxCountByInterval(MaxCount, Interval);
return rateLimiter;
}
}
}
}
Your code is not thread-safety.
Try this:
public class Singleton
{
protected Singleton() { }
private sealed class SingletonCreator
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance { get { return instance; } }
}
public static Singleton Instance
{
get { return SingletonCreator.Instance; }
}
}
Or use your favorite IoC-container with creating SingleInstance object
According to Jon Skeet's article, the following pattern is bad as it is not thread safe.
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
I have not learnt threading yet so it is a bit abstract to me. Could you give me a simple code to simulate the threading problem (we get notified when the problem occurs)?
Well thats pretty simple, just let something access a property within your singleton in parallel, for example like this console app.
class Program
{
static void Main(string[] args)
{
var threads = Enumerable.Repeat(new Action(() => Console.WriteLine(Singleton.Instance.guid)), 10);
Parallel.ForEach(threads, t => t());
Console.Read();
}
}
(I've added a guid property to your class to test that)
public sealed class Singleton
{
public Guid guid = Guid.NewGuid();
private static Singleton instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
The issue with this singleton implementation is that 2 threads can access the getter simultaneously and each one will create a new instance. So the first thread might end up with a different instance than the second one... which can lead to unexpected behavior.
This is just in reply to OP comment:
static void Main(string[] args)
{
int test = 5;
Task<Singleton>[] arr =
{
Task<Singleton>.Factory.StartNew(() => Singleton.Instance),
Task<Singleton>.Factory.StartNew(() => Singleton.Instance),
};
Task.WaitAll(arr);
foreach (var item in arr)
{
Singleton s = item.Result;
s.MyProperty = test++;
Console.WriteLine(s.MyProperty);
}
}
MyProperty is just an int property i added.
This page does a good job of describing how to create c# singletons, but it doesn't seem to explain how you actually use them.
http://msdn.microsoft.com/en-us/library/ff650316.aspx
So if I were to create this singleton below, how do I kick things off (I don't think I can instantiate it directly) and if I don't have an instance object how to I access it - e.g. how do I read and write to property prop1
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
public int prop1 {get; set;}
}
To use a singleton class, you simply call it's public static instance property. For example, suppose that you have a logger, and you don't want other developers to always instantiating it:
public class Logger
{
private static Logger logger = new Logger();
private Logger() { }
public static Logger Instance
{
get
{
return logger;
}
}
public void Log(text)
{
// Logging text
}
public int Mode { get; set; }
}
You should log this way:
Logger.Instance.Log("some text here");
In your case, to read/write Mode property, you should write:
Logger.Instance.Mode = 1;
int mode = Logger.Instance.Mode;
You can access the instance by using
Singleton.Instance
You only create the instance once, So you will have something like this
public sealed class Singleton
{
private static readonly Singleton instance;
private bool initialised = false;
private Singleton(){}
public static Singleton Instance
{
get
{
if(initialised)
return instance;
else {
initialsed = true;
instance = new Singleton();
return instance;
}
}
}
public int prop1 {get; set;}
}
Singleton.Instance.prop1 = 12;
I would like to collect more variants for create singleton class.
Could you please provide to me the best creation way in C# by your opinion.
Thanks.
public sealed class Singleton
{
Singleton _instance = null;
public Singleton Instance
{
get
{
if(_instance == null)
_instance = new Singleton();
return _instance;
}
}
// Default private constructor so only we can instanctiate
private Singleton() { }
// Default private static constructor
private static Singleton() { }
}
I have an entire article on this which you may find useful.
Oh, and try to avoid using the singleton pattern in general, due to its pain for testability etc :)
look here : http://www.yoda.arachsys.com/csharp/singleton.html
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;
}
}
}
This is how I understand I can implement the singleton pattern in C#:
public class ChesneyHawkes{
private static ChesneyHawkes _instance = new ChesneyHawkes();
public ChesneyHawkes Instance {get{return _instance;}}
private ChesneyHawkes()
{
}
}
What if I want to provide a single instance of an object, so that there can only ever be one, make the access to it public, but only allow it to be created or replaced by another singleton.
// The PuppetMaster should be the only class that
// can create the only existing Puppet instance.
public class PuppetMaster{
private static PuppetMaster_instance = new PuppetMaster();
public static PuppetMaster Instance {get{return _instance;}}
// Like a singleton but can be replaced at the whim of PuppetMaster.Instance
public static Puppet PuppetInstance {get {return Puppet;}}
private PuppetMaster()
{
}
public class Puppet{
// Please excuse the pseudo-access-modifier
puppetmasteronly Puppet(){
}
}
}
// To be accessed like so.
PuppetMaster.Puppet puppet = PuppetMaster.Instance.PuppetInstance;
You don't really need more than one singleton for that. Look at this example:
using System;
// interface for the "inner singleton"
interface IPuppet {
void DoSomething();
}
class MasterOfPuppets {
// private class: only MasterOfPuppets can create
private class PuppetImpl : IPuppet {
public void DoSomething() {
}
}
static MasterOfPuppets _instance = new MasterOfPuppets();
public static MasterOfPuppets Instance {
get { return _instance; }
}
// private set accessor: only MasterOfPuppets can replace instance
public IPuppet Puppet {
get;
private set;
}
}
class Program {
public static void Main(params string[] args) {
// access singleton and then inner instance
MasterOfPuppets.Instance.Puppet.DoSomething();
}
}