Constraints on class instantiation

I have many classes of algorithms that implement the same interface; another factory class "is responsible for creating the correct algorithm class via a config parameter and then calling the start method on that instance.

I would like to limit the visibility of the constructor (or any other instantiation mechanism) of the algorithm classes to the factory class only.

How can I solve this? The only clean solution I can think of is to move these classes to another .dll and change the algorithm classes to private, but that's not what I want to do right now.

+3


source to share


2 answers


Perhaps the following sample will suit you (yes, I know which reflection should not be used normally ...)

public class Algorithm
{
    private Algorithm()
    {
    }

    public void SomeMethod()
    {
    }
}

public static class Factory
{
    public static Algorithm Create()
    {
        var constructor = typeof(Algorithm).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null);
        return (Algorithm)constructor.Invoke(null);
    }
}

      



Here you can instantiate the Algorithm using Factory. Create, not a new algorithm.

+2


source


It won't be the answer you like, but: do not.

Having created this constructor private/internal/protected

makes it difficult for you to validate the algorithms, and you also prevent any API users from manually choosing their own implementation instead of using a factory.

I would say keep the constructors public, just make sure every required dependency is declared in the constructor. Here's where I take over the various constructor modifiers:



  • public

    - everyone can access your constructor and you can check the class - that's good.
  • protected

    - subclasses can access the constructor. This is fine, but really only used for abstract classes and / or constructor chaining.
  • internal

    - You disallow the use of a constructor for InternalsVisibleTo

    (friend) assemblies. This means that any user in your assembly can build it fine, but other assemblies must explicitly either InternalsVisibleTo

    be forced to use your factory, thereby tying the algorithm to the factory.
  • private

    - Useful for hiding the default constructor (although you don't need to do this if you create a constructor with at least one argument) or create only constructors with targets.

TL; DR - I would recommend not creating a constructor internal

. This way you can also make a class internal

(you refer to algorithms by their interface, not by their class, right?)

Another solution would be to make implementations of the classes private

and nest them in a factory. Ask them all to implement a common interface (which they should be doing already) and expose the interface to the rest of the application. This still does not avoid a complex check.

+3


source







All Articles