How can I make a class global to the entire application? - c#

I would like to access a class everywhere in my application, how can I do this?
To make it more clear, I have a class somewhere that use some code. I have an other class that use the same code. I do not want to duplicate so I would like to call the same code in both place by using something. In php I would just include("abc.php") in both... I do not want to create the object everytime I want to use the code.

Do you want to access the class or access an instance of the class from everywhere?
You can either make it a static class - public static class MyClass { } - or you can use the Singleton Pattern.
For the singleton pattern in its simplest form you can simply add a static property to the class (or some other class) that returns the same instance of the class like this:
public class MyClass
{
private static MyClass myClass;
public static MyClass MyClass
{
get { return myClass ?? (myClass = new MyClass()); }
}
private MyClass()
{
//private constructor makes it where this class can only be created by itself
}
}

The concept of global classes in C# is really just a simple matter of referencing the appropriate assembly containing the class. Once you have reference the needed assembly, you can refer to the class of choice either by it's fully qualified Type name, or by importing the namespace that contains the class. (Concrete instance or Static access to that class)
Or
You can have a Singleton class to use it everywhere but some people won't recommend you this way to proceed.

The other answers that you've been given about using a static class or a singleton pattern are correct.
Please consider, however, the fact that doing so does compromise your ability to test. In general, if you can, prefer dependency injection over globally accessed classes. I know this isn't always possible (or practical).
Just on that, you should also look up the abstract factory pattern. It allows you to have a well known factory class that produces the actual instance of a class that you're using. To have a globally accessed logging class, for example, don't directly create a logging class. Instead, use a logging factory to create it for you and return an interface to a logging class. That way it's easier to swap in and out different logging classes.

Since you do not want to create the object every time and it sounds like you are talking about some sort of utility methods...
I suggest you use static methods in an assembly which you can reference where needed

Related

Moving singleton definition into mixins in C#

I have to change around 10 classes into singletons and I thought that instead of copy-pasting the code it makes sense to use mixins, like it is described here: http://msdn.microsoft.com/en-us/vstudio/bb625996.aspx
However, I need not that much of additional methods, but more additional changes to the class itself, I have problems applying those instructions.
I tried to create an empty interface ISingleton and then to add the singleton part as extension to the new class public static class Singleton
This is singleton part which I would like to use:
public static SomeClass Instance
{
get { return _instance ?? (_instance = new SomeClass ()); }
}
private static SomeClass _instance;
But when adding it as extension I had a problem - how to define the Instance property, so it will be reusable by many classes?
And the second issue - I still need to change the constructors to private manually.
Does this approach makes any sense?
I haven't used mixins before, maybe this is just not the right scenario for it?
The mixins link you gave shows extension methods being used to add functionality to all objects supporting an interface. You still need to create the objects first. As singleton patterns handle the creation of objects it's basicly too soon to apply these techiniques.
Singleton needn't be so complicated, you're reading Jon Skeets article, a simple:
public sealed MyClass
{
private MyClass(){}
public static MyClass Instance = new MyClass();
}
Is often all you need. I'd happily repeat that code 10 times if needed. Or one can use a service locator or IoC container to manage the lifetime of objects.

Coding practice - using abstract or a private constructor

