Adding an attribute to generated classes for use by clients


I have a customer who is consuming our provided ServiceStack API as part of their own web site using Azure Redis for some aspects.

They’ve asked me if the generated C# classes from /types/csharp can include a [Serializable] attribute, as apparently Azure Redis requires this for their purposes (I must stress this Redis instance is not used by the ServiceStack aspect, but their own independent web site which consumes our ServiceStack API).

I’ve taken a look at CSharpGenerator.cs and can see where that would be possible to do (lines 227 to 234).

Now, I know there are some perils involved in this, as in my tinkering I found any class inheriting from QueryDb that has the [Serializable] attribute will cause the XSD generation to throw an error because QueryDb does not - so some reflection would need to be done to omit that attribute from such classes that inherit from something without [Serializable]

My question is: Would you consider accepting a PR with a new option for the generated C# classes to include a list of definable attributes to adorn generated classes with?

I can see there are already some options for including [DataContract] and [Generated] attributes - but it looks like this was deliberately and carefully crafted to limit what attributes can be included - and not a generic “add whatever you like” approach like I propose - probably to keep things simple and clean.

Perhaps there is another way of a consumer of the API being able to add an attribute to the generated classes?



I don’t want to add [Serializable] since its unnecessary and not needed for any of our supported serializers.

But as the generated DTOs are partial by default, the easiest solution is to just have an separate .cs source file that includes the Serializable attribute for each DTO needed, e.g:

[Serializable] public partial class Dto1 {}
[Serializable] public partial class Dto2 {}

So they will still be able to freely update from your API without overriding the partial classes with the attributes.

You could also provide a different endpoint that dynamically generates this source file for them.

I’ve decided to add an extensibility hook for all Generated Types where you can generate custom source code at the start of each type in this commit. So you could use this to add a [Serializable] attribute to all C# DTOs with:

CSharpGenerator.PreTypeFilter = (sb, type) => 
    if (!type.IsEnum.GetValueOrDefault() && !type.IsInterface.GetValueOrDefault())

This change is available from v5.1.1 that’s now available on MyGet.

1 Like

That’s awesome! Thank you so much!