vendredi 7 août 2020

Refactoring C# switch to remove explicit calls to methods using Reflection and DI

so i have been tasked with refactoring some code and have so far been unable to get to a working solution. The goal of the refactoring is to remove the explicit call to the subclasses by using reflection and dependency injection. The results should not change but the code should allow for new subclasses to be added without the need to rewrite any part of the code.

So far my idea was to first using Reflection API to get all the subclasses of the main abstract Instruction class, then get the execute method paramaters for each and here is where i am stuck, i have no idea how to use Dependancy injection to replace the switch statement.

Here is the relevant code: Translator.cs

                switch (opcode)
                    {
                        case "add":
                            ins = new AddInstruction(label, r, s1, s2);
                            break;
                        case "sub":
                            ins = new SubtractInstruction(label, r, s1, s2);
                            break;
                        case "mul":
                            ins = new MultiplyInstruction(label, r, s1, s2);
                            break;
                        case "div":
                            ins = new DivisionInstruction(label, r, s1, s2);
                            break;
                        case "out":
                            ins = new PrintInstruction(label, s1);
                            break;
                        case "lin":
                            ins = new StoreInstruction(label, r, s1);
                            break;
                        case "bnz":
                            ins = new SwitchInstruction(label, s1, l2);
                            break;
                        default:
                            return false;
                    }

Instruction.cs

    public abstract class Instruction
    {
        private string label;
        private string opcode;

        protected Instruction(string label, string opcode)
        {
            this.label = label;
            this.opcode = opcode;
        }

        public override string ToString() => label + ": " + opcode;

        // Execute this instruction on machine m. 
        public abstract void Execute(Machine m);
    }
}

AddInstruction.cs All other instructions have similar layouts

    public class AddInstruction : Instruction
    {
        private int reg, s1, s2;

        public AddInstruction(string lab, int reg, int s1, int s2) : base(lab, "Add")
        {
            this.reg = reg;
            this.s1 = s1;
            this.s2 = s2;
        }

        public override void Execute(Machine m) =>
            m.Registers[reg] = m.Registers[s1] + m.Registers[s2];

        public override string ToString() =>
            base.ToString() + " r[" + reg + "] r[" + s1 + "] r[" + s2 + "]";
    }
}

How would one go about making it so that the program can take future implementations of the Instruction class without using a length switch statement?

Thank you in advance





Aucun commentaire:

Enregistrer un commentaire