代码之家  ›  专栏  ›  技术社区  ›  JoelFan

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

  •  6
  • JoelFan  · 技术社区  · 14 年前

    新的

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

    8 回复  |  直到 14 年前
        1
  •  5
  •   munificent    14 年前

    如果出于某种原因,需要将工厂和构造的类放在单独的程序集中(这意味着只需使用 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;
    }
    

        2
  •  23
  •   Dan Bryant    14 年前

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

        3
  •  11
  •   Jeff Sternal    14 年前

    使其构造函数私有,并将工厂方法作为类本身的静态方法提供。

    在大多数情况下,您只需将构造函数设置为内部构造函数,就可以将工厂划分为自己的类—我发现阻止自己的团队使用它通常是不值得的 new

        4
  •  5
  •   Community Ian Goodfellow    7 年前

    使建造师内部和房子的工厂在同一装配。

    public MyClass
    {
        internal MyClass()
        {
        }
    }
    

    在同一组件中

    public MyClassGenerator
    {
        public static CreateMyClass()
        {
            return new MyClass();
        }
    }
    

    如果工厂不能在同一个装配中,或者此方法不适用于您,请查看 Dan's answer

        5
  •  2
  •   amarax    7 年前

    不管怎样,从工厂返回的是一些接口/抽象类,而不是具体类型。 当然,您不能将返回类型强制转换为客户机代码中的某个具体类型,但首先这是设计不好的标志,其次,您可以使用嵌套私有类继承的更具体的接口/抽象类来解决它。

    您可以在这里参考Eric Lippert的答案(对于类似的问题): Why Would I Ever Need to Use C# Nested Classes

        6
  •  1
  •   FacticiusVir    14 年前

    在某处

        7
  •  1
  •   Mike    14 年前

    很多人都提到过使用内部方法,但是您也可以保护构造函数并派生一个只包含静态工厂方法的类。这并不妨碍其他人做同样的事情,但在限制对构造函数的直接访问方面做得很好。

        8
  •  0
  •   Aliostad    14 年前

    内部的 如果你有一个单独的类作为工厂(我认为你应该)。如果工厂位于不同的部件上,请使用InternalVisible属性。