C# 无代码契约的前提条件

C# 无代码契约的前提条件,c#,asp.net,.net-4.0,refactoring,C#,Asp.net,.net 4.0,Refactoring,在ASP.net MVC中,不一定局限于MVC,仅举一个例子,我们的操作方法中始终具有与以下方法类似的先决条件: [HttpPost] public ActionResult Edit(FooModel viewModel) { if (viewModel == null) { throw new ArugmentNullException("viewModel"); } if (viewModel.Foo < 1) {

在ASP.net MVC中,不一定局限于MVC,仅举一个例子,我们的操作方法中始终具有与以下方法类似的先决条件:

[HttpPost]
public ActionResult Edit(FooModel viewModel)
{
    if (viewModel == null)
    {
        throw new ArugmentNullException("viewModel");
    }

    if (viewModel.Foo < 1)
    {
        throw new InvalidOperationException();
    }

    // Perform real tasks on viewModel (e.g. map it to model, persist to database)

}
在foododelrepository.cs中:


我的问题是,我们有没有更好的方法来重构代码,而不让存储库被这样的检查弄得乱七八糟?

我看不出有什么比这更清楚的东西是您已经提供的,是的,允许您向程序中添加声明性行为,但也隐藏了清晰的逻辑。因此,正如任何事情一样,它有两个方面:好的和坏的

我个人会选择你选择的解决方案,所以有简单的控制方法。 我想请大家注意的唯一一件事是:

public static bool IsValid(FooModel viewModel)
{
 ...
}

returs bool,所以在失败/否定响应的情况下,我希望返回false/true值,而不是引发异常。这是程序的控制流,所以简单地返回true或returnfalse就足够了,并且可以从方法的使用者那里得到

另一个选项是创建验证类。您只需将这些类的对象添加到列表中,并询问列表中的每个验证是否有效。只是其中一些优势:

相同的验证可重复用于其他控制器。 如果添加了验证,现有代码将保持未触及的打开/关闭原则 单元测试验证更容易,因为您不必调用控制器来查看它是否工作 如果您确实找到了验证上的所有引用,则可以看到使用验证的所有控件 您可以稍后选择是否只需要bool的异常而不更改验证。 更多信息和示例:

.Net 4.5支持真正的合同,请参见:我被困在.Net 4.0中。不幸的是:根据MSDN 4.0中也提供的消息,我的记忆力从来都不是最好的。我只是在4.5中开始使用它。因为我继承了一个现有的代码库,所以我不想引入对代码契约的新依赖。我只是想知道我上面的方法是否可以更好地重构。有没有一种方法可以在没有代码契约的情况下实现同样的效果?但是如果在viewModel处于无效状态时返回false,我将无法通知调用方无效状态的详细信息,例如哪个属性无效。@rexcfnghk:以及您如何向调用方发出无效状态的信号?引发异常类型?否,但如上例所示,如果我想将无效状态与一些更有意义的消息关联并将其发送回调用者,我该如何做?问题:但为什么要将ViewModel内容验证代码移到ViewModel本身之外?为什么不将ViewModel字段验证的责任推给ViewModel本身?如果state invalid或valid是上下文敏感的,那么您可以根据它相应地设置html控件的样式
public static bool IsValid(FooModel viewModel)
{
    if (viewModel == null)
    {
        throw new ArgumentNullException("viewModel");
    }

    if (viewModel.Foo < 1)
    {
        throw new InvalidOperationException();
    }

    // ...many more checks and throw exceptions accordingly

    // if we reach up to here, we are good, return true
    return true;
}
public static bool IsValid(FooModel viewModel)
{
 ...
}