【问题标题】:Execute Set of ValidationRule-C# Class Design - Better Approach执行一组 ValidationRule-C# 类设计 - 更好的方法
【发布时间】:2017-06-24 10:39:34
【问题描述】:

我有一个案例,我需要为不同的公司执行一组验证规则。一个公司会有多个验证规则。

所以我有下表结构

公司

ID 公司名称 1个ABC 2 防御

验证规则

规则 ID 名称 1 规则1 2 规则 2

CompanyValidationRuleMapping

MappingID CompanyId RuleID 1 1 1 2 1 2 3 2 2

我对每个验证规则都有单独的存储过程。

所以从我的c#代码中,我会找到一个公司对应的所有验证规则,并需要执行与该规则关联的验证存储过程。

所以我打算保留一个具有不同验证方法的接口“IValidation”。

或者

我可以为每个实现接口的验证创建不同的类吗

任何人都可以提出一个更好的方法。

【问题讨论】:

  • 原谅我的无知,SP到底是什么?
  • @CKing 存储过程
  • 那么对于每条规则都必须执行一个存储过程?
  • @ATC..Yes..验证后我需要提出不同的服务调用。我的疑问是类设计
  • 我不知道您的软件是如何设计的,或者我是否理解正确。您是否正在验证数据库中已保存的整体?在我看来,验证最好放在 1,在用户输入之后,在调用任何业务逻辑之前; 2、业务逻辑运行后保存到数据库前。所以要验证业务对象或实体。

标签: c# .net oop architecture class-design


【解决方案1】:

您的第一级通用验证接口,可以灵活地提供结果类型和要验证的模型:

public interface IValidate<T, R>
    where T : class
    where R : class // where T is any custom result and R is your custom model
{
    T Validate(R model);
}

假设,我需要验证将由不同的 sp 完全处理的公司政策:

public interface IValidateCompanyPolicies : IValidate<ValidationResult1, Company>
{
  ValidationResult1 Validate(Company model);
}

同样,我还需要检查公司的货币账户、税收、审计等:

public interface IValidateCompanyAccounts : IValidate<ValidationResult2, Company>
{
  ValidationResult2 Validate(Company model);
  bool HasAuditPassed(Company model);
}

分别。处理两种 IValidate 接口的类

public class ValidateCompanyPolicies : IValidateCompanyPolicies
{
    ValidationResult1 Validate(Company model)
    {
        // Hit stored procedure corresponding to company policies validation
    }
}

public class ValidateCompanyAccounts : IValidateCompanyAccounts
{
    ValidationResult2 Validate(Company model)
    {
        // Hit stored procedure corresponding to company's monetary accounts validation
    }

    bool HasAuditPassed(Company model)
    {
        // Hit stored procedure corresponding to get company audit results
    }
}

我的最终类需要在执行验证后执行所有业务密集型操作:

public class XYZCompany
{
    private IValidateCompanyPolicies companyPoliciesValidation;

    private IValidateCompanyAccounts companyAccountsValidation;

    public XYZCompany(
        IValidateCompanyPolicies companyPoliciesValidation,
        IValidateCompanyAccounts companyAccountsValidation)
    {
        // Perform DI
    }

    public bool UpdateCompany(Company model)
    {
        var checkPolicies = this.companyPoliciesValidation.Validate(model);

        if (checkPolicies.Success)
        {
            var checkAccounts = this.companyAccountsValidation.Validate(model);

            var auditSuccess = this.companyAccountsValidation.HasAuditPassed(model);

            if (checkAccounts.Success && auditSuccess)
            {
                // Perform DB save
            }
        }
    }
}

【讨论】:

  • @RRM..非常感谢你的详细回答..我会试试这个
【解决方案2】:

有几种情况:

  • 如果所有 Valudation SP 具有相同的参数和结果,您可以创建一个类来调用所有 SP,并将 SP 名称存储在 CompanyValidationRuleMapping 表中。看 Called SP from another SP

  • 如果每个 SP 都非常不同,那么您需要为每个 SP 设置不同的类

我建议使用相同的参数和结果创建所有 SP,因为这种方法更容易扩展和更改。

【讨论】:

  • 参数相同,但返回结果不同
  • 实现 IValidation 的每个规则的单独类会更好,验证的运行方式可能会改变(现在您使用的是 SP,这本身可能会改变)并且 IValidation 类的调用者只需关心什么IValidation 的底层方法返回,它本身将包含有关验证结果的所有详细信息。
  • 请注意公司资源,不久前我在一个使用许多规则的地方工作,并且大多数进行大量维护的人都非常擅长 SQL 而不是 C#,所以在那种情况下,拥有比 C# 类更多的 SP 会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 2012-07-20
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多