I am developing a client / server business software system using a custom HTTP based design that works similarly to CSLA.NET. What I will be doing is creating client and server objects where client method calls get serialized in to json (using json.net) or other format and then deserialized on the server in to the mirror server version. I am using custom attributes to mark functions and classes that can be called remotely. If it is an instance method it will serialize the calling object as well, where as static calls obviously will just serialize the method parameters. When the server call finishes it will respond with the method result, error state, and the new copy of the object in the case of instance calls.
I already have a test version of this running. What I am trying to do now is figure out the best pattern to use for these client and server object. My test version uses completely separate classes on the client and server. While that works I would like them to be more tied together to ensure that all the properties are the same etc.
I am relatively new to C# and do not have a whole lot of experience with them, but I thought that maybe using interfaces would be the best way. I am not 100% of the reasons for choosing interfaces vs normal class inheritance, but I can't think at the moment of any situation where I would have a use for a base class implementation so it seemed like a reasonable choice. The problem I ran in to was when I tried to do something like have a LoadCustomers
method that would return a List<IMyObject>
. The client version would need to cast a List<IMyObject>
to a List<MyObject_Client>
. It would error out though. It seems that while it works with casting the classes themselves, when you do it with generics like this it doesn't work. I think I would be able to get by casting each time I used the items in the List
vs casting the List
itself, but that seems messier to me. I also worried about having properties defined in the interface like List<IMyObject>
where technically they would accept any type of implementation of IMyObject
, but really when I am on the client I only want MyObject_Client
objects to be in that list. Both of these problems seem like they would also exist if I was using simple class inheritance instead of interfaces.
So at this point I am thinking that the best option is to make it one object for both client and server. What this means is that I would have some static context class that would maintain whether the program was using client or server objects. Then in each method would look something like this:
if (MyContextObject.ObjectContext == ocClient)
{
//Code to serialize and make call to server and return result
} else {
//Actual business logic
}
or
if (MyContextObject.ObjectContext == ocClient)
{
//Call to private client version of the function
} else {
//Call to private server version of the function
}
I have also considered possibly using delegates that get set during the constructor depending on the context. I am not sure if that is worth it or not partially because I am such a C# novice. It may improve readability I guess?
Having one class would be nice from the stand point of it all being in one place and it makes it easier to facilitate client to server calls because the exact object name you want to use on the server is the same exact one that is on the client. The problem is that isolating the client objects from the server objects has it's benefits as well.
So my question is what pattern should I use for these client server objects?
My concerns are:
- Robustness / Reliability / Speed - This will replace a real existing product so I don't want slow or "hacky" code)
- Maintainability - I want to easily be able to make updates and keep both client and server objects in sync. The more help from the compiler to make sure I didn't miss something on either one of the objects the better
- Readability - This is part of maintainability, but it is very important to me that it is simple and easy to understand code that is going to be used by multiple developers. By easy I mean easy for a programmer that understands the pattern we are using.
- Time to implement - I am coming from a horrible fat client world, but one of the only benefits it had was that I only had to implement one version of each method. Now I have two. The easier and faster it is to implement each method the better.
- Static - I would like it to be possible to use both static and not static methods. Some of the methods like LoadCustomers I would like to be static calls. I tried abstract classes I think and ran in to problems when the method was static.
- Platforms - I HAVE to support running the client AND server on every version of Windows start with Windows XP. I also must also be able to support 3rd party client implementations on any platform (web or desktop or mobile). We provide the main desktop app to use the software right now, but we want to be able to start interfacing with handheld devices (w/ barcode scanners) using html based clients we write. Also, today 3rd parties will write to our database directly so in the future I want to be able to provide them with a safe API to use to discourage them from destroying our customer's data because they don't know what they are doing :D