3

Possible Duplicate:
Factory pattern in C#: How to ensure an object instance can only be created by a factory class?

Suppose I have a Factory class that knows how to make a Square. If I feel that only the Factory class knows how to make a square and I want to prevent others (even in the same assembly) from creating a Square what would be the correct (if there is such a thing) way to go about it?

Community
  • 1
  • 1
Brandon Moore
  • 8,590
  • 15
  • 65
  • 120

3 Answers3

8

Depending on your situation, you could do this:

public class Square
{
    // Only Square and classes nested within it can call this
    private Square()
    {
    }

    public class Factory
    {
        public Square CreateSquare()
        {
            return new Square();
        }
    }
}

Then:

Square.Factory factory = new Square.Factory();
Square square = factory.CreateSquare();
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    If I were going to do that, would it not make more sense to have the Square be the inner class so that I can do the same for Circles and Triangles? This seems obviously backwards to me but I see someone else posted the same answer so it makes me curious if I'm missing something here... – Brandon Moore Feb 03 '12 at 10:38
  • @BrandonMoore: It wouldn't work in that case, as a containing class doesn't have access to the private members of the nested class. We'd need to know a more realistic scenario, basically - this pattern is a useful one (particularly for implementing the Builder pattern) but it's not *universally* applicable. – Jon Skeet Feb 03 '12 at 10:56
  • Oh right, I knew that. Oddly enough, I think I heard that according to spec the inner class shouldn't have access to the outer class's private members either... but c# and other compilers allow it anyway since it's useful. – Brandon Moore Feb 03 '12 at 11:01
  • @BrandonMoore: No, it's fine according to the spec, although there's one bit which isn't as clear as it should be. But from section 3.5.2, for the accessibility domain of a nested member M declared in a type T: "If the declared accessibility of M is private, the accessibility domain of M is the program text of T." The nested type is still within the program text of the containing type, so it's okay. – Jon Skeet Feb 03 '12 at 11:04
  • 1
    Are you sure you shouldn't have been a lawyer Jon? :) – Brandon Moore Feb 03 '12 at 11:20
2

You could move the factory and the class to an assembly and mark the class's constructor as internal so that it can only be called from within the assembly.

Note that this would allow other assembly members to access the constructor though, not only the factory.

This is how the Lookup<TKey, TElement> works for instance.

vc 74
  • 37,131
  • 7
  • 73
  • 89
  • Probably the solution I am going to end up using. I guess at some point if I really want to I could use some reflection to throw an exception at run-time if somebody misuses it. – Brandon Moore Feb 03 '12 at 11:25
2

One way I see (with the factory and the Square in the same assembly) is to move your factory methods as static methods of the Square class, and add only private constructors to your Square class.

You could also move your Factory class as an inner class of Square:

public class Square
{
    private Square()
    {
    }

    public int Size { get; set; }

    public static class Factory
    {
        public static Square CreateClass()
        {
            return new Square { Size = 10 };
        }
    }
}
ken2k
  • 48,145
  • 10
  • 116
  • 176