There's no telling what would be the "best" way to do this, it would give a huge margin for opinion, so I'll try to express the pros and cons of each form.
Before looking at this you should see whether or not you will share the types between the server and the clients. There are some factors that can influence this decision, such as versioning, type errors (breaking the client like this), duplication of code, possible errors in keeping the data between the client and the server, etc. These factors can influence whether or not you will share the data types.
If you decide to share, you would have the two options you showed, duplicate the code, or do the dll's / package versioning.
Using this form you are ensuring that the typing will be the same
between applications, thus not causing typing problems;
You will not have issues with serialization / decerialization because the types will be the same;
- Code duplication;
- Possible type error that will cause application problems;
- More work to keep codes up to date;
You have the same structure as if you were to duplicate the code, but it has the ease of versioning, thus making it less prone to errors, guaranteeing a "security" for communication between applications.
For example, if you have version 1.5.6 on the client and the server has 1.6, you may have some problems. With versioning you know what has changed and if it caused problems, you know how to fix it.
Now, if you do not choose to share the types, you will have a different scenario.
Using this form you would not be sharing the types between the client and the server, that is, explicitly. A possible modification on the server would not "break" the client, and vice versa.
- Client model is less connected to server, mirroring only output, but not types;
- The Server can be modified without risk to the clients;
- Allows improvements on any side (client-server) without "breaking" the application.
- Do not care about types;
- You do not have a contract between the client and the server;
- You do not know when you have any significant changes that could cause problems;
- Client and Server with different versions is more complex to find an error that could eventually happen;
- Do not care about types;
Note that not worrying about types is in pros in cons. The way you treat the data will decide whether it will be for or against.
Using typing defined between the systems will ensure a greater coupling, thus leaving more "security", if that is the word. However, you may experience problems if you have a different type of application. Without definite typing, you will have "problems" of versioning and weak typing. There is no way to be sure that you will have these problems, but rather problems that may arise during the project.
There is no "best" way to do this. We do not know about your project or how it would be applied in your application scenario.
There are some libraries that ~ promise ~ to accept both types, Expando is one of them. In this link you have a tutorial if you want to verify its operation.
Note: Regardless of the options you are sharing the types, the difference is that one is explicit and the other is not.
I have a certain drop by versioning in packages for greater control between systems. That way I will know exactly what has changed and where it has changed. If something happens, I'll know where to fix it.