I know what you're thinking... "This is a duplicate of
- c# call method based on contents of a variable, or of
- How to call an appropriate method by string value from collection?, or of
- Calling a method based on value of variable [duplicate]"
This is however not the case.
Scenario
I have two production systems that have the same type of data and they each have their own API. Unfortunately some of the API calls for these systems are different and some are the same. I want to create a generic interface/translation layer that would convert generic calls into the respective calls of the system being queried
During startup, the integration would check which version of the production system it needs to connect to and store that value in a variable. When I call "GetVehicle" I want to automatically translate this request into either "GetTruck" or "GetCar" based on the value of the previously defined variable.
Below is a short pseudo-code-ish example of what I'm trying to accomplish.
NOTE: You can skip to the bottom of the page if you want to read the question first.
There will be an enum
public enum TypesOfVehicles
{
Commercial,
Residential
}
The main program would instantiate the object and set the variable, then perform some action on the instantiated object.
internal static class Program
{
static void Main(string[] args)
{
var doStuffWithVehicles = new DoStuffWithVehicles();
doStuffWithVehicles.TypeOfVehicle = TypesOfVehicles.Commercial;
var myTruck = doStuffWithVehicles.GetVehicle(1);
doStuffWithVehicles.TypeOfVehicle = TypesOfVehicles.Residential;
var myCar = doStuffWithVehicles.GetVehicle(1);
}
}
DoStuffWithVehicles would be the "middleware/translation" layer for the two production systems. There are substantially more than two methods that would have to be mapped?
public class DoStuffWithVehicles
{
public TypesOfVehicles TypeOfVehicle { get; set; }
public T GetVehicle(int id)
{
switch (TypeOfVehicle)
{
case TypesOfVehicles.Commercial:
return HeavyVehicle.GetTruck(id);
break;
case TypesOfVehicles.Residential:
return LightVehicle.GetCar(id);
break;
}
}
public int GetWheels(int id)
{
switch (TypeOfVehicle)
{
case TypesOfVehicles.Commercial:
return HeavyVehicle.GetWheels(id);
break;
case TypesOfVehicles.Residential:
return LightVehicle.GetWheels(id);
break;
}
}
}
And the production system classes would look something like this
public class HeavyVehicle
{
public T GetTruck(int vehicleId)
{
return commercialContext.Query<HeavyVehicleObj>().Where(x => x.id == vehicleId);
}
public int GetWheels(int vehicleId)
{
return commercialContext.Query<HeavyVehicleObj>().Where(x => x.id == vehicleId).Select(x => x.nrOfWheels).FirstOrDefault();
}
}
and
public class LightVehicle
{
public T GetCar(int id)
{
return residentialContext.Query<LightVehicleObj>().Where(x => x.id == id);
}
public T GetWheels(int id)
{
return residentialContext.Query<LightVehicleObj>().Where(x => x.id == vehicleId).Select(x => x.nrOfWheels).FirstOrDefault();
}
}
Question Is there a way to build this type of interface/translation layer without having to create a switch for every single method that exists in both of the production system APIs?
Due to the performance impact of reflection (the system performs 100s of transactions per second and all of them include a SQL component), it is not an option.