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

c#构造函数注入和构造函数重载,c#,dependency-injection,constructor,inversion-of-control,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 } 但是需要在这个类中创建另一个不需要_someObject的相关方法,所以我创

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

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

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个参数)实例化该类,并使用Save()将someObject设置为null

我没有使用注射工具

上面是一个简单的例子,在其中,您是对的,我可以为null抛出一个异常,就像我在未设置属性时所做的一样


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

您可以使用运行时异常(如InvalidOperationException)来防止这种情况

如果有人使用双参数构造函数实例化类并尝试调用Save,只需检查“someObject”是否为null,如果为null:

抛出新的InvalidOperationException(“无法在当前对象状态下调用此方法”)

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

public void Save()
{  
    if (_someObject == null)
        throw new InvalidOperationException();
}
我想这是显而易见的。但是,除非您也将
SomeConstructor
类型更改为与其他类型类似的工作方式,否则您确实无法创建以不同方式构造类型的契约。decorator模式的作用是让您在运行时而不是编译时构建继承层次结构

然后,您可以根据内部允许的操作创建不同的对象。这是一些可以通过
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();
    }
}
类型
StringAndObject
JustString
实现
isomoconstructor
,它们可以根据需要处理
Save
方法


这是装饰器模式的一个微小变化,通常您会期望
isomconstructor
也作为参数传递给构造函数。

IoC认为,这只是一种友好解决依赖关系的方法,但不会解决任何OO问题。 我会把重点放在一个好的OO设计上,而不是试图找到一种欺骗框架的方法,强迫使用一个承包商而不是另一个。问题是如果你没有使用IoC框架,你会怎么做?
是否可能检查某个对象是否为空?

将您遇到的摩擦作为一个警告系统。它真的告诉你,你很可能正在走向低谷,并违反了法律


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

但是在上面的示例中,您基本上有一个类来保存/删除一个在构造函数中传递的对象。也就是说,1节课只是为了持久性?所有其他方法,如Get()和最近的SomeObject,都需要单独的类吗?这听起来有点过头了?有时这是过头了,但是你可以接受传递给构造函数的一个参数并不是在所有情况下都使用。嗯。。。我想并不总是有最好的方法。防御性编程意味着做出可能违反某些其他“原则”的决定。我想我只是希望在所有情况下都有一条覆盖规则。添加第二个构造函数以允许一个或多个字段保持null很难被称为防御性编码…添加一个Guard子句: