构造函数外部的C#对象构造

时间:2011-09-28 05:34:19

标签: c# dependency-injection

当涉及到设计类和它们之间的“通信”时,我总是试图以这样的方式设计它们,使得所有对象构造和组合都发生在对象构造函数中。我不喜欢从外部发生对象构造和组合的想法,就像其他对象设置属性和调用我的对象上的方法来初始化它一样。当多个对象尝试对您的对象执行此操作并且您永远不知道您的props \ methods将以何种顺序执行时,这尤其会变得丑陋。

不幸的是,我经常发现这种情况,特别是现在随着依赖注入框架的日益普及,许多库和框架依赖于某种外部对象初始化,并且通常不仅需要对我们的对象进行构造函数注入而且还需要属性也注射。

我的问题是:

  1. 是否可以让对象依赖于某些方法,或者在它们上面调用属性,之后他们可以认为它们被初始化了?

  2. 当你的对象是接收者时,它是某种模式,并且必须支持多个调用它的接口,这些调用的顺序是否重要? (比设置标志更好的东西,比如ThisWasDone,ThatWasCalled)

5 个答案:

答案 0 :(得分:9)

  

是否可以让对象依赖于某些方法,或者在它们上面调用属性,之后他们可以认为它们被初始化了?

没有。 Init方法很痛苦,因为不能保证它们会被调用。一个简单的解决方案是切换到接口并使用工厂或构建器模式来组成实现。

@Mark Seemann写了一篇关于它的文章:http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling.aspx

  

当你的对象是接收者时,是否存在某种模式,并且必须支持多个调用它的接口,这些调用的顺序是否重要? (比设置标志更好的东西,比如ThisWasDone,ThatWasCalled)

构建器模式。

答案 1 :(得分:0)

我认为没关系,但有影响。如果这是其他人要使用的对象,则需要确保在设置或访问方法或属性时应抛出异常,并且应该调用初始化但不是。

显然,如果您可以在构造函数中处理这个问题,那么它会更加方便和直观,那么您就不必实现这些检查。

答案 2 :(得分:0)

我没有看到任何错误。它可能不那么方便,但你不能总是在ctor中使用初始化,就像你不能在绿灯下驱动alwats。这些是您根据应用程序要求做出的决定。

  1. 没关系。例如,如果您的对象需要从TCP流或不存在或损坏的文件中读取数据,则想象一下。提起ctor的例外是baaad。

  2. 没关系。例如,如果您认为某些DSL语言编译器,它可能看起来像:

  3. A)查找所有全局变量,并检查内存分配总和是否满足您的设备需求

    B)解析错误

    C)检查自行循环

    等等......

    锄头有帮助。

答案 3 :(得分:0)

回答(1)

为什么不呢?引擎需要驱动程序,因为它必须输入汽车的钥匙,然后再打开电源。如果发动机停转,汽车会检测当前速度吗?或者汽车是否会在没有电源的情况下显示剩余的油?

某些编程目标无法在其对象构造期间初始化其actor,这不是因为它是一种非正确的做事方式,而是因为它是自然的,常规的和/或以语义方式表示其整个行为。

回答(2)

体面的课程使用文档将是您最好的朋友。就像对(1)的回答一样,在这个世界上有一些事情应该做,以便正确地完成它们,这不是一个问题,而是一个要求。

使用标志检查对象的状态也不是问题,这是为对象模型增加可靠性的好方法,因为它自己的行为和消费者会知道事情是否按预期完成。 / p>

答案 4 :(得分:0)

首先,工厂方法。

public class MyClass
{
    private MyClass()
    {
    }

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

其次,为什么你不想让另一个类为你创建一个对象? (工厂)

public class MyThingFactory
{
    IThing CreateThing(Speed speed)
    {
        if(speed == Speed.Fast)
        {
            return new FastThing();
        }

        return new SlowThing();
    }
}

第三,为什么多个类对你班级的新实例有副作用?您是否对其他类可以访问您的对象具有声明性控制权?