I have a class instance which is created by using Activator.CreateInstance() method. That class instance contains helper methods which are frequently used throughout the application. In order to avoid creating the instance multiple times, I'm just thinking about implementing an appropriate caching mechanism.
The following consideration should be taken into account:
1) I can't use static class and methods.
2) There are around 6 instances (1 instance per class) per App Domain.
Your suggestion would be much appreciated!
If you want to avoid creating it multiple times, then don't use the ASP.Net cache object. The cache object specifically does not guarantee that anything you put in it will remain there. In fact it's one of the first things to be cannibalized if the server needs to free up resources.
A better option would be to use the HttpApplicationState object, which should be used to store objects that need to be globally accessible to all sessions. It also has built in thread safety if you access it properly.
The code to do it is as follows:
HttpContext.Current.Application.Lock();
HttpContext.Current.Application["myObject"] = myObject;
HttpContext.Current.Application.Unlock();
Utilizing it is just
var myObject = (MyObject)HttpContext.Current.Application["myObject"];
Use a singleton pattern:
class MySingleton {
private static MySingleton instance;
public MySingleton {
if(instance != null)
// One already created, the only call to this
// should come through Activator
throw...
instance = this;
}
public static MySingleton GetInstance() {
if(instance == null) instance = new MySingleton();
return instance;
}
}
The activator uses the public constructor. Then you can still retrieve the instance through GetInstance().
Ad 1) How about a static container for your instance? Along the lines of a singleton pattern?
Ad 2) 6 singletons or one static generic singleton class.
P.S.: I guess the static restriction is meant only for the helper class itself?
P.P.S.: Using HttpContext.Current.Application would be pretty much the same approach, except slower.
Sounds like a case for a dependency injection container. No matter which one you pick, they all have support for caching like a singleton, and it will do the Activator.CreateInstance part for you.
I like NInject for it's simplicity.
Related
I've been experimenting with the SimpleServiceLocator, and I like it quite a bit, but there's one thing that I'm really frustrated by--you can't use automatic constructor injection for singletons. To make matters worse, you can't even use automatic constructor injection for its dependencies. You have to create the singleton object, all it's dependencies, all its dependencies dependencies, etc. manually.
Why is SimpleServiceLocator designed this way?
Aren't singletons supposed to be just like regular instances except that, upon the first request for an instance, that instance is stored and reused instead of a new one being created each time? Why does SimpleServiceLocator require an instance to be provided during the registration process rather than just allow the instance to be created and stored on first request?
I get that the point of SimpleServiceLocator is to not have a lot of bells and whistles and be really easy for beginners to use, but it seems like it's just designed incorrectly, and that the method for registering a singleton should be identical to the method for registering a regular instance except that the method name should be RegisterSingle<T>() instead of Register<T>(). Is there a reason for the more complicated (and seemingly less convenient) design I'm just not getting?
Meanwhile, is there another (preferably free) IOC container I can use that let's me register objects in code similarly to the SimpleServiceLocator but does allow automatic contructor injection for singletons (or at least allows automatic constructor injection for the dependencies of the singleton)?
The RegisterSingle<T> method is just a fancy helper method just to make life easier. What you can do with RegisterSingle<T> can also be done with the Register<T> method. The web site gives examples of this. You can register a single instance using the Register<T> method as follows (it uses a closure):
var weapon = new Katana();
container.Register<IWeapon>(() => weapon);
When you look at the lifestyle management examples on the web site, you can see the following example for creating a thread static instance:
[ThreadStatic]
private static IWeapon weapon;
container.Register<IWeapon>(
() => return weapon ?? (weapon = new Katana()));
I think this is the power of simplify, because there is almost nothing you can't do with this pattern. What you are trying to achieve is a bit harder, I must admit this, but nothing really advanced IMO. Here is the code you need to solve your problem:
private static IWeapon weapon;
container.Register<IWeapon>(
() => weapon ?? (weapon = container.GetInstance<Katana>()));
The trick is here to store the instance in a static variable (just as with the thread static), but now you should not create the instance yourself by newing it up, but you delegate the creation to the Simple Service Locator. This works, because –as you know- the SimpleServiceLocator will do automatic constructor injection when a concrete type is requested.
I must admit that it is a shame that we need to do this trickery. It would be nice if the library could actually do this for us. For instance, I can imagine a RegisterSingle<T> overload being added that allows us to do the following:
container.RegisterSingle<IWeapon>(
() => container.GetInstance<Katana>());
Please let me know what you think of such an overload. I'm always interested in feedback to make the library better. This would certainly be a nice feature for the next release.
Update:
Since release 0.14 we can do the following:
container.RegisterSingle<IWeapon, Katana>();
It won't get any easier than this.
Cheers
A typical singleton implementation has a private constructor, so the container cannot "see" it, call it, or detect dependencies.
Perhaps you are referring to the lifetime management features of some IoC containers, where you can configure the container to always return the same single instance of a class.
This is not what singleton means. Although the container returns the same instance, nothing prevents you from instantiating an instance in code using new.
A singleton, on the other hand, can only ever be instantiated once from any source (once per thread in some implementations). It does not expose a public constructor, rather a static method such as:
public class MySingleton
{
// note: not a thread-safe implementation
static MySingleton instance;
static DependencyThing thing;
private MySingleton(DependencyThing thing)
{
MySingleton.thing = thing;
}
public static MySingleton GetMySingleton(DependencyThing thing)
{
if(instance == null) instance = new MySingleton(thing);
return instance;
}
}
As you can see, you can't call new MySingleton() from outside the class itself. To "instantiate" the a MySingleton, you have to call MySingleton.GetMySingleton(thing). This call returns the sole instance or creates and then returns it.
SimpleServiceLocator has no way of knowing how to create this object, or from where to detect its dependencies.
This ability could be added if the API exposed something like
public void Register<T>(Expression<Func<T>> staticFactoryMethod)…
…in which case you could call Register(() => MySingleton.GetMySingleton());, but this would only work without parameters. There would have to be more overloads:
public void Register<T, TParam1>(Expression<Func<TParam1, T>> staticFactoryMethod)…
public void Register<T, TParam1, TParam2>(Expression<Func<TParam1, TParam2, T>> staticFactoryMethod)…
…so that the container would know what dependencies to instantiate and pass to the specified factory method.
All that said, it doesn't really make sense to have dependency injection with a singleton. Each subsequent call to GetMySingleton would have to ignore the arguments or alter the state of the singleton, which is almost certainly a very bad idea.
Using a Singleton class guarantees one instance of a class to give control to the programmer. Really useful.
I was wondering if for example a Singleton Interface existed in a given framework to bypass the need to create/add one explicitly?
Would be handy to decalre:
public sealed class MySingleton : ISingleton //or a different class
{ ... }
And then expect the class to only ever be instantiated once.
Is this a good idea, or am I thinking a bit off the mark? :)
I was wondering if for example a Singleton Interface existed in a given framework to bypass the need to create/add one explicitly?
It doesn't and can't exist. A singleton basically requires a static Singleton getInstance() method, but because it's static, it cannot be definied as an abstract (interface) method. It also makes sense, there can be only one singleton implementation, not multiple. Abstracting it is pointless.
You'll need to boilerplate complete singletons yourself. I however highly question how that's useful. It's certainly not its sole purpose to prevent stackoverflow or memory errors. Writing good code prevents that. Singletons are only useful if you want to have the enduser to deal with the same instance all the time. Which can be done as good without the singleton pattern by the way. Either just declare it static or make use of the "application scope" concept the average framework can provide you.
Instead of singletons, rather look for inversion of control (dependeny injection). That's by the way also exactly what Spring is doing. They do not use "pure" singletons. It was a poor word choice they made.
See also:
Singletons are evil
Patterns I hate #1: Singleton
Inversion of Control and Dependency Injection pattern
A Spring Singleton is not a Singleton
Singleton does not prevent stack overflow, not sure what you are getting at with that.
For Java, what came to mind is Spring. By default, every Spring bean you write is a singleton. You can use it in 100 places, and they will all be set automagically via injection, and all 100 references will go to the same object (i.e. a singleton). When you set up a project in Spring, you can make any class you want a singleton just by following the conventions.
Google Guice is a dependency-injection framework that supports a #Singleton annotation.
Note that classes annotated with #Singleton aren't "true" singletons - there's nothing stopping client code from creating many instances of such a class. However, Guice-managed dependencies will all share the same instance.
See http://code.google.com/p/google-guice/wiki/Scopes
Maybe not what you're looking for, but here's my favorite version of the singleton pattern in C#. It's thread-safe, uses lazy instantiation, and doesn't require any locks. It's also pretty painless to write... no frameworks needed. ;)
class MyClass
{
// ...
#region Singleton pattern
private MyClass() { }
public static MyClass Instance { get { return Singleton.instance; } }
class Singleton
{
static Singleton() { }
internal static readonly MyClass instance = new MyClass();
}
#endregion
// ...
}
To get the object instance:
MyClass m = MyClass.Instance;
In Java you can do this simply with an enumerated type. You specify the number of instances so that there can be none (also called a utility class), one (also called a singleton) or more as you choose.
public enum MySingleton {
INSTANCE;
}
.NET 4.0 has the Lazy(T) Class, which will lazily-initialize a value on first access, in a thread-safe manner. There are lots of examples at the Lazy Initialization topic.
Also, if you are using Unity, there is a lifetime manager which you can configure with the ContainerControlledLifetimeManager to ensure a single instance.
Ruby has a module called singleton that makes the class which includes it a singleton. This module is built into the standard library.
The intention behind the singleton pattern is "Configure once. Use multiple times". This is typically used to share any kind of data or resources as mentioned in one of the answers above. But it is also useful to enable any kind of "management" application. (think JMX if it is Java)
You have one instance of a certain class that you can use multiple times. Since there is only one instance, by configuring that instance appropriately, you can reflect the configuration changes across the app. Hence the singleton pattern gives the ability to enable a "management dashboard" to your app.
Spring or Spring.NET (the .NET implementation of Spring) are useful for configuring and injecting singletons. The same arguments apply for any kind of dependency injection framework. You should read about dependency injection in general to harness the full power. A true singleton, across multiple JVMs or clusters, is usually harder to create and manage. and might require tool support. In practice, it is not necessary to create and maintain that.
Don't confuse singletons with statics! The construct looks similar but it can be pretty different. Now to drum my own trumpet! Here is a link to an article that I had written about static methods.
public class Singleton<T> where T : class, new()
{
static class SingletonCreator
{
internal static readonly T instance = new T();
}
public static T Instance
{
get
{
return SingletonCreator.instance;
}
}
}
It is lazy and versatile. Define constructors on demand.
In a web app, I need to have only one instance of a class called ProcessManager. One way is to make it a singleton. The other way is to use the HttpApplicationState to make sure I always access the same instance, like this:
public static ProcessManager ProcessManager
{
get
{
HttpApplicationState applicationState = HttpContext.Current.Application;
if (applicationState["ProcessManager"] == null)
{
applicationState["ProcessManager"] = new ProcessManager();
}
return (ProcessManager)applicationState["ProcessManager"];
}
}
Which method is better and why?
Based on the limited description you've given, I would choose a Singleton, because then it doesn't have a dependency on HttpContext.Current, and can be used outside of the ASP.Net pipeline (for example, when you want to write unit tests.)
(As an aside, when you set something into ApplicationState, you also need to first call Lock() on it, and then Unlock() it after you're done writing to it, to make sure it's thread safe.)
Alternately, allow injection of an HttpContext when you create your ProcessManager, such that you can use it with a mocked HttpContext.
if you plan to implement it as singleton,as per Jon Skeet (a.k.a C# guru),he personally prefers the code below
public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
(I'm assuming your ProcessManager constructor is private.)
Making it an actual singleton would be best, because such an approach would make it structurally impossible for other programmers that are maintaining your code to accidentally create multiple instances. There's nothing stopping a consumer from accessing the HttpApplicationState directly and removing and replacing the ProcessManager instance. So you must rely on convention to protect the instance of ProcessManager in HttpApplicationState.
Only if there is an actual use case for multiple instances of the class to exist does it make sense to allow multiple instantiations while relying on convention to protect the instance in HttpApplicationState.
I have the following, very interesting class ...
pubilc class Thing{
public Thing()
{
DoSomethingThatTakesALongTime();
}
public boolean CheckSomething(string criteria)
{
return criteria == "something";
} }
In my ASP.Net MVC application, I need to make a call to CheckSomething very frequently.
As you can see, the constructor takes a long time to load.
What approaches can I use to cache the class? Keep in mind that I want to keep it testable ... and I don't know what that entails!!!!
Cheers,
ETFairfax
You could use the Factory Pattern to create it (Flyweight pattern to share memory)
Create a Factory that returns an instance of the class. The factory would look like this
if instance in cache
return cached instance
if not
create instance
cache instance
return instance
For cache you could use HttpContext Cache or Enterprise Library Cache.
EDIT
Interesting discussion below of which pattern this is.
My understanding is as follows:
I ask something to create the object, that something is a factory, therefore factory pattern.
I try to reuse an object in memory, flyweight pattern. The python code in this example looks very much like my answer: http://en.wikipedia.org/wiki/Flyweight_pattern
But there is only a single instance of the object, therefore the singleton pattern
The cache where the object is stored is also a singleton
You can create a static instance of that class.
Somewhere:
public static Thing singleThing = new Thing ();
Now upon the first access of the singleThing variable for a given application domain your constructor will work out. After this is done the object will be kept in memory until the end of the application domain (server restart, update of code, changes in web.config, recycling etc.). It means the once initialized object will be available to all clients of your application.
if your thing class does something global to your aplication (not session dependant) just make the class static or add the instance to the cache (HttpContext.Cache)
As an exercise, I'm translating parts of our large and battle-hardened Delphi-framework to C#.
Included in this framework is a generic singleton parent class. Of course, implementing a singleton in C# is fairly easy (there is even a Jon Skeet article, so what more could I wish for), but our Delphi singleton has a slightly different take on the pattern: as opposed to publishing an 'instance' property/method, it has a "fake" constructor that always returns the same instance. The essential characteristic of this approach is that the user of the singleton class doesn't know that he is dealing with a singleton:
as far as they know, they just construct any old class and request some information from it.
I want to accomplish the same thing in C# (as an exercise, so it doesn't have to be production-quality code, evil hackery is fine), but so far I've failed.
Any suggestion to make a simple myInstance = new MyClass(); always return the same instance is most welcome!
Additional info
We are talking a convenience-implementation of the singleton pattern, as offered by the framework. It doesn't necessarely have to be a parent-class, but it does have to assist the developers in creating their own singletons as well. Requiring them to manually redirect all their method calls to the single-instance will not make them overflow with joy. :-)
I'm not really interested in debating whether or not this is the right way to deal with singletons, for now I'm just interested in the finer art of c#-tweaking.
You would do a Proxy (Edit: As Tom points out below, the proper design pattern is Monostate):
public class MyClass {
MyActualClass _actual;
public MyClass() {
_actual = MyActualClass. Instance;
}
public DoStuff() {
_actual.DoStuff();
}
}
internal class MyActualClass {
private MyActualClass {
}
public DoStuff() {
...
}
MyActualClass _instance;
public static Instance {
get {
if(_instance == null)
_instance = new MyActualClass()
return _instance;
}
}
}
....
public static void Main() {
var my1 = new MyClass();
var my2 = new MyClass();
}
my1 != my2 but my1.DoStuff() calls the same instance of the method as my2.DoStuff()
This would be simplified even further if you programmed of an interface only.
Edit: The equality problem could partially be solved by making _actual protected internal and overwriting MyClass.Equals(object obj) to check whether this._actual == obj._actual
I believe the Monostate pattern will give you what you need:
"The Monostate gives us the singularity of state that we so treasure in the Singleton, but without all of the static headaches that come along with it."
More here:
http://jeremyjarrell.com/archive/2008/04/21/88.aspx
As far as I know, this cannot be done for real because of how C# handles object instances. In order for a constructor to be called, the instance has to actually be created, and you can't just "return" another object from a constructor.
The best thing I can come up with (other than using a factory method) is to treat the class internally as a Singleton, and create "dummy" instances that all just point back to that original instance, when created. So for example, in your constructor you would check to see if the singleton has been initialized, and if not, would initialize it, then you would basically just proxy each instance's methods and properties back to the singleton.
In this implementation, the singleton needn't even be necessarily the same class, but you could if you wanted to keep things contained.
Update: One drawback of this approach is that although each instance would behave as a singleton, it would still have its own object reference and therefore you might also want to override Equals() for equality comparisons.
I think you could possibly roll something with Remoting.
Update:
A better way would be to wrap a proper singleton class in a struct or lightweight class.
Create the singleton as a static member and make all methods access the single static instance.
class SingletonWrapper {
private static RealSingleton instance = new RealSingleton();
public void methodA() {
instance.methodA();
}
public String getA() {
return instance.getA();
}
}
(This is actually Java code but C# is similar enough, I think. :)
I don't see how you can, as constructors don't use a return statement. You could clone all of the relevant links to the singleton, but it would have local copies of local variables, and be very messy.
Instead have the constructor check if the singleton is instantiated, and if it has been already, throw an exception, or log a warning to the developer who is using the old style code.
How about using a static function to return an object insted of using the new keyword.
static private m_obj my_obj;
static private bool my_new_obj;
static public m_obj create_m_obj()
{
if (my_new_obj == false)
{
my_new_obj = true;
my_obj = new my_obj();
}
return my_obj;
}
Then you have easy full controle over the creation of the object, if I an not mistaken.