More granular control on InitializedCollections?

Wonder how I might gain more granular control over the generation of initialized collections. I have explicit AutoQuery QueryBase DTOs in which the arrays/lists should not be initialized as they will change the query itself.

From what I see so far only the InitializeCollections flag exists to toggle this behavior. I was hoping for the ability to attribute [SuppressInitializeCollections] on DTOs in which I am certain the consumer should not initialize automatically, overriding the global flag.

I just started mixing AutoQuery into one of my new projects and ran into this issue and my UI guy is having to manually remove the constructor just for the AutoQuery type, as for all the other DTOs we do wish to have collections initialized.

I really don’t want to add a new custom attribute negating every global configuration available. You can use Add ServiceStack Reference twice, once that uses ExcludeTypes and InitializeCollections=true and the other that IncludeTypes and InitializeCollections=false so you get custom DTO’s generated with different configurations.

Is it just for AutoQuery DTO’s you want to disable this with? As a better solution might be to ignore empty collections in AutoQueries as I’m not sure if there is a valid use-case to query an empty collection?

That makes sense, but this requires my UI guy to have to pay attention when generating types for his project.

So far this is the only use-case we have found a need to do this for. It would be nice if it suppressed it at the code-gen, because even if you suppressed at AutoQuery, all those empty collections would still be sent over the wire because they are not null, which seems overly chatty.

They should only have to do this once, since you should be able to keep updating the same generated file where it keeps the preferences.

But this is what the InitializeCollections=false is supposed to control, disabling it leaves them uninitialized.

My UI layer consumers are lazy, and making noise about the fact they are having to go thru such a “work around” process. I also see that this might be a friction point if I expose similar APIs to our external customers. I’d prefer to just clean it up server-side and have it “just work”.

As it stands now, any time I decide to implement my read functionality via AutoQuery I am going to force my consumer to know they need to preform this work around in order to get a properly working DTO signature for QueryBase objects.

I still don’t see what’s wrong with setting InitializeCollections=false?

You can change this default on the Server:

var nativeTypes = this.GetPlugin<NativeTypesFeature>();
nativeTypes.MetadataTypesConfig.InitializeCollections = false;

If the payload is an issue, then you can disable it.

So our ultimate solution was the leave the default initialization of collections, because all other DTOs required this.

On the client-side we already us a standard PostXYZAPI(this T dto) extension pattern to call external services, so that method now first checks if the dto is QueryBase then we null any empty List<T> collections before sending the request.
This resulted is much less friction then having to maintain 2 sets of DTO templates and manually adjusting which types needed initialization or not.

Sounds like you want to maintain different behavior for just AutoQuery DTO’s so I’ve added this as a server-side config option in this commit where you can disable initializing collections for AutoQuery base types in your AppHost.Configure() with:

this.GetPlugin<NativeTypesFeature>().InitializeCollectionsForType = 

The InitializeCollectionsForType is just a Func<MetadataType, bool?> predicate so you can customize it on a per type basis where returning null will default to the specified InitializeCollections behavior.

I’m still considering whether or not I should have this enabled by default as AutoQuery DTO’s by nature are likely to have a lot of unused collection properties on the other hand I’d prefer not to have nuanced behavior just for AutoQuery services and I don’t want to break existing code relying on a initialized collection so I’ll hold off from enabling it by default until I see more reported issues / requests for this feature.

Anyway this option is available from v4.0.55 that’s now available on MyGet.

Great! I think this is a pretty good comprise for now, it at least gives me a clean way to export my types without notifying my consumers which types needed special treatment.