如何对中间层.NET应用程序类/方法进行版本化

时间:2015-04-22 14:41:13

标签: c# .net versioning asp.net-web-api2

我们有一个典型的N层.NET应用程序,它位于我们的数据库和Web API服务层之间。此应用程序包括业务层,数据存储库/访问以及相关的DTO和Business Objects。

我们有适当的解决方案来版本化我们的存储过程和Web API端点。问题是这个中间层版本的解决方案,实际的类方法和架构对象。所有Google搜索都会在源代码管理解决方案中提供源代码版本的结果,或者如何使用程序集信息进行版本化,这些都不是我们所指的,因此结果有限。

例如,我们有两个端点:

... api / v1 / tax / charges

... API / V2 /税务/费用

v1必须点击方法的一个版本CalculateTaxPctgs,v2点击具有更新的业务逻辑的另一个版本。当我们在v2中更改了一个字段的名称时,需要使用不同版本的POCO Tax和TaxItem。

易于开发但难以管理且非常严格/静态的解决方案是创建两个不同的方法,CalculateTaxPctgs_V1和CalculateTaxPctgs_V2。这似乎不是一个好主意。

很难为这种困境找到最佳实践甚至替代解决方案。这是一个企业应用程序,每天需要数百万个请求,因此性能非常重要,但代码管理和可靠性也是如此。

2 个答案:

答案 0 :(得分:0)

我使用对象继承而不是不同的方法。这样,如果方法在不同版本之间保持不变,则不需要以任何方式更改实现。然后,您可以使用某种工厂来创建所需的实例。例如:

public virtual class TaxCalculatorBase {
    public virtual ICollection<TaxPercentage> CalculateTaxPercentages() {
        DefaultImplementation();
    }
}

public sealed class TaxCalculatorV1 : TaxCalculatorBase {
    //Same implementation so no need to override
}

public sealed class TaxCalculatorV2 : TaxCalculatorBase {
    //Same implementation but with a bit extra
    public override ICollection<TaxPercentage> CalculateTaxPercentages() {
        base.CalculateTaxPercentages();
        ExtraStuff();
    }
}

public sealed class TaxCalculatorV3 : TaxCalculatorBase {
    //Different implementation
    public override ICollection<TaxPercentage> CalculateTaxPercentages() {
        NewImplementation();
    }
}

public static class TaxCalculatorFactory {
    public static TaxCalculatorBase Create(int version) {
        switch (version) {
            case 1: return new TaxCalculatorV1;
            case 2: return new TaxCalculatorV2;
            case 3: return new TaxCalculatorV3;
            default: throw new InvalidOperationException();
        }
    }
}

public class CallingClass {
    public void CallingMethod(int versionFromURL) {
        var calculator = TaxCalculatorFactory.Create(versionFromURL);
        var percentages = calculator.CalculateTaxPercentages();
        percentages.DoStuffWithThem();
    }
}

如果api实现了一个完整的新版本,那么每次工厂都可以更通用,例如:

public static class MyFactory {
    public static TaxCalculatorBase CreateTaxCalculator(int version) {
            switch (version) {
                case 1: return new TaxCalculatorV1;
                case 2: return new TaxCalculatorV2;
                case 3: return new TaxCalculatorV3;
                default: throw new InvalidOperationException();
            }
        }
    }
    //various other methods to create classes which depend on version
}

答案 1 :(得分:0)

为解决这个问题,我们实现了动态加载程序集,可处理80多个不同的版本。它运作良好。我们不会更改已部署的软件(除非存在严重缺陷),因为它是生产系统的一部分,一旦工作,我们就无法承受。

随着时间的推移,我们也有一些重要的变化,比如使用几个不同版本的.NET。为了解决这个问题,我们将请求路由到不同的应用程序部署。