Add ServiceStack Reference
I'm just trying out your VS Add ServiceStack Reference plugin for the first time. Seriously awesome stuff! I'm using it to keep the DTOs in sync across my mobile projects.
On the whole it seems to work perfectly. However some things I'd like some clarity on:
1) How can I change the default namespace of the generated dtos.cs file? Could this be a MetadataTypesConfig setting? The namespaces on the mobile apps do not necessarily map to the namespaces from the web services projects.
2) In my DTOs I have enums. If the enum lives in the same namespace as the DTO object, the generated Enum names (in the metadata) are properly populated and the correct enum created in C# with it's values in code. However due to the structure of some of my projects, the enums are not necessarily defined in the same namespace at the DTO. In this situation (for enums and classes), the corresponding classes and enums do not seem to be generated in C#. I can provide you an example link privately to show you what I mean if you want.
Thanks for your help!
It's normal for namespaces of Server DTO's not to match up with the client project, i.e. the generated DTO's would mirror the sane C# namespaces as if you were sharing your Server DTO .dll instead.
Changing the global namespace is currently only possible in languages which have all DTO's under a single namespace which atm is only F# and TypeScript, I'll look at adding this feature to C# and VB.NET as well although this will mean that every DTO will need to be uniquely named (a restriction not required with multiple namespaces).
Is the enum in the same Project as Server DTO dll? i.e. would the client have access to it if you shared your Server DTO .dll instead? In which case the recommended practice is to make sure that everything the client needs to communicate with your Service is in a separate stand-alone DTO project. You can also remove the dependency on internal system enums by changing the property on the DTO to be a string.
Dylan v.d Merwe:
I understand about having a stand-alone DTO project with all the relevant communication items in, however this is not possible in my case due to the setup of the many client projects and dependencies.
Still in this case would it not be possible to generate the code for the required enums/classes regardless? The generated code would be independent from the server's implementation (and namespaces and project are actually irrelevant at this point) which I thought would be the aim. If it's not possible I'll take a look at the generation code to see what I can tweak, otherwise I can always keep on maintaining the files manually across the projects
This is really something you should be striving for as otherwise you're headed down a slippery slope where it's no longer possible to call your Services with just a url and its self-contained DTO's (irrespective as to how big or complex or large the System gets). Once you break this contract it'll become harder to recover from the situation where you've now brought a tonne of extra complexity to your Services consumers who'll now have to research the cyclical dependencies of your Servers .dlls to determine whether it's feasible or not to call your services with its typed DTO's.
The problem with this heuristic of bringing it internal enums/types is that it makes it difficult to determine whether or not we're re-declaring already existing .NET enums/types will cause compilation errors. I can investigate offering custom server configuration to explicitly include external types, but as it's something I would like to discourage I don't want to add extra complexity to deal with it. IMO the best solution is you manually redeclare the internal enums on the client which as it's outside of the normal path shows that it's a code-smell (a bad one IMHO) and it's something that will let you keep track of how bad it gets and hopefully encourage refactoring it later on. Also as I mentioned earlier changing the DTO enum property to a string also breaks the explicit binary contract which is another option that's an easy workaround.
Dylan v.d Merwe:
I get at what you're saying, but if you had to see the project structure you'd understand. Just to clarify, all Service classes and DTOs are contained within their respective projects/dlls. This goes to what you were saying with keeping them all in-check. It's just that the DTOs themselves sometimes contain enum fields or Lists of other DTO-like classes that do not exist in the main DTO dll - these are the items which are not being properly generated. I still believe that they should be. The reason these enums or DTO like classes are not contained in the primary DTO dll is due to other references or integrations.
"It's just that the DTOs themselves sometimes contain enum fields or Lists of other DTO-like classes that do not exist in the main DTO dll... The reason these enums or DTO like classes are not contained in the primary DTO dll is due to other references or integrations. "
This is the slippery slope I'm saying should be avoided - in order for this to be possible your services now rely on internal types outside of your DTO's, so now clients need knowledge of your internal types. Again I'd highly discourage this, you can also avoid this dependency with a copy of the enums in the DTO .dll and just use
ConvertTo to translate between them.
If you want you can put together a small repro with empty/Mock Services and I can look at whether it's something that can be easily avoided without causing further regressions.
I've added support for GlobalNamespace on C# and VB.NET as well available from next v4.0.37+ that's now on MyGet: https://github.com/ServiceStack/ServiceStack/wiki/MyGet
You can play around with the deployed version on: