Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I "override" a method in a partial class?

Tags:

c#

I've been looking for a solution to a complex problem we're having in my company. This company is part of an alliance of 4 companies that covers our country in four "regions". Our branch developed a WebService in C# and we distribute this project to our fellow developers in the other branches. Everyone hosts the WebService in their own servers.

Now, I've been struggling with something you can expect when the companies don't get along. I have to adapt an existing method to suit our "regional needs".

So I've got this class :

public partial class MyClass{
     public static ComplexReturnType MyMethod(){
          // National code. Everyone uses this block of code.
     }
}

I created a Regional folder that I will exclude from compilation when distributing the DLL to the other branches. Inside this folder I created the file MyClass.cs and went on with this :

public partial class MyClass{
     public static ComplexReturnType MyMethod(){
          // Regional code. Only my commpany will use this.
     }
}

The method MyMethod is called in other files. I understand how partial works, but I can't find a solution that suits my needs without creating a child class and rewriting every call already present in the other files.

Does anyone have an idea on how to deal with this ?

Edit after answer

I decided to go with the Strategy Design Pattern, and when I was done I thought "If a branch decides to overwrite any method, all the other branches have to override the same method with the national code in their regional strategy class".

So that's not really nice. Instead I did this :

public class VStrategy
{
    public virtual ComplexReturnType MyMethod(){
        // National code. Method moved from MyClass
    }
    public virtual AnotherReturnType MySecondMethod(){
        // National code. Method moved from MyClass
    }
}

public class SomeBranchStrategy: VStrategy
{
    public override ComplexReturnType MyMethod() {
        // Regional code for overriding a method
    }
}

public class AnotherBranchStrategy: VStrategy
{
    public override AnotherReturnType MySecondMethod(){ {
        // Regional code for overriding a method
    }
}

public class MyClass
{
    private static VStrategy _strategy = new VStrategy();
    public static VSTrategy Strategy { get {...}; set {...} }
    public static ComplexReturnType MyMethod()
    {
        return Strategy.MyMethod();
    }
    public static ComplexReturnType MySecondMethod()
    {
        return Strategy.MySecondMethod();
    }
}

This way, without the Interface, every branch can override any method they want without an impact for the other branches. You just move the method code to the VStrategy class and override it in your own Regional class.

Hope this helps anyone who could be in this situation.

like image 246
shajz Avatar asked Dec 15 '22 06:12

shajz


1 Answers

Like Maurice Stam said, encapsulate what varies. At first glance, I would use the strategy pattern: http://www.oodesign.com/strategy-pattern.html

public interface IStrategy
{
    ComplexReturnType MyMethod();
}

public class NationalDefaultStrategy : IStrategy
{
    public ComplexReturnType MyMethod() { }
}

public class BostonStrategy: IStrategy
{
    public ComplexReturnType MyMethod() { }
}

public class MyClass
{
    private static IStrategy _strategy = new NationalDefaultStrategy();
    public static ISTrategy Strategy { get {...}; set {...} }
    public static ComplexReturnType MyMethod()
    {
        return _strategy.MyMethod();
    }
}

This way, you can easily change the strategy being used at runtime

MyClass.Strategy = new BostonStrategy();

If you make it an instance method instead of a static one (I probably would) and decide to use an IoC container like Castle Windsor, you could even wire up the strategy in a configuration file.

Edit

Logically, each branch would have their own configuration file. There are two advantages in using this approach:

  • all branches would be using the same code base
  • your code would obey the Open Closed principle, which states that your classes should be closed for modification, and open for extension: http://en.wikipedia.org/wiki/Open/closed_principle.
like image 110
dcastro Avatar answered Dec 22 '22 00:12

dcastro