Every once in a while when writing code I face a situation where I want to do something trivial, something that is usually done as a no brainer for a programmer. I start writing code and hit a wall immediately, it turns out it’s not as straightforward as it seems.
What I wanted to achieve
I am calling 4 different web services from 4 different methods. Each web service has a method that receives a request as an object and initiates a BizTalk orchestration. The request object is quite big, it has lots of properties that need to be filled. All 4 request objects have exactly the same properties inside (same names and types) but the objects differ in the class name and namespace. Have a look at the below class diagram.
Each object is going to be filled in it’s respective method and since all classes have the same properties there will be redundant code in all 4 methods. I want to extract the code that fills the object into a separate method that will take the request object and all it’s values as parameters and assign the properties with their correct values. This method will be called from the 4 places where I want to fill the request object.
In order to access the properties of any of my request classes I must have an instance of that type. The issue is that the method I want to create doesn’t always receive the same type as a parameter. It could be any one of the 4 types shown in the diagram.
You might say why not change the parameter type to “object”. The problem with this is that I have to cast this object to one of the above types and hold a reference to it in order to fill it’s properties.
The solution was changing the parameter type to “dynamic”. After all this parameter may have 4 possible types. The caller of this method will then be responsible for casting back the dynamic object to the type it requires.
This is what the code looks like without using “dynamic”
Type1 type1 = new Type1();
type1.Prop1 = 1;
type1.Prop2 = 2;
type1.Prop3 = 3;
type1.Prop4 = 4;
type1.Prop5 = "a";
type1.Prop6 = "b";
type1.Prop7 = "c";
type1.Prop8 = "d";
type1.Prop9 = true;
type1.Prop10 = true;
type1.Prop11 = false;
type1.Prop12 = false;
Remember that I have more properties than this and that this code will be duplicated 4 times.
This is what the method that will fill the objects look like:
public void FillData(ref dynamic request, int prop1, int prop2, int prop3, int prop4, string prop5,
string prop6, string prop7, string prop8, bool prop9, bool prop10, bool prop11, bool prop12)
request.Prop1 = prop1;
request.Prop2 = prop2;
request.Prop3 = prop3;
request.Prop4 = prop4;
request.Prop5 = prop5;
request.Prop6 = prop6;
request.Prop7 = prop7;
request.Prop8 = prop8;
request.Prop9 = prop9;
request.Prop10 = prop10;
request.Prop11 = prop11;
request.Prop12 = prop12;
The following code will call the above method, this code will be called in the 4 places where I need to fill my request object. Each time the appropriate type will be used.
Type1 type1 = new Type1();
dynamic dynamicType = (dynamic)type1;
FillData(ref dynamicType, 1, 2, 3, 4, "a", "b", "c", "d", true, true, true, true);
type1 = (Type1)dynamicType;
At the end
You’re probably saying to yourself that I am over thinking this and that it’s too much fuss just to avoid duplicating code. Perhaps you are right but small things like this annoy me. I am always trying to find the most optimized way.
I’d love to hear comments and improvements or if I can achieve the above in a different way.