Project
I’ve developed a remoting class which is used to replace a subset of WCF. This has been done because we are targeting a mobile Plattform with Unity3D and need to keep the Memory consumption as small as possible. ( So we don’t need to include System.ServiceModel which actually has a size of 2.7MB which is a lot for a small mobile RAM )
It’s working fine right now for all types ( including complex types which will be serialized using my own serializer written years ago ) and it’s also capable to handle complex situations ( A calls B, B calls A, A returns something, B returns something ).
Method invokation
For invoking methods on the target site i’m using Type.InvokeMember which actually works for the most cases except for nullable-types. And this is the problem i’ve faced. In my interface definition the method looks like this:
public interface IServerContract
{
void SetUsageID(Int32? id);
}
The ServerProxy ( A object which handles the call to the remote method ) i’m doing the following:
public class ServerProxy : ProxyBase
{
public void SetUsageID(Int32? id)
{
RemoteCall("SetUsageID", id);
}
}
As usual the parameter id is boxed because the definition of RemoteCall looks like this:
public void RemoteCall(String methodName, params Object[] arguments) { ... }
At this point i got only a System.Int32 and not a nullable anymore. I’m serializing the arguments and deserializing them on the target machine. At this point i’m calling Type.InvokeMethod which causes a exception because he can’t find a method which takes a Int32 as first parameter ( second when not ignoring this ).
What is the best solution for this issue? There are serval ways but all would cause a performance impact.
The boxing rules for
int?indeed mean that once you have it as anobjectyou see:null, and nothing more can be discerned(int)5and(int?)5have exactly the same appearance withinobjectAs such, the options available:
MethodInfo, then useMethodInfo.Invoke(this ensures no ambiguity in the parameters)Personally, though, I have a very simplistic view on such things… rather than trying to encode a vague multi-parameter method, another option is to simplify to always passing a single, DTO-based, parameter – i.e. instead of
SetUsageID(int?)you could haveSetUsage(SetUsageArgs)(or something similar), whereSetUsageArgshappens to have a single property. The point being: you’re now just encoding a single DTO, and once you have deserialized that DTO there is no ambiguity.