views:

96

answers:

4

C# .Net 4.0

I'd like to know how I can have a class which can only be instantiated from one single place. An example:

I've got a Provider class. This class exposes a method called GetData. When GetData is called, the Provider will instanciate a Data class, populate and return it. The Data class cannot be instanciated by anybody different then the Provider, so the only way to access the data will be through the Provider. Once GetData is called and a caller has received the Data class instance, he should be able to access properties/methods of this class.

How can this be done? Is there a pattern for this sort of problem? A short sample would be highly appreciated. Thanks in advance!

+7  A: 

It sounds like you are looking for the factory pattern:

The factory pattern is a creational design pattern used in software development to encapsulate the processes involved in the creation of objects.

Basically your Provider class is the factory that controlls the creation of instances of the Data class.

One thing you could do control this would be to place these two types in their own assembly and make the constructor for Data be internal but the class itself public. This would mean that anyone who references the assembly would be forced to use the Provider class to create instances of Data (unless they used reflection, of course).

Andrew Hare
+1 Andrew - for mentioning the Fcatory pattern
ChrisBD
Thanks for your reply. I actually thought of a solution with multiple assemblies, but that would be a too big burger for this small project. Do you have an easy example on how to implement this pattern with everything being in the same assembly?
Matthias
A: 
public class Provider
{
  protected Provider()
  {
  }

  public static Provider CreateNewProvider()
  {
    return new Provider();
  }
}
ChrisBD
The OP wants to know how to declare the `Data` class, not the `Provider` class!
Hosam Aly
Ah my mistake for not reading the question properly. Is that the reason for the down vote?
ChrisBD
Yes, as it is misleading with regards to the OP's question.
Hosam Aly
+1  A: 

Here is an example of what Andrew described:

public class Data
{
    internal Data()
    {
        // internal constructor cannot be called from outside the assembly
    }

    // properties, fields and methods
}

public class Provider
{
    public Data GetData()
    {
        return new Data();
    }
}
Hosam Aly
+6  A: 

Another solution would be to create an interface IData, and declare the Provider.GetData method to return IData instead of Data. Then you can have your Data class nested inside Provider. This way your Data class cannot be instantiated even by classes in the same assembly. Here is an example:

public interface IData
{
    // properties and methods
}

public class Provider
{
    public IData GetData()
    {
        return new Data();
    }

    private class Data : IData
    {
        // your implementation
    }
}
Hosam Aly