[ACCEPTED]-Disposable singleton in C#-dispose
At that point I don't think I'd really consider 14 it to be a singleton any more, to be honest.
In 13 particular, if a client uses a singleton 12 they're really not going to expect that 11 they have to dispose of it, and they'd be 10 surprised if someone else did.
What's your 9 production code going to do?
EDIT: If you 8 really, really need this for unit tests 7 and only for unit tests (which sounds questionable 6 in terms of design, to be frank) then you 5 could always fiddle with the field using 4 reflection. It would be nicer to work out 3 whether it should really be a singleton or whether 2 it should really be disposable though - the two 1 very rarely go together.
Mark Release
as internal
and use the InternalsVisibleTo
attribute to expose 10 it only to your unit testing assembly. You 9 can either do that, or if you're wary someone 8 in your own assembly will call it, you can 7 mark it as private
and access it using reflection.
Use 6 a finalizer in your singleton that calls 5 the Dispose
method on the singleton instance.
In 4 production code, only the unloading of an 3 AppDomain
will cause the disposal of the singleton. In 2 the testing code, you can initiate a call 1 to Release
yourself.
Singletons should not be Disposable. Period. If 2 someone calls Dispose prematurely, your 1 application is screwed until it restarts.
public class Foo : IDisposable
{ [ThreadStatic] static Foo _instance = null;
private Foo() {IsReleased = false;}
public static Foo Instance
{ get
{ if (_instance == null) _instance = new Foo();
return _instance;
}
}
public void Release()
{ IsReleased = true;
Foo._instance = null;
}
void IDisposable.Dispose() { Release(); }
public bool IsReleased { get; private set;}
}
0
You could use a nested lazy singleton (See 7 here) with some simple modifications:
public sealed class Singleton : IDisposable
{
Singleton()
{
}
public static Singleton Instance
{
get
{
if (!Nested.released)
return Nested.instance;
else
throw new ObjectDisposedException();
}
}
public void Dispose()
{
disposed = true;
// Do release stuff here
}
private bool disposed = false;
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
Remember 6 to throw ObjectDisposedException in all 5 public methods/properties of the object 4 if it has been disposed.
You should also, provide 3 a finalizer method for the object, in case 2 Dispose doesn't get called. See how to correctly 1 implement IDisposable here.
If the class implements IDisposable (as 1 you imply it does) then just call x.Dispose()
For unit tests you could use a "manual" instance 18 (but you would need a way to instantiate 17 the object).
In your case, probably you should 16 better use the factory pattern (abstract/method 15 - whichever is the best for your case), combined 14 with a singleton.
If you want to test if 13 the singleton has disposed properly of the 12 used objects (in unit test), then use the 11 Factory method, otherwise use the singleton 10 pattern.
By the way, if you don't have access 9 to the singleton source code or you are 8 not allowed to modify it, you would better 7 wrap it to another singleton, and provide 6 all the logic from the new one (more like 5 a proxy). It sounds like overkill, but it 4 could be a viable solution.
Also, in order 3 to be able to control the access to it, provide 2 a factory, and let the clients get the new 1 object only if the object hasn't been disposed.
Another option to make a disposable Singleton 3 is to use SandCastle's [Singleton] atribute for your 2 class, then Castle framework takes care 1 of disposing all disposable Singleton objects
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.