I have a question about coding practice. I want to create a class which can't be initialized. I believe I have 3 options:
Abstract modifier
Static modifier
Private constructor
I don't want to create a static class simply because of having to name all of my properties and methods 'static' - it looks messy (and I can't use the 'this' keyword).
According to the MSDN:
Use the abstract modifier in a class declaration to indicate that a
class is intended only to be a base class of other classes.
Edit Nothing will inherit form this class.
However, it would be a solution (but it seems wrong to me to use it in this situation).
Or, I can make a private constructor so the class cannot be initialized.
If it helps the reason for why is this: The class is responsible for starting off a work flow process. It doesn't need to be initialized since nothing is returned - it just needs to be 'started'.
Demo code
class Program
{
static void Main(string[] args)
{
WorkFlow wf = new WorkFlow(); // this will error which is fine!
ComplexObject co = new ComplexObject();
WorkFlow.Begin(co);
Console.ReadKey();
}
}
public class WorkFlow
{
private WorkFlow()
{
//private to prevent initialization but this feels wrong!
}
public static void Begin(ComplexObject co)
{
//code to begin the workflow
}
}
I want to create a class which can't be initialized.
That leaves the possible usages: static or base-class only.
If your class is going to be derived from, use abstract. A private/protected constructor would be a hack in this situation.
Your sample code looks more like a static class. With Singleton as alternative.
What about doing just what you have done but using your Begin method as a factory to create your workflow.
var workflow = Workflow.Begin(complexObject);
public class WorkFlow
{
private WorkFlow()
{
//private to prevent initialization but this feels wrong!
}
public static WorkFlow Begin(ComplexObject co)
{
return new Workflow(co);
}
}
Good practice: Private constructor (at least is what the GOF book recommends when using the Factory pattern, for example). I'll suggest you to use abstract if it's a base class (that's what it's name suggest).
If the class is strictly being used as a base class, it would have to be abstract for me.
Based on your update I would go for a static class & method e.g.
WorkFlow.Begin(co);
However, since you don't want to do this I think it only leaves you with one option...private constructor.
Seems like you would need a singleton.
More reference here:
http://msdn.microsoft.com/en-us/library/ff650849.aspx
if you dont like the ideea, well an abstract class would be best suited because as you said you dont want to instantiate it, and lets not forget that the abstract class does just that, so why try and use a private constructor.
I don't want to create a static class simply because of having to name
all of my properties and methods 'static' - it looks messy (and I
can't use the 'this' keyword).
Well, either you make ctor private or make a class static, the only way caller can access methods and properties of your class (if the caller is not derived one) is via public static members.
Having private ctor give you more flexibility in inheritance chain, but doesn't help much in "avoid static members" scenario.
I will prefer private constructor ie its identical to Singleton pattern
Info
Coding
Private constructors seems to be good approach for your requirement. Abstracts are good too but private constructor is handy than abstract. But if you would like to extend its information then its probably good idea to use abstract.
If the class needs to be "started" it needs to be initialized (unless all you're going to use are static methods).
Abstract classes are used to leave some (or all) of the implementation to subclasses, and by your description - not suitable for you.
"Static classes" - no special gain here I guess (in your case).
Private constructors - used to limit who can instantiate the class.
Not sure that any of these matches your design, but I guess you really want a singleton - look it up, this is the most common and basic design pattern.
BTW - I use singletons only as a last resort, usually when the class controls some kind of non shared resource.

Best way to prevent a class from being Instantiated?

I need to know how to prevent a class from being Instantiated in .net?
I know few methods like making the class Abstract and Static.
Is there any more way to achieve this?
Making the class static is the best approach, if you absolutely don't want any instances. This stops anyone from creating instances. The class will be both sealed and abstract, and won't have any constructors.
Additionally, the language will notice that it's a static class and stop you from using it in various places which imply instances, e.g. type arguments and variables. This indicates the intention more clearly than just having a private constructor - which could mean that there are instances, created within that class (e.g. for a singleton implementation).
Oh, and making the class static will stop you from introducing any pointless instance members in the class, too :)
See MSDN for more information about static classes.
Mark the constructor(s) private, protected or if in used from another assembly, internal
Marking the constructor private. Of course, this doesn't prevent the class from instantiating itself through a static method, for example...
More practically, what's the purpose of disallowing class instantiation. If it's to have a singleton, then a private constructor is appropriate. If it's to force subclassing, making the class abstract is better; if it's to have a class with utility methods, making it static is one way (then you can only have static methods).
I need to know how to prevent a class from being Instantiated in .net?
Your question is not clear.
Do you mean instantiated at runtime? Make the class abstract or static.
Do you mean that the constructor is not accessible in code? Make the constructor private. But note that someone could still use reflection to grab a handle on a constructor and instantiate an instance at runtime.
So, which do you mean?
If the question is:
How can you make your class not be instanced without having your class
be static or abstract?
Then the answer to this is to implement the singleton pattern, which in .NET 4+ this is done easily with:
public sealed class myClass
{
private static readonly Lazy<myClass> lazyInstance =
new Lazy<myClass>(() => new myClass());
public static Instance
{
get
{
return lazyInstance.Value;
}
}
private myClass()
{
// constructor logic here
}
}
The singleton pattern allows you to pass your class around as a reference to methods, while still ensuring that you have only a single instance of your class. It also makes testing much easier as you can have a ImyClass instance which myClass implements, this is very helpful when making mock objects.
Without .NET4 you can still implement the singleton pattern, for example:
private static readonly myClass instance = new myClass();
public static Instance
{
get
{
return instance;
}
}
// rest of code remains the same
Which doesn't have deferred loading until it's called, there's lots of other ways as well (I think about 6 different ways), but the above two are the most common ones.
In summary the question is likely asking if you know the singleton pattern and if you recognise it's importance over static classes for unit tests and mock objects.
As others have already pointed out, static fields, even those marked readonly can be set with reflection, in addition the private constructor can be called using reflection. If you need to prevent these, either you need to make the calling code run in a less trusted app-domain space, or you will need to implement your class as static.
Generally though, people don't bother with such levels of reflection to get around your constraints unless they 'really need to' for example, writing obscure / extreme fringe case unit tests.

Static to instance, how do I handle properly?

I have a static class I am deprecating and modifying the class to force clients to use an instance variable.
Question is, how do I handle allowing the previous static class to remain and be used (with obsolete attribute) and also allow the new non static class to be used as well (same name, same method names)?
Is this possible?
There are several ways you can use, but none do exactly what you want:
Remove the static modifier, making it a normal non-static class, and optionally make it partial, implementing the new instance related code in a second file. With this method, however, you will not be able to obsolete the entire static class, as you have only one class.
Place the new class in a new namespace
Place the new class in a new project, but in the same namespace as the original
If you make all the old static members obsolete, I would go for option nbr. 1.
I don't think it will be possible to keep the same name and parameters but you could do this
[Obsolete("This class is obsolete; use class B instead")]
Visual Studio will hint to the user, that they should be using the new class.
Not possible with same class name and same members, the type would be ambiguous. This is frequently done using the obsolete attribute's message field to tell the caller what class to use instead, in this case, your new instance class.
You could come up with some convoluted versioned interface, perhaps, but even in the best case that would be unclear to callers and they would have to know which version they were dealing with. Callers need to handle an instace and static classes differently, so hiding which they are using would only lead to problems (were it possible to do so).
One thing you could do is to implement non-static versions of methods through an explicitly implemented interface, like this:
public interface ITest
{
string Foo();
}
// your class
public class Test : ITest
{
//original, static version of Foo
public static string Foo()
{
return "foo";
}
// Foo reimplemented as a non-static method
// note that you need to implement ITest explicitly
// for it to compile
string ITest.Foo()
{
return "foo";
}
}
This compiles and works as expected, except that the non-static methods can only be called through the interface, i.e.:
ITest t = new Test(); //assigning to a variable of type ITest
Console.WriteLine(t.Foo()); // writes "foo"
Console.WriteLine(Test.Foo()); // and calling the static method still works too

make sure object only created by factory (C#)

How do I make sure that a certain class is only instantiated by a factory and not by calling new directly?
EDIT: I need the factory to be a separate class (for dependency injection purposes) so I can't make it a static method of the class to be instantiated, and so I can't make new private.
If the factory is in the same assembly and you only need protection against external assemblies instantiating the class, you can make the constructor internal. The only way I know to prevent this for all other classes (including those in the same assembly) is to make the instantiated class a nested private class of the factory and only expose it as an interface. If the class is its own factory (a static factory method), then you can make the constructor private, as others have mentioned.
Make its constructors private and supply the factory method as a static method on the class itself.
In most cases you can just make the constructors internal, allowing you to break the factory out into its own class - I've found it's often not worth trying to prevent my own team from using new to create instances within the class' assembly.
If, for some reason, you need the factory and the constructed class to be in separate assemblies (which means simply using internal won't work), and you can ensure that your factory gets a chance to run first, you can do this:
// In factory assembly:
public class Factory
{
public Factory()
{
token = new object();
MyClass.StoreCreateToken(token);
}
public MyClass Create()
{
return new MyClass(token);
}
private object token;
}
// In other assembly:
public class MyClass
{
public static void StoreCreateToken(object token)
{
if (token != null) throw new InvalidOperationException(
"Only one factory can create MyClass.");
this.token = token;
}
public MyClass(object token)
{
if (this.token != token) throw new InvalidOperationException(
"Need an appropriate token to create MyClass.");
}
private static object token;
}
Yes, it's cumbersome and awkward. But there may be weird situations where this is actually a good solution.
Make the constructor internal and house the factory in the same assembly.
public MyClass
{
internal MyClass()
{
}
}
in same assembly
public MyClassGenerator
{
public static CreateMyClass()
{
return new MyClass();
}
}
If the factory can't be in the same assembly or this method doesn't work for you, look to Dan's answer
You can make your concrete classes as nested private classes with public constructors inside your factory class - this way your factory can create them, others can't even see them.
Anyway you return from factory some interface / abstract class, not concrete type.
Of course you won't be able to cast your return type to a concrete type somewhere in a client code but first it's a sign of bad design, second you can always workaround it with more concrete interface / abstract class your nested private class inherits.
you can refer to the Eric Lippert's answer here (for a similar problem):
Why Would I Ever Need to Use C# Nested Classes
It will always be created by calling new somewhere, but if you only want that to happen in your factory class, you can set all the constructors to Internal (or Private, and use a Public Static factory method on the same class).
Many people have mentioned using internal, but you can also make your constructors protected and derive a class that just has the static factory method in it. This doesn't prevent others from doing the same thing, but does a pretty good job at restricting direct access to your constructors.
I do not like to have the factory on the type itself especially if it is a domain object. Have it internal if you are having a separate class as factory (which I think you should). Use InternalVisible attribute if the factory is on the different assembly.

Categories

Resources