Accessing a Singleton returns (NullReferenceException) - c#

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;
}
}

Related

Function referring to an instance created by other function C#

I have a question that may be silly, but I'm new to C#, so pardon my insolence. I am wondering whether it is possible for a function to refer to an instance, which has been created by another function.
I am including an exemplary code to illustrate what I mean:
class Program
{
static void Main(string[] args)
{
Instantiator.Instantiate();
Referent.Refer(instance);
Console.ReadLine();
}
}
public class Instance
{
public void OnInstantiated()
{
Console.WriteLine("I have been instantiated.");
}
public void OnReferred()
{
Console.WriteLine("I have been referred to.");
}
}
public class Instantiator
{
public static void Instantiate()
{
Instance instance = new Instance();
instance.OnInstantiated();
}
}
public class Referent
{
public static void Refer(Instance instance)
{
if(instance != null)
{
instance.OnReferred();
}
else
{
Console.WriteLine("No instance to refer to.");
}
}
}
What could I use to be able to refer to the "instance" instance (which is created by the Instantiator.Instantiate function) in the Referent.Refer function?
Thanks in advance for your pertinent comments!
Make Instantiator return the class when done
public class Instantiator
{
public static Instance Instantiate()
{
Instance instance = new Instance();
instance.OnInstantiated();
return instance;
}
}
class Program
{
static void Main(string[] args)
{
var instance = Instantiator.Instantiate();
Referent.Refer(instance);
Console.ReadLine();
}
}
The pattern Instantiate() is doing is often called the "Factory Pattern"
Another option you could use is the Singleton pattern. If you also need your instance to be only one, you can give the responsibility to create a new instance and return it afterwards to the class itself.
class Program
{
static void Main(string[] args)
{
Instance.Instantiate();
Referent.Refer(Instance.GetInstance());
Console.ReadLine();
}
}
public class Instance
{
private static Instance myInstance;
public void OnInstantiated()
{
Console.WriteLine("I have been instantiated.");
}
public void OnReferred()
{
Console.WriteLine("I have been referred to.");
}
public static void Instantiate()
{
myInstance = new Instance();
myInstance.OnInstantiated();
}
public static Instance GetInstance()
{
return myInstance;
}
}
public class Referent
{
public static void Refer(Instance instance)
{
if (instance != null)
{
instance.OnReferred();
}
else
{
Console.WriteLine("No instance to refer to.");
}
}
}

Raise Error, dispose object and re-create it

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.

How can we create a Singleton Instance for a Window?

I have searched for creating a Singleton object for a window in WPF.
public static Test DefInstance
{
get
{
if (formDefInstance == null) // formDefInstance.IsDisposed
{
initializingDefInstance = true;
formDefInstance = new cas18();
initializingDefInstance = false;
}
return formDefInstance;
}
set { formDefInstance = value; }
}
But the forDefInstance.IsDisposed is not working and throwing an error.
Any Idea regarding this?
I think everyone should take a look at Jon Skeet's C# In Depth site. If only to read and permanently burn into their brains the singleton patter a-la C#.
http://csharpindepth.com/Articles/General/Singleton.aspx
In your scenario, try to implement this (thread safe, non-lazy):
public sealed class DefInstance
{
private static readonly DefInstance instance = new DefInstance();
static DefInstance()
{
}
private DefInstance()
{
}
public static DefInstance Instance
{
get
{
return instance;
}
}
}
There are also Lazy<T> implementions and various other implementations of the pattern in that site.
I don't know if it's what you want to do but it works for me :
private static MyWindow _defInstance;
public static MyWindow DefInstance
{
get
{
if (null == _defInstance)
{
_defInstance = new MyWindow();
}
return _defInstance;
}
}
In MyWindow code :
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
this.Visibility = Visibility.Hidden;
e.Cancel = true;
}
To use it :
DefInstance.Show();
Then, only one window is display and you use one instance of your window.
you can achieve this by implementing following method
private static volatile DefInstance instance;
private static object syncRoot = new Object();
private DefInstance() {}
public static DefInstance Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DefInstance();
}
}
return instance;
}
}

global "class object" or global "server object"

I am doing a project including a custom OPC Client.
The Class Main represents the MainWindow in a WPF application.
The private field _opcServer will hold an object for further use.
Only one _opcServer object is allowed at any time.
I came up with this (it's all sample code and works fine)
// "Main" Class --> it's a WPF Window
public class Main
{
// the "global" server object
private OpcServer _opcServer = new OpcServer();
public Main() {}
private void connectOpcServer()
{
if(this._opcServer == null)
{
// the "global" server object
this._opcServer = this.opcClientFactory().connectOpcServer("someOpcServer");
if(this._opcServer != null)
{
// we made the connection
}
else
{
// connection failed
}
}
}
private void disconnectOpcServer()
{
if(this._opcServer != null)
{
if(this.opcClientFactory().disconnectOpcServer(this._opcServer))
{
// disconnected
this._opcServer = null;
}
else
{
// something went wrong
}
}
}
private OpcClient ocpClientFactory()
{
OpcClient opcClient = new opcClient();
return opcClient;
}
}
// Client Class
public class OpcClient
{
// the server object
private OpcServer _opcServer = new OpcServer();
public OpcClient() {}
public OpcServer connectOpcServer(string progID)
{
bool madeConnection = this._opcServer.Connect(progID);
if(madeConnection)
{
return this._opcServer;
}
else
{
return null;
}
}
public bool disconnectOpcServer(OpcServer opcServer)
{
this._opcServer = opcServer;
if(this._opcServer.disconnect())
{
this._opcServer = null;
return true;
}
return false;
}
}
Not much comments in the code but I think you get the point.
Every time connect or disconnect is triggered via user action, a new object of the OPC Client is created and the Server Object is passed in the one or the other direction.
There will be more methods (like read tags, etc ...) like this, but since the user should use them only once or twice per day, I see no problem with creating new objects and passing something between them.
But what if there is a real funny user who thinks he has to use these things (connect/disconnect/ etc...) all the time. Then I will end up creating many objects!
I gave it a thought and came up with this.
public class Main
{
// the client object
private OpcClient _opcClient = OpcClient.Instance;
public Main(){}
private void connectOpcServer()
{
if(this._opcClient.connectOpcServer("someOpcServer"))
{
// we made the connection and can now use
// this._opcClient.opcServer
}
else
{
// connection failed
}
}
private void disconnectOpcServer()
{
if(this._opcClient.disconnect())
{
// disconnected
}
else
{
// something went wrong
}
}
}
public class OpcClient
{
private static OpcClient _instance;
public static OpcClient Instance
{
get
{
if(instance == null)
{
_instance = new OpcClient();
}
return _instance;
}
}
private OpcClient()
{
this.opcServer = new OpcServer();
}
public OpcServer opcServer
{
get;
private set;
}
public bool connectOpcServer(string progID)
{
return this.opcServer.Connect(progID);
}
public bool disconnectOpcServer()
{
return this.opcServer.disconnect();
}
}
Now I create a singelton of the OPC Client and pass it to the main class. Now only one object will be created, the user can click connect/disconnect all day long.
What is the best way to proceed here?
Store the Server Object in the main class
Store the Class Object in the main class
Depends
Both are bad ideas (if so, why? What can I do instead?)
I am choosing the 2nd option.
By choosing the singleton approach I can make sure that there is only one Server Object.
This is very important.

C# Singleton pattern with triggerable initialization

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);
}
}
}

Categories