c#构造函数注入和构造函数重载

时间:2011-06-02 09:01:49

标签: c# dependency-injection constructor inversion-of-control

我第一次使用构造函数注入,并且希望能够防御性地编写代码。

因此,如果我有一个带有构造函数和save方法的类,如下所示:

public SomeConstructor(string name, Object someObject)
{
  _name= name;
  _someObject= someObject;
}

public void Save()
{
  // Does a database save
}

但是需要在这个Class中创建另一个不需要_someObject的相关方法,所以我创建了一个重载的链式构造函数:

public SomeConstructor(string name) : this(name, null)
{
}

如何使用带有1个参数的第二个构造函数并使用someObject为null的Save()成功阻止某人实例化该类?

我没有使用注射工具。

上面是一个简单的例子,在其中,你是正确的我只能像没有设置属性那样抛出null的异常。

我想避免的是在每种方法开始时进行的一系列验证检查。

4 个答案:

答案 0 :(得分:4)

将您遇到的摩擦用作警告系统。这真的告诉你,你可能会走向低cohesion并违反Single Responsibility Principle

如果是这种情况,请将该类重构为两个单独的类。

答案 1 :(得分:1)

您可以使用InvalidOperationException之类的运行时异常来防止这种情况。

如果某些人使用two-parameters-constructor实例化该类并尝试调用Save,只需检查“someObject”是否为null,如果是这样:

throw new InvalidOperationException("This method cannot be invoked in current object state");

另一方面,如果您的库使用第二个构造函数,并且不允许第三方库开发人员使用它,则此构造函数应该具有内部修饰符。

答案 2 :(得分:0)

public void Save()
{  
    if (_someObject == null)
        throw new InvalidOperationException();
}

我猜这很明显。但是你真的无法创建一个不同构造类型的契约,除非你也将SomeConstructor类型更改为decorator pattern。装饰器模式的作用是让你在运行时而不是编译时构建继承层次结构。

然后,您可以根据内部允许的操作创建不同的对象。对于可以使用Save方法的前提条件轻松处理的内容,这是一些工作。但也许这就是你所需要的。如果你这样做,你可以在SomeConstructor的构造函数中规定你的合同。

以下是一个例子:

interface ISomeConstructor
{
    void Save();
}

class SomeConstructor
{
    ISomeConstructor impl;

    public SomeConstructor(string name, object someObject)
    {
        impl = new StringAndObject(name, someObject);
    }

    public SomeConstructor(string name)
    {
        impl = new JustString(name);
    }

    public void Save()
    {
        impl.Save();
    }
}

StringAndObjectJustString类型实现了ISomeConstructor,他们可以根据需要处理Save方法。

这是装饰器模式的轻微变化,因为通常你会期望ISomeConstructor作为参数传递给构造函数。

答案 3 :(得分:0)

IoC它只是一种动态解决依赖关系的方法,但不解决任何OO问题。 我会专注于一个好的OO设计,而不是试图找到一种方法来欺骗框架强制使用承包商而不是另一个。问题是如果你不使用IoC框架,你会怎么做? 可能检查SomeObject是否为null?