How to implement mid-level .NET middle classes / methods.

We have a typical N-Layer.NET application that sits between our database and the web API service level. This application consists of Business Layer, Data Repository / Access, as well as related DTOs and Business Objects.

We have solutions for the version of our stored procedures and our web API endpoints. The problem is the solution for the version of this middle tier, the actual class methods, and the schema objects. All Google searches contain results for the source code of the version in the version control solution or how to use the version using the Assembly information, neither what we mean, nor are the results limited.

So, for example, we have two endpoints:

... api / v1 / tax / charges

... api / v2 / tax / value

v1 should hit one version of the CalculateTaxPctgs method and v2, which falls into another version with updated business logic. Along with the need to use different versions of POCO Tax and TaxItems, since we changed the name of one field in version 2.

It is easy to develop, but difficult to manage and a very tough / static solution would be to create two different methods CalculateTaxPctgs_V1 and CalculateTaxPctgs_V2. That doesn't sound like a good idea.

It is difficult to find best practices or even alternative solutions to this dilemma. This is an enterprise application that processes millions of requests every day, so performance is extremely important, but it is also the management and reliability of the code.

+6
source share
3 answers

Obviously, this depends on how your solution integrates, but will redirect assembly versions to something that you could use:

https://msdn.microsoft.com/en-us/library/7wd6ex19%28v=vs.110%29.aspx

You can redirect your application to use a different version of the assembly in several ways: through the publisher policy, through the application configuration file; or through the machine configuration file.

0
source

Instead of using different methods, I would use object inheritance. That way, if the method remains the same between the different versions, you do not need to change the implementation in any way. Then you can use factory to create the required instance. For instance:

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(); } } 

If api implements the whole new version every time the factory can be more general and something like:

 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 } 
0
source

To solve this problem, we have implemented dynamically loaded assemblies that process more than 80 different versions. It works well. We do not change the deployed software (unless there is a serious flaw), since this is part of the production system that we cannot afford to break when it works.

We also have some critical changes over time, for example, using several different versions of .NET. To cope with this, we send requests for different application deployments.

0
source

Source: https://habr.com/ru/post/985690/


All Articles