类实例创建限制

时间:2014-09-11 07:56:48

标签: c# factory class-visibility

我有许多实现相同接口的算法类;另一个"工厂" class有责任通过config参数实例化正确的算法类,然后在该实例上调用start方法。

我想将算法类的构造函数(或任何其他实例创建机制)的可见性限制为仅限工厂类。

我该如何解决这个问题?我能想到的唯一干净的解决方案是将这些类移动到不同的.dll中并将算法类更改为私有类,但这不是我现在想要做的。

2 个答案:

答案 0 :(得分:3)

这不是您希望听到的答案,但是:不要。

通过创建构造函数private/internal/protected,您很难测试算法,并且您也阻止API的任何使用者手动选择他们自己的实现而不是使用工厂。

我想说将构造函数保留为public,只需确保构造函数中声明了所需的每个依赖项。这是我对构造函数的各种修饰符的看法:

  • public - 每个人都可以访问您的构造函数,您可以测试该类 - 这很好
  • protected - 子类可以访问构造函数。这没关系,但实际上只用于抽象类和/或构造函数链接。
  • internal - 您将构造函数的使用限制为InternalsVisibleTo(朋友)程序集。这意味着程序集中的任何人都可以正常构造它,但其他程序集必须明确地InternalsVisibleTo强制使用您的工厂,从而将算法耦合到工厂。
  • private - 用于隐藏默认构造函数(尽管如果创建具有至少一个参数的构造函数则不需要执行此操作),或仅创建可链接构造函数。

TL; DR - 我建议不要制作构造函数 internal。通过这样做你也可以制作 internal(你 通过他们的界面引用算法而不是他们的类,对吗?)

另一个解决方案是创建类private的实现并将它们嵌套在Factory中。让它们都实现一个通用接口(它们应该已经在做)并将接口暴露给应用程序的其余部分。这仍然无法避免使其难以测试的问题。

答案 1 :(得分:2)

也许你会对以下样本感到满意(是的,我知道不应该正常使用什么反射......)

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);
    }
}

在这里,您可以通过Factory.Create创建算法实例,而不是通过新算法。