确保对象仅由工厂创建(C#)

Joe*_*Fan 6 c# factory new-operator

如何确保某个类仅由工厂实例化而不是直接调用new

编辑:我需要工厂是一个单独的类(为了依赖注入目的)所以我不能使它成为实例化类的静态方法,所以我不能使新的私有.

Dan*_*ant 23

如果工厂位于同一个程序集中,并且您只需要保护外部程序集实例化该类,则可以将构造函数设置为内部.我知道阻止所有其他类(包括同一程序集中的类)的唯一方法是使实例化的类成为工厂的嵌套私有类,并仅将其作为接口公开.如果类是它自己的工厂(静态工厂方法),那么你可以像其他人提到的那样使构造函数成为私有的.


Jef*_*nal 11

使其构造函数为私有,并将类方法作为静态方法提供给类本身.

在大多数情况下,您可以将构造函数设置为内部,允许您将工厂分解为自己的类 - 我发现通常不值得尝试阻止我自己的团队new在类的程序集中创建实例.


s_h*_*itt 5

使构造函数内部并在同一个程序集中容纳工厂.

public MyClass
{
    internal MyClass()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在同一个集会中

public MyClassGenerator
{
    public static CreateMyClass()
    {
        return new MyClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果工厂不能在同一个组件中,或者这种方法对你不起作用,请看Dan的答案


mun*_*ent 5

如果由于某种原因,您需要工厂和构造的类在单独的程序集中(这意味着简单地使用internal将无法工作),并且您可以确保您的工厂有机会先运行,您可以这样做:

// In factory assembly:

public class Factory
{
    public Factory()
    {
        token = new object();
        MyClass.StoreCreateToken(token);
    }

    public MyClass Create()
    {
        return new MyClass(token);
    }

    private object token;
}

// In other assembly:

public class MyClass
{
    public static void StoreCreateToken(object token)
    {
        if (token != null) throw new InvalidOperationException(
            "Only one factory can create MyClass.");

        this.token = token;
    }

    public MyClass(object token)
    {
        if (this.token != token) throw new InvalidOperationException(
            "Need an appropriate token to create MyClass.");
    }

    private static object token;
}
Run Code Online (Sandbox Code Playgroud)

是的,这很麻烦,很尴尬.但可能有一些奇怪的情况,这实际上是一个很好的解决方案.