Search code examples
c#design-patternsoopfactory

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


Recently I've been thinking about securing some of my code. I'm curious how one could make sure an object can never be created directly, but only via some method of a factory class. Let us say I have some "business object" class and I want to make sure any instance of this class will have a valid internal state. In order to achieve this I will need to perform some check before creating an object, probably in its constructor. This is all okay until I decide I want to make this check be a part of the business logic. So, how can I arrange for a business object to be creatable only through some method in my business logic class but never directly? The first natural desire to use a good old "friend" keyword of C++ will fall short with C#. So we need other options...

Let's try some example:

public MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    public MyBusinessObjectClass (string myProperty)
    {
        MyProperty = myProperty;
    }
}

public MyBusinessLogicClass
{
    public MyBusinessObjectClass CreateBusinessObject (string myProperty)
    {
        // Perform some check on myProperty

        if (true /* check is okay */)
            return new MyBusinessObjectClass (myProperty);

        return null;
    }
}

It's all okay until you remember you can still create MyBusinessObjectClass instance directly, without checking the input. I would like to exclude that technical possibility altogether.

So, what does the community think about this?


Solution

  • Looks like you just want to run some business logic before creating the object - so why dont you just create a static method inside the "BusinessClass" that does all the dirty "myProperty" checking work, and make the constructor private?

    public BusinessClass
    {
        public string MyProperty { get; private set; }
    
        private BusinessClass()
        {
        }
    
        private BusinessClass(string myProperty)
        {
            MyProperty = myProperty;
        }
    
        public static BusinessClass CreateObject(string myProperty)
        {
            // Perform some check on myProperty
    
            if (/* all ok */)
                return new BusinessClass(myProperty);
    
            return null;
        }
    }
    

    Calling it would be pretty straightforward:

    BusinessClass objBusiness = BusinessClass.CreateObject(someProperty);