I'm new to C# and I'm unsure why this singleton pattern is throwing a System.TypeIntializationException:
Here is the ViewModel setting a reference to the ProductRepository singleton:
private void BindingChartView_Load(object sender, EventArgs e)
{
// Call the method that creates a DataSet
ProductRepository taskRepo = this.SetupData();
}
Here is how the ProductRepository singleton is defined:
namespace Chart.Model
{
public class ProductRepository
{
private static readonly ProductRepository instance;
public static ProductRepository Instance
{
get { return instance; }
}
static ProductRepository()
{
instance = new ProductRepository();
}
private ProductRepository()
{
InitializeRepos();
}
}
}
EDIT: Here is what I have for the Setup() method. InitializeRepos() is all commented out.
private ProductRepository SetupData()
{
taskRepo = ProductRepository.Instance;
return taskRepo;
}
Basically, a watch on taskRepo is what is showing me the exception, and it says that it was thrown by Chart.Model.ProductRepository.Instance.
I apologize, I found that the problem was a reference to a 3rd party dll's class in the private constructor, just after InitializeRepos(). I had parsed it out here to simplify, but it turned out to be the culprit.
Related
i feel stupid really, but i think i am being snow blind. i cannot access a singleton class method when calling from another classy. i get the dreaded
(NullReferenceException).
here are both my simple singleton and how i am calling the method.
public class PlayerNodePosition : MonoBehaviour
{
public static PlayerNodePosition instance;
string code;
void Awake()
{
if (instance == null)
{
Debug.LogWarning("More than one instance of Inventory found!");
return;
}
instance = this;
}
public void AddCode(string _code)
{
code = _code;
}
}
and here is the caller from another script.
void AddCode()
{
PlayerNodePosition.instance.AddCode("Added!");
}
being a "simpleton" i am obviously missing the obvious.
You don't instantiate instance anywhere. You would need something like
private static PlayerNodePosition playerNodePosition;
public static PlayerNodePosition instance
{
get
{
if (playerNodePosition == null) {
playerNodePosition = new PlayerNodePosition();
}
return playerNodePosition;
}
}
The method Awake should be static and the instance should be set. I have no chance to check whether this runs as I have no C# installed, but the Debug log warning you give is logically wrong. If there is no instance, you need to create one. If there is an instance, you return that one. This is the singleton pattern.
public class PlayerNodePosition : MonoBehaviour
{
public static PlayerNodePosition instance;
string code;
void static getInstance()
{
if (instance == null)
{
instance = new PlayerNodePosition();
}
return instance;
}
public void AddCode(string _code)
{
code = _code;
}
}
Let's assume we have the following two classes, How can we listen for Errors and if any error occurred, recreate the singleton? I have put together the following code, but would like to know if there is a pattern for safely raise error, dispose object and recreate it automatically?
`
static void Main(string[] args)
{
MyFirstClass.Instance.SayHello();
}
}
class MySecondClass
{
public int ID { get; set; }
public void SayHelloFromSecondClass()
{
Console.WriteLine("Say Hello From Second Class");
}
public MySecondClass(int id)
{
ID = id;
}
}
public sealed class MyFirstClass
{
private static readonly MyFirstClass instance = new MyFirstClass();
private static MySecondClass msc;
public event EventHandler ErrorOccuredEvent;
private MyFirstClass() { }
public static MyFirstClass Instance
{
get
{
msc = new MySecondClass(id: 1);
return instance;
}
}
public void SayHello()
{
Console.WriteLine("Hello World...");
}
static void ErrorOccured(object sender, EventArgs e)
{
Console.WriteLine("Oops");
msc = null;
Thread.Sleep(5000);
GC.Collect();
msc = new MySecondClass(id: 2);
}
}
`
If I understand well, MyFirstClass (which is a singleton) is a kind of wrapper around MySecondClass that turns MySecondClass into a singleton as well.
Let's call MyFirstClass: Wrapper
Let's call MySecondClass: Service
If the clients always consume the Service through the single instance of Wrapper, then re-creating a Wrapper will not help, because the clients might keep a reference to Wapper. Re-creating Service can help if the clients don't see it and cannot keep a reference to it. Therefore they must consume the service indirectly.
It's easiest to achieve this through an interface:
public interface IHelloService
{
void SayHello();
}
public class HelloService : IHelloService
{
public void SayHello()
{
Console.WriteLine("Hello");
}
}
public class HelloServiceWrapper : IHelloService
{
public static readonly IHelloService Instance = new HelloServiceWrapper();
private HelloServiceWrapper () {}
private IHelloService _service;
public void SayHello()
{
EnsureServiceAvailable();
_service.SayHello();
}
private void EnsureServiceAvailable()
{
if(_service == null) {
_service = new HelloService();
}
}
private void HandleError()
{
_service = null;
}
}
But if the error happens when the client is using the service ...
HelloServiceWrapper.Instace.SayHello();
... this call might fail.
You would have to re-create the service instantly in order to make succeed the client's call (assuming that re-creating the service will solve the problem and that the error will not occur again immediately):
public void SayHello()
{
try {
_service.SayHello();
} catch {
_service = new HelloService();
_service.SayHello();
}
}
Note: Disposing the service invalidates the object and makes any reference a client has to it invalid. But re-creating a new one does not give the client a new reference! You would need to have a reference to the clients reference in order to be able to give the client a new instance.
I am used to writing embedded c and poorly skilled in c#.
My problem is that I want to be able to run the function openAnotherForm() from Welcome_Form and right now the code does not work. I patiently tried different things but only managed to push my frustration.
I simplified my relevant code to illustrate the problem.
File 1 - This will run and open file 2.
class UIcode
{
private Welcome_Form Welcome;
private AnotherForm_Form AnotherForm;
public UIcode()
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}
File 2 - When I click TheButton, the program should run the function openAnotherFrom from file 1.
public partial class Welcome_Form : Form
{
public Welcome_Form()
{
InitializeComponent();
}
private void TheButton_Click(object sender, EventArgs e)
{
// Function from file 1
UIcode.openAnotherForm();
}
}
I realize the problem might be quite trivial but I would still be grateful for an explanation on how to do this.
Preferable: The functions from UIcode should only be recognized by classes specified by UIcode.
You can change the constructor to take a reference to the instance of UIcode that opened it:
private static UIcode myParent;
public Welcome_Form(UIcode parent)
{
myParent = parent;
InitializeComponent();
}
Now in UIcode:
public UIcode()
{
Welcome = new Welcome_Form(this);
Application.Run(Welcome);
}
And finally, back in Welcome_Form:
private void TheButton_Click(object sender, EventArgs e)
{
// Function from file 1
myParent.openAnotherForm();
}
Your openAnotherForm() method is not static, so it needs an instance reference in order to be used. Either instantiate a UICode object, or mark the method as static.
You to create an instance of the class in File1 to call the method. You've called the class UICode, so the constructor should be renamed from public UserInterface() to public UICode().
class UIcode
{
private Welcome_Form Welcome;
private AnotherForm_Form AnotherForm;
public UIcode() // Renamed Constructor
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}
public partial class Welcome_Form : Form
{
public Welcome_Form()
{
InitializeComponent();
}
private void TheButton_Click(object sender, EventArgs e)
{
// Create an instance UICode
UICode instance = new UICode();
// Call the method from the instance, not from the class.
instance.openAnotherForm();
}
}
Alternatively, you can make openAnotherForm() a static method, but you'll also need to make the instance variables (Welcome and AnotherForm) static. You will also need to initialize them, but you can do that by making the constructor static as well.
class UIcode
{
private static Welcome_Form Welcome;
private static AnotherForm_Form AnotherForm;
public static UIcode() // Renamed Constructor
{
Welcome = new Welcome_Form();
Application.Run(Welcome);
}
public static void openAnotherForm()
{
Welcome.Hide();
AnotherForm = new AnotherForm_Form();
AnotherForm.ShowDialog();
}
}
I need a singleton that:
is lazy loaded
is thread safe
loads some values at construction
those values can be queried at any time
the initialization MAY happen at some precise time, before the querying begins - so I must be able to trigger it from the outside somehow. Of course, triggering multiple times should only do the initialization once.
I use .NET 3.5.
I've started with Jon Skeet's implementation (5th version) using a static subclass:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
This ticks almost all the boxes, except the "trigger initialization from outside". Since the actual initialization happens inside the ctor, it can't happen more than once.
How can this be accomplished?
The singleton will be used like this:
public static void Main(){
//do stuff, singleton should not yet be initialized.
//the time comes to initialize the singleton, e.g. a database connection is available
//this may be called 0 or more times, possibly on different threads
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
//actual call to get retrieved values, should work
var retrieveVals = Singleton.Instance.Values;
}
Seems like you could do:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton(bool loadDefaults)
{
if (loadDefaults)
Values = new[]{"quick", "brown", "fox"};
else
Values = new[]{"another", "set", "of", "values"};
}
public static Singleton Instance { get { return Nested.instance; } }
public static void Initialize() {
Nested.Initialize();
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton(true);
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
instance = new Singleton(false);
}
}
}
}
}
Or to create a single instance that will be updated:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
Instance.Values = new[]{"another", "set", "of", "values"};
}
}
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
And the third variation based on your immutable comment and removal of Nested class comment:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
private static Singleton instance;
private static object instanceLock = new object();
public static Singleton Instance {
get {
Initialize();
return instance;
}
}
public static void Initialize() {
if (instance == null) {
lock(instanceLock) {
if (instance == null)
instance = new Singleton();
}
}
}
}
The first idea I had was to just use a throwaway variable assigned to the singleton's instance, which would (probably?) trigger the initialization
static Main()
{
var unused = Singleton.Instance;
//this should initialize the singleton, unless the compiler optimizes it out.
//I wonder if the compiler is smart enough to see this call has side effects.
var vals = Singleton.Instance.Values;
}
... but programming by side-effects is something I try hard to avoid, so let's make the intention a bit clearer.
public class Singleton {
public static void Initialize() {
//this accesses the static field of the inner class which triggers the private Singleton() ctor.
Instance._Initialize();
}
private void _Initialize()
{ //do nothing
}
[the rest as before]
}
so the usage would be:
static Main()
{
//still wondering if the compiler might optimize this call out
Singleton.Initialize();
var vals = Singleton.Instance.Values;
}
Btw this would also work:
static Main()
{
var vals = Singleton.Instance.Values;
}
Compiler optimization aside, I think this deals with all the requirements.
You can set up an Initialize method that can be fired from outside, if you need the initialize to happen later, but if the values are different on each time it is fired, then it cannot be static, which violates the Singleton pattern.
Based on your example, which has no variables, I assume you are just delaying when the initialization happens (routine rather than constructor), but your question suggests you want different values, but if multiple initializations happen close together, it only initializes once, so I am a bit confused on this.
I am not sure you need a Singleton only implmentation, but cannot fully answer without information on whether or not the Initialize() runs the same code every time or has some type of variable nature.
You can use double-checked locking pattern. Just add following code in you Singleton class:
public sealed class Singleton
{
..........................
private static object locker = new object();
private static bool initialized = false;
public static void Initialize() {
if (!initialized){
lock(locker) {
if (!initialized){
//write initialization logic here
initialized = true;
}
}
}
}
.......................
}
You can do something like this
public sealed class Singleton
{
IEnumerable<string> Values { get; set; }
private Singleton()
{
Console.WriteLine("-- Private Singleton constructor");
Values = new[] { "quick", "brown", "fox" };
}
public static Singleton Instance
{
get
{
Console.WriteLine("- Singleton Instance");
return Nested.instance;
}
}
public static void Initialize()
{
Console.WriteLine("- Singleton Initialize");
Nested.Initialize();
}
internal class Nested
{
private static object syncRoot = new object();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
Console.WriteLine("-- Static Nested constructor");
}
internal static readonly Singleton instance = new Singleton();
internal static void Initialize()
{
lock (syncRoot)
{
Console.WriteLine("-- Locked");
Console.WriteLine("--- Nested Initialize");
Console.WriteLine("-- Unlocked");
}
}
}
}
Usage
class Program
{
static void Main(string[] args)
{
var i = Singleton.Instance;
i = Singleton.Instance;
Console.WriteLine("-----");
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
Console.Read();
}
}
Which outputs
- Singleton Instance
-- Private Singleton constructor
-- Static Nested constructor
- Singleton Instance
-----
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
public class Singleton<T> where T : class, new()
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
throw new Exception("singleton needs to be initialised before use");
}
return instance;
}
}
public static void Initialise(Action<T> initialisationAction)
{
lock(typeof(Singleton<T>))
{
if (instance != null)
{
return;
}
instance = new T();
initialisationAction(instance);
}
}
}
I think I couldnt do this thing, but I try to ask (maybe :)).
Suppose I have this Main class :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
}
}
now if I want to try to call this instance from another Context Class (web application), I do this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(UiUtils.myObject.Title());
}
}
but what I'd like to do is this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
so, use directly myObject and not UiUtils.myObject :)
I think this is not possible, but maybe I wrong and there are any strategies :) Thanks
** EDIT **
my solution for the moment :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
iContext.myObject = myObject;
}
}
public class iContext : System.Web.UI.UserControl
{
public static MyObject myObject;
public iContext()
{
}
public iContext(MyObject myObject)
{
myObject = myObject;
}
}
public partial class context_eventi_CustomClass : iContext
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
seems to works! What do you think about?
Per MSDN,
A static method, field, property, or
event is callable on a class even when
no instance of the class has been
created. If any instances of the class
are created, they cannot be used to
access the static member. Only one
copy of static fields and events
exists, and static methods and
properties can only access static
fields and static events. Static
members are often used to represent
data or calculations that do not
change in response to object state.
and
"To access a static class member, use the name of the class instead of a variable name to specify the location of the member."
and
The static member is always accessed
by the class name, not the
instance name
#Daniel Earwicker says in his answer on SO here:
...Static members fail to integrate
well with inheritance. It makes no
sense to have them heritable. So I
keep static things in separate static
classes...
So I am not clear on your design why MyObject needs to be static. All you are trying to save is a little typing, but inheritance will not help you here either.
Edit:
I tried to replicate your code in a simple console application. The output is not what you would expect:
namespace ConsoleApplication1
{
public class UiUtils
{
public static int myObject = 1;
public UiUtils()
{
myObject = new int();
iContext.myObject = myObject;
Console.WriteLine("This is UiUtils\n");
}
}
public class iContext
{
public static int myObject = 2;
public iContext()
{
Console.WriteLine("This is iContext\n");
}
public iContext(int myObject)
{
myObject = myObject;
}
}
public class iContext2 : iContext
{
public static int myObject = 3;
public iContext2()
{
Console.WriteLine(myObject.ToString() + "\nThis is iContext2\n");
Console.WriteLine(iContext.myObject.ToString());
}
}
class Program
{
static void Main(string[] args)
{
iContext2 icontext = new iContext2();
Console.In.ReadLine();
}
}
}
The output ends up being this:
This is iContext
3
This is iContext2
If you add a call to iContext.myObject, then it outputs it's number:
This is iContext
3
This is iContext2
2
To access the object without typing the class you can use inheritance.
public class CustomClass : UiUtils
This will share UiUtils properties with CustomClass