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

问题描述:

我第一次使用构造函数注入并希望防御地编写我的代码。c#构造函数注入和构造函数重载

因此,如果我有一类具有一个构造函数和一个保存如下方法:

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

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

但随后需要建立在这个类另一个相关的方法,该方法不需要_someObject所以我创建一个重载链构造函数:

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

我怎样才能成功地阻止别人用这个第二个构造带1个参数初始化类,并利用具有someObject为空保存()?

我没有使用注射工具。

上面是一个简单的例子,在这个例子中,你是正确的,我可以只为null引发异常,就像我没有设置属性一样。

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

使用您所遇到的摩擦作为警告系统。这实际上告诉你,你可能会走向低点cohesion并违反Single Responsibility Principle

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

+0

但在上面的例子中,你基本上有1个类来保存/删除一个对象,它在构造函数中传递。即1类仅用于持久性?所有其他方法(如Get()最近的SomeObject都需要一个独立的类?这有点听起来像矫枉过正? – asn1981 2011-06-02 12:06:39

+0

有时它是过度的,但是你可以只接受传递给构造函数的参数中的一个参数不被使用。 – 2011-06-02 12:22:30

+0

嗯......我猜并不总是最好的办法。防守编程意味着做出可能违反其他“原则”的决定。我想我只是希望在所有情况下都有一个压倒一切的规则。 – asn1981 2011-06-02 12:42:59

您可以通过运行时异常(如InvalidOperationException)来防止这种情况。

如果某些实例化的类与双参数构造函数并试图调用保存,只是检查是否“someObject”是空的,如果是这样:

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

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

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作为参数传递给构造函数。

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