I have the following code implementation of my generic singleton provider:
public sealed class Singleton<T> where T : class, new()
{
Singleton()
{
}
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator()
{
}
internal static readonly T instance = new T();
}
}
This sample was taken from 2 articles and I merged the code to get me what I wanted:
http://www.yoda.arachsys.com/csharp/singleton.html and
http://www.codeproject.com/Articles/11111/Generic-Singleton-Provider.
This is how I tried to use the code above:
public class MyClass
{
public static IMyInterface Initialize()
{
if (Singleton<IMyInterface>.Instance == null // Error 1
{
Singleton<IMyInterface>.Instance = CreateEngineInstance(); // Error 2
Singleton<IMyInterface>.Instance.Initialize();
}
return Singleton<IMyInterface>.Instance;
}
}
And the interface:
public interface IMyInterface
{
}
The error at Error 1 is:
'MyProject.IMyInterace' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MyProject.Singleton<T>'
The error at Error 2 is:
Property or indexer 'MyProject.Singleton<MyProject.IMyInterface>.Instance' cannot be assigned to -- it is read only
How can I fix this so that it is in line with the 2 articles mentioned above? Any other ideas or suggestions are appreciated.
Does my implementation break the Singleton pattern?
Basically, you've given a class constraint on your singleton class, along with the new() constraint.
When writing
Singleton<IMyInterface>
you're using an interface type as T, which violates the type constraint you defined.
For error 2,
Singleton<IMyInterface>.Instance = CreateEngineInstance();
you're trying to assign a value to a read-only property. So you need to define a setter on your Instance property for that line to work.
Update
Something along these lines should do it for you :
public sealed class Singleton
{
private static Hashtable bindings = new Hashtable();
private static Hashtable instances = new Hashtable();
private static void checkType(Type requested, Type bound)
{
if (requested.IsValueType)
throw new Exception("Cannot bind a value type to a reference type");
// also check type inheritance and other things...
}
private static void checkBinding(Type requested)
{
if (!(bindings.ContainsKey(requested)))
throw new Exception(String.Format("Type {0} was not bound !", requested.FullName));
}
public static void Bind<T, U>() where U : class, new()
{
checkType(typeof(T), typeof(U));
bindings[typeof(T)] = typeof(U);
}
public static T GetInstance<T>()
{
Type requested = typeof(T);
Type bound = (Type) bindings[requested];
checkBinding(requested);
if (!instances.ContainsKey(requested)) {
// We know that type "bound" was set with a new() class constraint
instances[requested] = (T) Activator.CreateInstance(bound);
}
return (T) instances[requested];
}
}
You could then write :
Singleton.Bind<IMyInterface, MyClass>();
IMyInterface instance = Singleton.GetInstance<IMyInterface>();
If you want to go further, you could also specify the lifecycle of the objects created by this provider, so that you could use singletons, or have the provider return a new object for each call, and so on.
You should also take a look at the Dependency Injection pattern, which seems close to what you want achieve, and also look at existing DI frameworks (NInject, Nhibernate) that already do this and much more.
Sure, you have an issue there. You generic is suppose to take class, not interface.
internal static readonly T instance = new T();
Your code suppose to create an instance of that class, you could not instantiate interface type.
So, if you need some type to act as singletone, you should write:
Singleton<MyInterface>.Instance
where
public class MyInterface : IMyInterface { }
Then you don't need to have any 'if' in you code, since it Singleton responsibility to instantite an object and keep it as only one instance.
Not related to question: currently Singletone's are considered by many developers as 'code-smell', so in general you have to avoid them. Try to think you application without Singletone at all.
Related
I have a Factory. I do not want to allow classes that this factory produces to be instantiated outside of the factory. If I make them abstract, static, or give them private constructors then they won't be instantiable at all! Is this a language restriction or what?
I don't want to allow this
var awcrap = new Extrude2013 (); // BAD !!!
awcrap.extrudify (); // I don't want to allow this
Rest of code:
using System;
namespace testie
{
public enum ExtrudeType { Extrude2013, Extrude2014 }
public interface IExtrudeStuff {
void extrudify();
}
public class Extrude2013 : IExtrudeStuff {
public void extrudify(){
Console.WriteLine ("extrudify 2013");
}
}
public class Extrude2014 : IExtrudeStuff {
public void extrudify(){
Console.WriteLine ("extrudify 2014");
}
}
public static class ExtrudeFactory {
public static IExtrudeStuff Create(ExtrudeType t) {
switch (t) {
case ExtrudeType.Extrude2013: return new Extrude2013 ();
case ExtrudeType.Extrude2014: return new Extrude2014 ();
default: return null;
}
}
}
class MainClass {
public static void Main (string[] args) {
// Now for the pretty API part
var o = ExtrudeFactory.Create (ExtrudeType.Extrude2013);
o.extrudify ();
var p = ExtrudeFactory.Create (ExtrudeType.Extrude2014);
p.extrudify ();
var awcrap = new Extrude2013 (); // BAD !!!
awcrap.extrudify (); // I don't want to allow this
}
}
}
You can't completely disallow this. Whether or not it's a language "restriction" would be a matter of opinion, but there are things that you could consider:
Make the constructor internal. This will allow any type within the declaring assembly to call the constructor, but nothing outside the assembly. This would mean that any code you write in that assembly to be responsible for calling the factory, and it also means that you could not declare subtypes of the class in another assembly, since it would be unable to call the constructor.
A similar approach would be to make the class you expose abstract (or an interface), then declare an internal (or even private as a subclass of the factory, since it would never be referenced outside of the factory) type that implements the abstract class or interface.
Require a token that only the factory can provide in the constructor. This is how the DataTable class works. While the constructor could still be called, the user would have to pass in null for the value and it would at least be obvious that they shouldn't be doing this.
The whole point of Factory Pattern is that only the Factory knows how to choose and make an object and it only exposes the instantiated object's functionality through an interface not a concrete class. Making the object's constructor private fails because Factory itself cannot instantiate it.
Solution:
1- Define an interface class which all types of the Extrude20XX classes implement it such as IExtrudeStuff.
2- Wrap the Extrude20XX classes inside the class of Factory as private nested classes.
3- Implement the interface IExtrude in all the ExtrudeXX classes.
4- Write a (static) Create (t) method like:
public static class ExtrudeFactory {
public static IExtrudeStuff Create(ExtrudeType t) {
{
switch (t) {
case ExtrudeType.Extrude2013: return new Extrude2013 ();
case ExtrudeType.Extrude2014: return new Extrude2014 ();
default: return null;
}
}
}
I do have a class, which is defined as:
public abstract class Singleton <T> : BaseObject
where T : Singleton <T>
{
}
I want to define an array of those generic singletons somewhere else. Something like
public MonoSingleton[] singletons;
How can I retrieve the proper type of that generic (that seems to be recursive, as you may see)? How can I write this out?
Are you trying to do the 'curiously recursive template pattern', like this?
class CuriouslyRecursiveBase<T>
{
}
class CuriouslyRecursiveDervied<T> : CuriouslyRecursiveBase<T>
{
}
class MyClass : CuriouslyRecursiveBase<MyClass>
{
}
To instantiate the derived from the base, you just use:
class CuriouslyRecursiveBase<T>
{
public static void InstantiateDerived()
{
T instance = (T)Activator.CreateInstance(typeof(T));
}
}
Since T is actually the derived type (MyClass) and curiously is also type (CuriouslyRecursive<MyClass>).
Specifically applied to your problem:
// Create a common interface that all singletons use. This allows
// us to add them all to a list.
interface ISingleton { }
class Singleton<T> : ISingleton
{
// Store our list of ISingletons
static List<ISingleton> instances = new List<ISingleton>();
static T instance;
protected Singleton() { }
public static T GetInstance()
{
// Either return the existing instnace, or create a new one
if (Singleton<T>.instance == null)
{
Singleton<T>.instance = (T)Activator.CreateInstance(typeof(T));
// Use a common interface so they can all be stored together.
// Avoids the previously mentioned co-variance problem.
// Also, compiler isn't built to follow curious recursiveness,
// so use a dynamic statement to force runtime re-evaluation of
// the type hierarchy. Try to avoid dynamic statements in general
// but in this case its useful.
instances.Add((dynamic)Singleton<T>.instance);
}
return Singleton<T>.instance;
}
}
class MyClass : Singleton<MyClass>
{
}
public static void Main()
{
MyClass my = MyClass.GetInstance();
}
More info:
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Using design-time code, you'll be able to get the type by using the typeof operator and giving some argument to the generic parameter:
typeof(Singleton<SomeImplementationOfBaseObject>)
Or
typeof(Singleton<>)
But there's an alternative: reflection.
Type singletonType = Type.GetType("NamespaceA.NamespaceN.Singleton`1");
The 1 part is the number of generic parameters. If you've something like Class<T, S> it would be 2 and so on.
Note that using reflection you don't need to give the generic argument. You can get the type with the generic parameter anyway. In order to give the generic argument, you would do this:
Type genericType = singletonType.MakeGenericType(typeof(SomeImplementationOfBaseObject));
Or if you want to get it directly, you would do this:
Type singletonType = Type.GetType("NamespaceA.NamespaceN.Singleton`1[[NamespaceA.NamespaceN.SomeImplementationOfBaseObject]]");
The string inside [[ ]] its the full name for the type passed as generic argument. Note that if the generic type isn't the same assembly as the executing one, you'll need to provide an assembly qualified name (for example, "NamespaceA.MyClass, MyAssembly").
UPDATE
The OP said in some comment:
If I do use: public Singleton<BaseObject>[] singletons;, it warns me
with: 'error CS0309: The type BaseObject' must be convertible to
Singleton' in order to use it as parameter 'T' in the
generic type or method 'Singleton'
This is another problem: you can't do covariance in classes. For doing such thing, you'll need an interface like this:
public interface ISingleton<out TBaseObject> where TBaseObject : .........
And make the Singleton<T> class implement it.
Thus, you can create such array this way:
public ISingleton<BaseObject>[] singletons;
Covariance lets you upcast generic parameters and it's limited to interfaces and delegates.
Learn more here:
http://msdn.microsoft.com/en-us/library/ee207183.aspx
How can i create a class with zero constructor, just like MessageBox class which has no constructor.
I can not make this class static, beacause a public static method is declared in it, and that method makes object of this class.
in C# 3.5
i want to make this class just like System.Windows.Forms.MessageBox class,
in which there is no constructor and
when we create object of this class error occurres :
this class has no constructor
where as a class with a private constructor when object creates error occurrs -
the constructor is not accessible due to its protection level.
The only way to create a class without a constructor is to use static class.
However, it seem you want to be able to create instances of this class from inside the class itself, which is not possible with a static class. For that, you should give the class a private constructor:
class Foo
{
private Foo() { }
public static Foo Create()
{
return new Foo(); // Only members of Foo can directly invoke the constructor.
}
}
If a method outside of Foo in the same assembly tries to instantiate Foo, the message given will be that the constructor is not accessible due to its protection level. If you try to access it from another assembly, it will give the message that Foo has no constructors.
The methods on MessageBox are static; you can do that with the static modifier:
public static class Foo {
public static void Bar() {...}
}
then:
Foo.Bar();
In earlier versions of c# (before static was allowed on classes) you had to cheat:
public class Foo {
private Foo() {} // hide the constructor
public static void Bar() {...}
}
Make it static class with no constructor or make it an Abstract class.
Make a static class, or make a class with a private constructor.
You can add public STATIC methods into your class and you would acheve the same as in messagebox.
Remember that static methods cannot access non static properties or methods in the same class.
Hope it helps.
Consider usage of Creational patterns, described in GOF ("Gang Of Four")
There are the following ways:
1) If you want to have only one instance of object to be created, use Singleton
There is a good example of thread-safe singleton on MSDN
In this strategy, the instance is created the first time any member of
the class is referenced
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
2) If you don't want to specify the exact class to create, use Factory method
Here is an extract from an article on C#-Corner Factory method Design pattern using C#
abstract class Factory
{
public abstract Product GetProduct(); //Factory Method Declaration
}
class concreteFactoryforProcuct1 : Factory
{
public override Product GetProduct() //Factory Method Implementation
{
return new Product1();
}
}
3) If there is a group of objects to be created this way, use Abstract factory
Here are extracts from an article on codeproject: Understanding and implementing abstract factory pattern in C#
Creating the Abstract Factory
interface IPhoneFactory //'I' stands for interface no relation with Iphone
{
ISmart GetSmart();
IDumb GetDumb();
}
Creating the Concrete Factories
class SamsungFactory : IPhoneFactory
{
public ISmart GetSmart()
{
return new GalaxyS2();
}
public IDumb GetDumb()
{
return new Primo();
}
}
...
Creating the Client
enum MANUFACTURERS
{
SAMSUNG,
HTC,
NOKIA
}
class PhoneTypeChecker
{
IPhoneFactory factory;
...
public PhoneTypeChecker(MANUFACTURERS m)
{
m_manufacturer= m;
}
public void CheckProducts()
{
switch (m_manufacturer)
{
case MANUFACTURERS.SAMSUNG:
factory = new SamsungFactory();
break;
case MANUFACTURERS.HTC:
factory = new HTCFactory();
break;
case MANUFACTURERS.NOKIA:
factory = new NokiaFactory();
break;
}
...
factory.GetSmart();
factory.GetDumb();
...
}
}
static void Main(string[] args)
{
PhoneTypeChecker checker = new PhoneTypeChecker(MANUFACTURERS.SAMSUNG);
checker.CheckProducts();
...
}
4) Use you common sense to develop your own design that would satisfy your needs.
If the purpose of it is not allowing user it instantiate new instances of the class you could make
all constructors less visible then public .
For example - protected.
In a non-static method I could use this.GetType() and it would return the Type. How can I get the same Type in a static method? Of course, I can't just write typeof(ThisTypeName) because ThisTypeName is known only in runtime. Thanks!
If you're looking for a 1 liner that is equivalent to this.GetType() for static methods, try the following.
Type t = MethodBase.GetCurrentMethod().DeclaringType
Although this is likely much more expensive than just using typeof(TheTypeName).
There's something that the other answers haven't quite clarified, and which is relevant to your idea of the type only being available at execution time.
If you use a derived type to execute a static member, the real type name is omitted in the binary. So for example, compile this code:
UnicodeEncoding.GetEncoding(0);
Now use ildasm on it... you'll see that the call is emitted like this:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
The compiler has resolved the call to Encoding.GetEncoding - there's no trace of UnicodeEncoding left. That makes your idea of "the current type" nonsensical, I'm afraid.
Another solution is to use a selfreferecing type
//My base class
//I add a type to my base class use that in the
//static method to check the type of the caller.
public class Parent<TSelfReferenceType>
{
public static Type GetType()
{
return typeof(TSelfReferenceType);
}
}
Then in the class that inherits it, I make a self referencing type:
public class Child: Parent<Child>
{
}
Now the call type typeof(TSelfReferenceType) inside Parent will get and return the Type of the caller without the need of an instance.
Child.GetType();
You can't use this in a static method, so that's not possible directly. However, if you need the type of some object, just call GetType on it and make the this instance a parameter that you have to pass, e.g.:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
This seems like a poor design, though. Are you sure that you really need to get the type of the instance itself inside of its own static method? That seems a little bizarre. Why not just use an instance method?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
I don't understand why you cannot use typeof(ThisTypeName). If this is a non-generic type, then this should work:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
If it's a generic type, then:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
Am I missing something obvious here?
When your member is static, you will always know what type it is part of at runtime. In this case:
class A
{
public static int GetInt(){}
}
class B : A {}
You cannot call (edit: apparently, you can, see comment below, but you would still be calling into A):
B.GetInt();
because the member is static, it does not play part in inheritance scenarios. Ergo, you always know that the type is A.
For my purposes, I like #T-moty's idea. Even though I have used "self-referencing type" information for years, referencing the base class is harder to do later.
For example (using #Rob Leclerc example from above):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
Working with this pattern can be challenging, for example; how do you return the base class from a function call?
public Parent<???> GetParent() {}
Or when type casting?
var c = (Parent<???>) GetSomeParent();
So, I try to avoid it when I can, and use it when I must. If you must, I would suggest that you follow this pattern:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
Now you can (more) easily work with the BaseClass. However, there are times, like my current situation, where exposing the derived class, from within the base class, isn't needed and using #M-moty's suggestion just might be the right approach.
However, using #M-moty's code only works as long as the base class doesn't contain any instance constructors in the call stack. Unfortunately my base classes do use instance constructors.
Therefore, here's my extension method that take into account base class 'instance' constructors:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}
EDIT
This methods will works only when you deploy PDB files with the executable/library, as markmnl pointed out to me.
Otherwise will be a huge issue to be detected: works well in developement, but maybe not in production.
Utility method, simply call the method when you need, from every place of your code:
public static Type GetType()
{
var stack = new System.Diagnostics.StackTrace();
if (stack.FrameCount < 2)
return null;
return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType;
}
I need to have the generic type parameter as an interface, however I would like to instantiate the type in the generic class (SomeGenericType) as follows:
class Program
{
static void Main(string[] args)
{
var val = new SomeGenericType<ISomeInterface>();
Console.ReadKey();
}
}
internal class SomeGenericType<T> where T : new()
{
public SomeGenericType()
{
var test = new T();
}
}
public class SomeClass : ISomeInterface
{
public string TestVal { get; set; }
}
public interface ISomeInterface
{
string TestVal { get; set; }
}
This throws the following compile time error:
"ISomeInterface must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method SomeGenericType"
I understand why it happens, however I was wondering if there is any way around this problem?
Thanks.
No, the new() constraint requires that an instance of the type can be created with the syntax
new T()
This clearly isn't true of either an abstract class or an interface, only a concrete class with a public parameterless constructor.
You could defer the problem until runtime by removing the constraint, and using:
Activator.CreateInstance<T>()
instead to create the object. Then as long as the actual type used at runtime satisfies these constraints, your code will work as you want it to. However, if you do attempt to use an interface or an abstract class, then you will encounter a runtime error.
In your specific case, this line would throw an exception
var val = Activator.CreateInstance<SomeGenericType<ISomeInterface>>();
You're past the compile-time error, but to no effect.
An alternative idea, which may be irrelevant, but it looks like you are looking for a way to ask for an ISomeInterface, and have an instance of its "default" implementation SomeClass provided. This is the sort of thing that an Inversion of Control (IOC) container can handle for you. If you want to investigate further, you could look at Spring.NET, Microsoft Unity, AutoFac, LinFu or one of many other frameworks.
The problem is, there is no way for the compiler to know which class to instantiate for the given interface. As David M points out:
This is the sort of thing that an Inversion of Control (IOC) container can handle for you
I think using a framework might be over kill for this simple requirement. What you can do is create a Factory class of your own like this:
public class Factory
{
Dictionary<Type, Type> typeMapping = new Dictionary<Type, Type>();
public void Register<IType, CType>()
{
typeMapping.Add(typeof(IType),typeof(CType));
}
public IType Create<IType>()
{
Activator.CreateInstance(typeMapping[typeof(IType)]);
}
}
throw in a few sanity checks and this class should be ready to use.
The issue here is the new constraint is tied to having a concrete type implementation. This can't ever work with simply and interface or abstract class since they cannot be directly instantiated. You must provide a concrete class here
var val = new SomeGenericType<SomeClass>()