Problem with this approach is the serialized object may become huge (eg with ModuleOptionsMetadata), unless we customize the serialization, but then it may not play well for other purposes.

What's the problem with using only the essence of what is needed for *this* usecase?

I see one benefit down below, which is that we get back a "true" MD when deserializing, but:
1) do we really? ie can we trust the deserialization today? tomorrow?
2) shouldn't we use something else instead of ModuleDefinition. Something like ModuleIdentifier that has type+name only?