We need to use an unmanaged library in our code that has static methods. I'd like to introduce the library operation as a dependency in my code. And apart from having static methods, the library has an initialization method and a settings method, both are global. So I can't just wrap this in an instance class, because if one instance changes a setting, all other instances will be affected, and if one instance gets initialized, all other instances will be reinitialized.
I thought about introducing it as a singleton class. This way it will be in an instance class, but there will only be one instance thus I won't have to worry about changing the settings or initialization. What do you think about this approach? I'm pretty new to the dependency injection pattern and I'm not sure if the singleton pattern is a good solution? What would your solution be to a similar case?
Edit: The initialization takes a parameter too, so I can't just lock the method calls and re-initialize and change settings every time it is called.
Edit 2: Here are the signatures of some methods:
public static void Initialize(int someParameter)
// Parameter can only be changed by re-initalization which
// will reset all the settings back to their default values.
public static float[] Method1(int someNumber, float[] someArray)
public static void ChangeSetting(string settingName, int settingValue)
If you only need to set the settings once at start up, then I would recommend making a non-static wrapper class which does all the initialization of the static class in its own static constructor. That way you can be assured that it will only happen once:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
UnManagedStaticClass.Settings = ...;
}
public void Method1()
{
UnManagedStaticClass.Method1();
}
}
However, if you need to change the settings each time you call it, and you want to make your instances thread-safe, then I would recommend locking on a static object so that you don't accidentally overwrite the static settings while they're still in use by another thread:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
}
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you need to pass initialization parameters into your class's instance constructor, then you could do that too by having a static flag field:
public class MyWrapper
{
public MyWrapper(InitParameters p)
{
lock (lockRoot)
{
if (!initialized)
{
UnManagedStaticClass.Initialize(p);
initialized = true;
}
}
}
static bool initialized = false;
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you also need to re-initialize each time, but you are concerned about performance because re-initializing is too slow, then the only other option (outside of the dreaded singleton) is to auto-detect if you need to re-initialize and only do it when necessary. At least then, the only time it will happen is when two threads are using two different instances at the same time. You could do it like this:
public class MyWrapper
{
public MyWrapper(InitParameters initParameters, Settings settings)
{
this.initParameters = initParameters;
this.settings = settings;
}
private InitParameters initParameters;
private Settings settings;
static MyWrapper currentOwnerInstance;
static object lockRoot = new Object();
private void InitializeIfNecessary()
{
if (currentOwnerInstance != this)
{
currentOwnerInstance = this;
UnManagedStaticClass.Initialize(initParameters);
UnManagedStaticClass.Settings = settings;
}
}
public void Method1()
{
lock (lockRoot)
{
InitializeIfNecessary();
UnManagedStaticClass.Method1();
}
}
}
I would use a stateless service class, and pass in state info for the static class with each method call. Without knowing any details of you class, I'll just show another example of this with a c# static class.
public static class LegacyCode
{
public static void Initialize(int p1, string p2)
{
//some static state
}
public static void ChangeSettings(bool p3, double p4)
{
//some static state
}
public static void DoSomething(string someOtherParam)
{
//execute based on some static state
}
}
public class LegacyCodeFacadeService
{
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}
You'll have to fill in the blanks a little bit, but hopefully you get the idea. The point is to set state on the static object for the minimum amount of time needed, and lock access to it that entire time, so no other callers can be affected by your global state change. You must create new instances of this class to use it, so it is fully injectable and testable (except the step of extracting an interface, which I skipped for brevity).
There are a lot of options in implementation here. For example, if you have to change LegacyCodeState a lot, but only to a small number of specific states, you could have overloads that do the work of managing those states.
EDIT
This is preferable to a singleton in a lot of ways, most importantly that you won't be able to accumulate and couple to global state: this turns global state in to non-global state if it is the only entry point to your static class. However, in case you do end up needing a singleton, you can make it easy to switch by encapsulating the constructor here.
public class LegacyCodeFacadeService
{
private LegacyCodeFacadeService() { }
public static LegacyCodeFacadeService GetInstance()
{
//now we can change lifestyle management strategies later, if needed
return new LegacyCodeFacadeService();
}
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}
Related
I have a C# static class accessed from multiple threads. Two questions:
Are my private static fields thread safe when the field is initialized on declaration?
Should I lock when creating private static fields from within static constructor?
Usage of static class from different threads:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
string name = MyStaticClass.GetValue(9555);
//...
});
}
}
}
Option 1 of static class:
public static class MyStaticClass
{
private static MyClass _myClass = new MyClass();
public static string GetValue(int key)
{
return _myClass.GetValue(key);
}
}
Option 2 of static class:
public static class MyStaticClass
{
private static MyClass _myClass;
private static object _lockObj = new object();
static MyStaticClass()
{
InitMyClass();
}
private static void InitMyClass()
{
if (_myClass == null)
{
lock(_lockObj)
{
if (_myClass == null)
{
_myClass = new MyClass();
}
}
}
}
public static string GetValue(int key)
{
return _myClass.GetValue(key);
}
}
Instance class created from the static class:
public class MyClass
{
private Dictionary<int, Guid> _valuesDict = new Dictionary<int, Guid>();
public MyClass()
{
for (int i = 0; i < 10000; i++)
{
_valuesDict.Add(i, Guid.NewGuid());
}
}
public string GetValue(int key)
{
if (_valuesDict.TryGetValue(key, out Guid value))
{
return value.ToString();
}
return string.Empty;
}
}
Should I lock when initializing private static fields from within static constructor?
Let's not bury the lede here:
Never lock in a static constructor. Static constructors are already locked by the framework so that they run on one thread exactly once.
This is a special case of a more general bit of good advice: never do anything fancy with threads in a static constructor. The fact that static constructors are effectively locked, and that lock can be contested by any code that accesses your type, means that you can very quickly get into deadlocks that you did not expect and are hard to see. I give an example here: https://ericlippert.com/2013/01/31/the-no-lock-deadlock/
If you want lazy initialization, use the Lazy<T> construct; it was written by experts who know how to make it safe.
Are my private static fields thread safe when the field is initialized on declaration?
Thread safety is the preservation of program invariants when program elements are called from multiple threads. You haven't said what your invariants are, so it is impossible to say if your program is "safe".
If the invariant you are worried about is that the static constructor is observed to run before the first static method is executed, or the first instance is created, of a type, C# guarantees that. Of course, if you write crazy code in your static constructor, then crazy things can happen, so again, try to keep your static constructors very simple.
fields of static class are not thread safe by default and should avoid unless it is just for read purpose.
Here down side is "lock" as well, it will create serialized processing in multi threaded environment.
public static class MyStaticClass
{
private static MyClass _myClass;
private static object _lockObj;
static MyStaticClass()
{
_myClass = new MyClass();
_lockObj = new object();
}
public static string GetValue(int key)
{
return _myClass.GetValue(key);
}
public static void SetValue(int key)
{
lock(_lockObj)
{
_myClass.SetValue(key);
}
}
}
Your second version is preferable. You can lock it down a little bit more by making your field readonly:
public static class MyStaticClass
{
private static readonly MyClass _myClass = new MyClass();
public static string GetValue(int key)
{
return _myClass.GetValue(key);
}
}
Your intent appears to be that _myClass is initially set to an instance of MyClass and never set to another. readonly accomplishes that by specifying that it can only be set once, either in a static constructor or by initializing it as above. Not only can another thread not set it, but any attempt to change it will result in a compiler error.
You could omit readonly and just never set _myClass again, but readonly both communicates and enforces your intent.
Here's where it gets trickier: Your reference to an instance of MyClass is thread safe. You don't have to worry about whether various threads will replace it with a different instance (or set it to null), and it will be instantiated before any threads attempt to interact with it.
What this does not do is make MyClass thread safe. Without knowing what it does or how you interact with it, there's no way for me to say what the needs or concerns are.
If that is a concern, one approach is to use a lock to prevent concurrent access that shouldn't occur, exactly as #Mahi1722 demonstrated. I'm including the code from that answer (not to plagiarize, but if anything happens to that answer then this one will refer to an answer that doesn't exist.)
public static class MyStaticClass
{
private static MyClass _myClass = new MyClass();
private static object _lockObj = new object();
public static string GetValue(int key)
{
return _myClass.GetValue(key);
}
public static void SetValue(int key)
{
lock(_lockObj)
{
_myClass.SetValue(key);
}
}
}
Both methods that interact with _myClass lock using _lockObject which means that any execution of either will block while another thread is executing either.
That's a valid approach. Another is to actually make MyClass thread safe, either by using concurrent collections or implementing such locks within that class. That way you don't have to use lock statements in every class that uses an instance of MyClass. You can just use it knowing that it manages that internally.
Both are correct,
but there is no need to lock inside static constructor.
So, i will choose the first option, it is shorter and clearer
I am wondering if this class is thread safe
Can I access the Currencies property's getter without performing a lock?
Should I lock my access to the Currencies property within the GetLiveExchangeRates() method?
public class CurrencyManager
{
public static List<CurrencyModel> Currencies { get; private set; }
private static readonly object LockObj = new object();
public CurrencyManager()
{
Currencies = new List<CurrencyModel>();
}
public static void GetLiveExchangeRates()
{
lock (LockObj)
{
Currencies = GetSomeFooLiveDataFromInternet();
}
}
}
EDIT
How would you refactor it?
If you must stick with a static class, I would refactor the class like this:
public class CurrencyManager
{
private static readonly IEnumerable<CurrencyModel> currencies = Enumerable<CurrencyModel.Empty();
private static readonly object LockObj = new object();
public static void RefreshLiveExchangeRates()
{
lock (LockObj)
{
CurrencyManager.currencies = GetSomeFooLiveDataFromInternet();
}
}
public static IEnumerable<CurrencyModel> GetCurrencies()
{
return CurrencyManager.currencies;
}
}
Renaming the method to something that better describes what is actually happening. When you call it GetLiveExchangeRates, I would expect it to return back the exchange rates rather than void. I'd then delete the constructor all together and create a GetCurrencies() method that returns the collection, or an empty one if the collection is null. It seems like the collection you are exposing, Currencies, should not be exposed publicly as a List as that allows consumers to change it. You haven't explained what the point of the collection is, so I'm making an assumption by trying to infer what is happening through your naming conventions.
If I were to write this, I would probably hide this behind a service instead. Removing the need for the static class. You hold a reference to the exchange rates in your view model/controller/service what-have-you. When you need to refresh them, hit the service again.
Service
public class CurrencyService
{
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
return GetSomeFooLiveDataFromInternet();
}
}
Consumer (viewmodel/controller etc)
public class MyController
{
private IEnumerable<CurrencyModel> currentRates;
public MyController()
{
// Instance a new service; or provide it through the constructor as a dependency
var currencyService = new CurrencyService();
this.currentRates = currencyService.GetLiveExchangeRates();
}
}
Then your consuming class would use the collection it fetched from the service. If it wants to, it can pass around that collection to other objects that depend on it. When you feel the collection is stale, you re-fetch them from the service. At this point, you probably wouldn't need to do any locking because only the consumer can use the property and can control when it can and will change the property. This lets multiple instances query for the latest exchange rates without having to do a lock and make everyone queue up to receive them.
Ideally, I'd like to see it passed in as a dependency via the constructor, hidden behind an interface, with the rates refreshed at the time they are needed. So instead of fetching the rates in the constructor, I would fetch them lazily when needed. This would let you do the work async (assuming your real implementation is async).
Edit
If you are storing the collection in the static class for caching purposes, you could store the collection in the service, and always return the collection. The only time a new set of exchange rates is returned is when you clear the cache.
public class CurrencyService
{
private static IEnumerable<CurrencyModel> currencyRates;
private static object ratesLock = new object();
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
if (currencyRates == null)
{
lock (ratesLock)
{
currencyRates = GetSomeFooLiveDataFromInternet();
}
}
return currencyRates;
}
public void ClearRates()
{
currencyRates = null;
}
}
This is more or less an implementation change. Your controller/viewmodel would continue to hit GetLiveExchangeRates(), but it would only fetch them once from your external service. Each time afterwards it would just return the cache. You only pay the locking fee once, then when other objects hit your service concurrently you don't pay the locking fee again.
I have some classes that caches data from a database, these classes are loaded with data when their static constructor gets called.
I need to call a static Reload method at all these classes, except those that is not initialized yet.
E.g.: City caches data from a database
public class City
{
public City Get(string key)
{
City city;
FCities.TryGetValue(key, out city);
return city;
}
private static Dictionary<string, City> FCities;
static City()
{
LoadAllCitiesFromDatabase();
}
public static void Reload()
{
LoadAllCitiesFromDatabase();
}
private static void LoadAllCitiesFromDatabase()
{
// Reading all citynames from database (a very slow operation)
Dictionary<string, City> loadedCities = new Dictionary<string, City>();
...
FCities = loadedCities;
}
}
The problem is that City might not have been used yet (it might not be used in this service) and there is no reason to load it from the database then.
My reload all method looks much like this:
public static class ReloadAll
{
public static void Do()
{
foreach (Type classType in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t.IsClass && !t.IsAbstract))
{
MethodInfo staticReload = classType.GetMethods().FirstOrDefault(m => m.IsStatic && m.IsPublic && m.ReturnType == typeof(void) && m.Name == "Reload" && m.GetParameters().Length == 0);
if (staticReload != null)
{
if (StaticConstructorHasBeenCalled(classType))
staticReload.Invoke(null, null);
}
}
}
private bool StaticConstructorHasBeenCalled(Type classType)
{
// How do I check if static constructor has been called?
return true;
}
}
I need a little help with implementing StaticConstructorHasBeenCalled.
At first glance, I thought this could be an issue where <grin> Quantum Mechanical Copenhagen interpretation might apply ("As soon as you look at it, it changes"). </grin> I.e. anything you do in the class to observe whether it has been initialized would probably cause it to initialize itself...
But you don't have to do it in the class, just keep a list somewhere else (other than in any of these static classes) that is populated by every static class when it gets initialized. Then in your reset function, just iterate through the classes in the list.
If you have several of these classes, how about controlling their instantiation through a factory or manager class.
This could keep track of which have been used and call the reload methods where appropriate.
You should not use long-running operations in the static constructor, or at least, they should not run synchronously. Static constructor run implicitly, and when implicit execution takes significant time, it makes for interesting bugs :)
Also, if you do use static constructors, methods and whatnot that maintain state, try to isolate them in a fully static class, so they will, for most scenarios, act like singletons. I would change the implementation to something along these lines:
public static class CityRepository
{
private static bool areCitiesLoaded;
private List<City> cities;
static CityRepository()
{
areCitiesLoaded = false;
cities = new List<City>();
}
//method that will be called in all other method, to ensure
//that the cities are loaded
private static void EnsureLoad()
{
if (!areCitiesLoaded)
{
LoadAllCitiesFromDatabase();
areCitiesLoaded = true;
}
}
}
public class City {} //city instance methods
you could use the singleton pattern, and add a field that will tell you if the unique instance has already been created
actually no need to make a singleton, just keep your static class, and load the data when the property getter that should return it is called:
static class City
{
static bool _loaded = false;
public bool Loaded { get { return _loaded; } }
public static List<C> Data
{
get
{
if (!_loaded)
{
doLoading();
_loaded = true
}
}
}
}
I asked if there was any way to see if a static constructor was called. I think that the answer was no, but a workaround would be to create a manager that could keep track of repositories.
The goal was to change as little as possible to the existing classes.
My solution to a manager class is:
public static class RepositoryManager
{
public delegate void Reload();
private static List<Reload> FRepositories = new List<Reload>();
public static void Register(Reload repository)
{
lock (FRepositories)
{
FRepositories.Add(repository);
}
repository();
}
public static void ReloadAll()
{
List<Reload> list;
lock (FRepositories)
{
list = new List<Reload>(FRepositories);
}
foreach (Reload repository in list)
repository();
}
}
Using the example with the City class the changes would be limited to the static constructor.
public class City
{
// ...
static City()
{
RepositoryManager.Register(LoadAllCitiesFromDatabase);
}
// ...
}
My ReloadAll method would then be as simple as:
public void ReloadAll()
{
RepositoryManager.ReloadAll();
}
Thank you for all your answers, I have rewarded each of you that suggested some kind of a manager as a solution to the problem.
The drawback of this solution is that whenever someone creates a repository that needs to be reloaded/updated/cleared once in a while they have to remember to use the RepositoryManager.
I have a method which should return a snapshot of the current state, and another method which restores that state.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
The state Snapshot class should be completely opaque to the caller--no visible methods or properties--but its properties have to be visible within the MachineModel class. I could obviously do this by downcasting, i.e. have CurrentSnapshot return an object, and have RestoreSnapshot accept an object argument which it casts back to a Snapshot.
But forced casting like that makes me feel dirty. What's the best alternate design that allows me to be both type-safe and opaque?
Update with solution:
I wound up doing a combination of the accepted answer and the suggestion about interfaces. The Snapshot class was made a public abstract class, with a private implementation inside MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Because the constructor and methods of Snapshot are internal, callers from outside the assembly see it as a completely opaque and cannot inherit from it. Callers within the assembly could call Snapshot.Restore rather than MachineModel.Restore, but that's not a big problem. Furthermore, in practice you could never implement Snapshot.Restore without access to MachineModel's private members, which should dissuade people from trying to do so.
Can MachineModel and Snapshot be in the same assembly, and callers in a different assembly? If so, Snapshot could be a public class but with entirely internal members.
I could obviously do this by
downcasting, i.e. have CurrentSnapshot
return an object, and have
RestoreSnapshot accept an object
argument which it casts back to a
Snapshot.
The problem is that somebody could then pass an instance of an object which is not Snapshot.
If you introduce an interface ISnapshot which exposes no methods, and only one implementation exists, you can almost ensure type-safety at the price of a downcast.
I say almost, because you can not completely prevent somebody from creating another implementation of ISnapshot and pass it, which would break. But I feel like that should provide the desired level of information hiding.
You could reverse the dependency and make Snapshot a child (nested class) of MachineModel. Then Snapshot only has a public (or internal) Restore() method which takes as a parameter an instance of MachineModel. Because Snapshot is defined as a child of MachineModel, it can see MachineModel's private fields.
To restore the state, you have two options in the example below. You can call Snapshot.RestoreState(MachineModel) or MachineModel.Restore(Snapshot)*.
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Example:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
* It would be neater to have Snapshot.RestoreState() as internal and put all callers outside the assembly, so the only way to do a restore is via MachineModel.RestoreState(). But you mentioned on Jon's answer that there will be callers inside the same assembly, so there isn't much point.
This is an old question, but i was looking for something very similar and I ended up here and between the information reported here and some other I came up with this solution, maybe is a little overkill, but this way the state object is fully opaque, even at the assembly level
class Program
{
static void Main(string[] args)
{
DoSomething l_Class = new DoSomething();
Console.WriteLine("Seed: {0}", l_Class.Seed);
Console.WriteLine("Saving State");
DoSomething.SomeState l_State = l_Class.Save_State();
l_Class.Regen_Seed();
Console.WriteLine("Regenerated Seed: {0}", l_Class.Seed);
Console.WriteLine("Restoring State");
l_Class.Restore_State(l_State);
Console.WriteLine("Restored Seed: {0}", l_Class.Seed);
Console.ReadKey();
}
}
class DoSomething
{
static Func<DoSomething, SomeState> g_SomeState_Ctor;
static DoSomething()
{
Type type = typeof(SomeState);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
Random c_Rand = new Random();
public DoSomething()
{
Seed = c_Rand.Next();
}
public SomeState Save_State()
{
return g_SomeState_Ctor(this);
}
public void Restore_State(SomeState f_State)
{
((ISomeState)f_State).Restore_State(this);
}
public void Regen_Seed()
{
Seed = c_Rand.Next();
}
public int Seed { get; private set; }
public class SomeState : ISomeState
{
static SomeState()
{
g_SomeState_Ctor = (DoSomething f_Source) => { return new SomeState(f_Source); };
}
private SomeState(DoSomething f_Source) { Seed = f_Source.Seed; }
void ISomeState.Restore_State(DoSomething f_Source)
{
f_Source.Seed = Seed;
}
int Seed { get; set; }
}
private interface ISomeState
{
void Restore_State(DoSomething f_Source);
}
}
I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.
I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,
Additional question.
The idea of singleton is good, but I have the following questions:
If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.
I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late
thanks
pradeep
Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.
For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx
EDIT
The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.
Instead of a static class, have a static instance of a class:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
You can also delegate to an instance of the class:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.
EDIT: Additional question
When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.
Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.
You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, e.g. when you have to pass the object as a parameter.
Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (e.g., "using...").
The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
Building on Ahemd Said's answer: (and props to him!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(untested... but mostly right, I think)
You could also add in usage of the IDispose interface for more cleanup.
You can create a method in the static class which resets the values of all properties.
Consider you have a static class
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
Now you can use any of the below approaches from any other class to reset value of a static class
Approach 1 - Calling directly
ClassA.ResetValues();
Approach 2 - Invoking method dynamically from a known namespace and known class
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Approach 3 - Invoking method dynamically from an assembly/set of assemblies
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.
Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.
Eg I have a logger class as follows:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
In my constructor of my Form I call the following to setup the logger.
Logger.InitLogger(LogError);
Then from any class in my project I can do the following:
Logger.LogError("error",new Exception("error), true);