public class MyClass
{
// private fields
//////////////////////////////////////////////////////////////////////////
public MyClass(string param1, string param2)
{
// do some stuff
}
private static object syncRoot = new Object();
private static volatile MyClass instance = null;
public static MyClass Log
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new MyClass();
}
}
return instance;
}
}
private MyClass()
{
// do some stuff
}
public void myFunction(string txt, uint flags)
{
// do some stuff
}
}
This is my class and I use it this way
MyClass.Log.myFunction("some string", flags);
But constantly get that either MyClass is null or MyClass.Log is null when i use this class in other class functions.
What do I do wrong?
In addition to the question here is the error i get:
System.NullReferenceException: Object reference not set to an instance of an object.
at MyNamespace.MyClass..ctor()
at MyNamespace.MyClass.get_Log()
The code you showed looks good.
MyClass can't be null as it is a class. Log shouldn't be null either, your singleton implementation looks OK.
My guess is that the problem is that you are using the parameterless constructor of MyClass. I guess that myFunction somehow uses something that is only initialized in the constructor that takes the two parameters.
Actually, according to your stack trace the problem is inside the parameterless constructor. I guess you are trying to log something in there, like this : instance.Log(...);. That won't work, because at that point instance is still null. You should simply use Log(...) instead.
Related
After loading a DLL and obtaining a type, I get an exception trying to instantiate it:
Assembly dll = Assembly.LoadFrom(#"C:\path\file.dll");
Type type = dll.GetType("namespace.CustomClass");
object obj = Activator.CreateInstance(type); // <-- System.MissingMethodException
"No constructor with 0 parameters defined for this object" (average translation)
Exploring the loaded type, I can see the DeclaredConstrunctors -> {Void .ctor()}
But calling type.GetConstructors() I get an empty array (I guess that means that only default constructor exists?)
I neither found any factory class that returns an object of my class, or an getInstance function.
Any idea how to proceed?
There are a few possibilities here.
The first is that the all of the defined parameters take parameters. There's no guarantee that every class has a 0-parameter constructor. Here's an example of some code that produces this error:
public class SomeCons
{
public SomeCons(string cons)
{
}
}
static void Main(string[] args)
{
object result = Activator.CreateInstance(typeof(SomeCons));
}
The second possibility namespace.CustomClass has a private constructor. The following code produces similar behavior to what you saw. I also included an example of how to find the actual constructor - you want to use Binding Flags.
private class NoCons
{
private NoCons()
{
}
}
static void Main(string[] args)
{
// As you saw, this shows one declared constructor
Type exploratory = typeof(NoCons);
// Returns nothing
ConstructorInfo[] constructors = typeof(NoCons).GetConstructors();
// Returns 1 constructor
constructors = typeof(NoCons).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
Please note that it may be important to understand exactly why namespace.CustomClass has a private constructor in the first place. That's actually a really common thing to do if you're trying to define a Singleton, in which case you probably don't want to call the constructor directly.
For a singleton like this:
private class NoCons
{
private NoCons()
{
}
private static NoCons _instance;
public static NoCons Instance
{
get
{
if (_instance == null)
{
_instance = new NoCons();
}
return _instance;
}
}
}
try something like this:
Type exploratory = typeof(NoCons);
PropertyInfo singletonProperty = exploratory.GetProperties(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(prop => prop.Name.Contains("Instance"));
string name = singletonProperty.GetGetMethod().Name;
var noCons = exploratory.GetMethod(name).Invoke(null, null) as NoCons;
The DLL had a related OCX file placed in another folder.
The file has been registered using:
Regsvr32 .\file.ocx
After that, I've been able to instantiate an object calling:
using Microsoft.VisualBasic;
MyAssemblyName object = (MyAssemblyName) Interaction.CreateObject( "MyNamespace.MyAssemblyName", "");
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have two singleton classes in my project.
public class VStateManager : IVState
{
private static readonly object _createLock = new object();
private static VStateManager _vsManager = null;
public static VStateManager GetVStateManager()
{
lock (_createLock)
{
if (_vsManager == null)
{
return new VStateManager();
}
return _vsManager;
}
}
}
public class VTRFactory : IVTR
{
private static VehicleFactory _VTRFactory =null;
private static readonly object _createLock = new object();
public static VehicleFactory GetVTRFactory()
{
lock(_createLock)
{
if(_VTRFactory == null)
{
return new VTRFactory();
}
return _VTRFactory;
}
}
}
My colleague suggested to create a singleton class (something like a singleton factory) that accepts a generic interface and produces both these singleton objects
How can this be done.?
First of all, your classes aren't implementing singleton at all. Look at this:
if (_vsManager == null)
{
return new VStateManager();
}
return _vsManager;
_vsManager will be always null, so multiple instances will be created each time you access the instance. It should be:
if (_vsManager == null)
{
_vsManager = new VStateManager();
}
return _vsManager;
That's the way you ensure only one instance will be created.
Also, I would use a property instead of a function, it's more clear:
public class VStateManager : IVState
{
private static readonly object _createLock = new object();
private static VStateManager _vsManager = null;
public static VStateManager Instance
{
get
{
lock (_createLock)
{
if (_vsManager == null)
{
_vsManager = new VStateManager();
}
return _vsManager;
}
}
}
}
Then you can use per example VStateManager.Instance.XXX.
Second, why you need a third class to create those singletons? When you need to use them accessing GetXXXX would create the needed instance, is there any reason to create those instances before you need them?
If you really need those instances to be initialized before they are needed then you can do something very simple like this:
public static class Initializer()
{
public static void Init()
{
var a = VStateManager.GetVStateManager();
var b = VehicleFactory.GetVTRFactory();
}
}
Then to initialize just call Initializer.Init(). Overcomplicating the code without any reason is the root of all evil in programming, don't try to solve a problem that doesn't exists as that solution can create real problems.
The singleton factory you are looking for can be created using generics. You need to pass the type for which you need to create a singleton instance and the factory will return an instance of that type with making sure that only one instance of that type is created.
The very basic implementation of such singleton factory would look as following.
public static class SingletonFactory
{
private static readonly object lockObject = new object();
//Dictionary to store the singleton objects
private static readonly Dictionary<string, object> singletonObjects = new Dictionary<string, object>();
// Method to retrieve singleton instance.
// Note the constraint "new ()". This indicates that this method can be called for the types which has default constructor.
public static T GetSingletoneInstance<T>() where T:new ()
{
var typeName = typeof(T).Name;
T instance;
lock (lockObject)
{
// Check in the dictionary if the instance already exist.
if (singletonObjects.ContainsKey(typeName))
{
//Retrieve the instance from the dictionary.
instance = (T) singletonObjects[typeName];
}
else
{
// If it does not exist in the dictionary,
// create a new instance
// and store it in the dictionary.
lock (lockObject)
{
instance = new T();
singletonObjects.Add(typeName, instance);
}
}
}
// Return the instance of type "T" either retrieved from dictionary
// or the newly created one.
return instance;
}
}
Following is how you use this factory.
class Program
{
static void Main(string[] args)
{
var vstateManager = SingletonFactory.GetSingletoneInstance<VStateManager>();
var vehicleFactory = SingletonFactory.GetSingletoneInstance<VehicleFactory>();
Console.ReadKey();
}
}
The implementation of SingletonFactory is a very basic version. And it has limitation that it can be used only for the types which have default constructor.
But it can be further extended to use DI module to initialize the instances without worrying about their constructors. Also it can be extended to store the instances in somewhere else then dictionary such as cache, memcaches or database.
I hope this would help you get whatever you are looking for.
I am working on some code which is something like this:
class A
{
static SomeClass a = new Someclass("asfae");
}
Someclass contains the required constructor.
The code for this compiles fine without any warning. But I get a code hazard in system:
"The Someclass ctor has been called from static constructor and/or
static initialiser"
This code hazard part of system just to make it better by warning about possible flaws in the system or if system can get into bad state because of this.
I read somewhere on the web that static constructor/initialiser can get into deadlock in c# if they wait for a thread to finish. Does that have something to do with this?
I need to get rid of this warning how can i do this.
I can't make the member unstatic as it's used by a static function.
What should I do in this case , Need help.
You could hide it behind a property and initialize it on first use (not thread-safe);
class A
{
static SomeClass aField;
static SomeClass aProperty
{
get
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
or use Lazy (thread-safe):
class A
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
...or this very verbose thread safe version :)
class A
{
static SomeClass aField;
static object aFieldLock = new object();
static SomeClass aProperty
{
get
{
lock (aFieldLock)
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
}
By initialising it as a static field, it behaves as it would in a static constructor, i.e. it probably gets initialised the first time an instance of your class is instantiated, but might happen earlier. If you want more control over exactly when the field is initialised, you could use Lazy<T>, e.g.:
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
This way, you know that the initialisation of SomeClass will only happen the first time the field is accessed and its Value property called.
I think to understand your problem you need to know the difference between static constructors and type initializers, there is a great article from Jon Skeet about this issue:
http://csharpindepth.com/Articles/General/Beforefieldinit.aspx
The point is that following constructions are not the same, and there are difference in the behavior:
class Test
{
static object o = new object();
}
class Test
{
static object o;
static Test()
{
o = new object();
}
}
In any case, you could try to create a static constructor for your class to be able to have more control on this initialization, and maybe the warning will disappear.
If the member is only used by a static method, and only by this one, I would recommend you to put it in the scope if this static method and not as class member.
I have a MyObject that creates a static devDrv from an external DLL. If devDrv is created by the MyObject constructor. code works fine. If devDrv is created by one of the MyObject.Connect(see 2nd object below), the first call to MyObject.Connect() works fine. On the second call, I'll get this error: "COM object that has been separated from its underlying RCW cannot be used". It seems like the devDrv is not persistent. I would like this devDrv object to be created by MyObject.Connect as seen in the 2nd object below. I'll appreciate your help.
// this code works fine.
public sealed class MyObject
{
static ExtDeviceDriver devDrv;
public MyObject()
{
devDrv = new ExtDeviceDriver();
}
public void Connect()
{
devDrv.connect();
}
}
//this code causes exception.
public sealed class MyObject
{
static ExtDeviceDriver devDrv;
public MyObject()
{
// do not create devDrv here.
//devDrv = new ExtDeviceDriver();
}
public void Connect()
{
if (devDrv == null)
devDrv = new ExtDeviceDriver();
devDrv.connect();
}
}
I would create static constructor instead of this way
public class MyObject
{
static ExtDeviceDriver devDrv;
static MyObject()
{
devDrv = new ExtDeviceDriver();
}
public void Connect()
{
devDrv.connect();
}
}
but it seems that the problem is from ExtDeviceDriver and not with your code, may be you aren't allowed to connect twice
I have a singleton and when I call it from my UnitTest I get
"System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'mycompany.class'threw an exception"
public sealed class MySingleton
{
private static MySingleton instance = new MySingleton();
private MySingleton()
{
ConnectionString = GetConnectionstring();
}
public static MySingleton NewConnectivity
{
get { return instance ?? (instance = new MySingleton()); }
}
public string ConnectionString { get; set; }
private static string GetConnectionstring()
{
return "bla";
}
}
I can't see much from what is there... Bu if you have a static field-initialiser, why does the property need to check for null? Actually I suspect this is due to the field initialiser running before other code in the static constructor etc.
I would try removing the field initialiser - but note that without this there is an edge case (timing/thread-race) that could result in more than one object being created. If that isn't acceptable there are lots of ways of avoiding this thread race.
A TypeInitializationException occurs when your static constructor in the class "mycompany.class" throws an exception. Try to put a breakpoint in your static constructor and step into each call? Do you get some other exception in that case?