Dynamic Content Types
In general it's recommended to bake content types in to your codebase because it makes it much simpler for incoming developers to see what is available and use things like the events system with autocomplete to quickly link up what they need. However there is also some occasions where it would be useful to create a basic one via the admin panel at runtime. These are dynamic content types, and they are available via the Api/CustomContentTypes module:
socialstack i Api/CustomContentTypes
How it works
Content types created via this module are first class citizens: they have the exact same performance characteristics as ones built in to the codebase. This is because the module generates a controller, service and a C# class to represent your content type at runtime. It then runs it through the regular service startup flow which allows things like the permission system and database engine to mount the content type automatically and in the same way it would if it was built in.
Working with one from code
If you later need to add events to a dynamic content type, you have 2 options: either create the source of the module so it becomes built in to the code, or alternatively, you can use Services.Get to find the service:
// Get a weak reference to a service for a custom content type called "GalleryItem":
var galleryItemService = Services.Get("GalleryItem");
// Get the event group, which is what would be the equiv of Events.GalleryItem if it existed:
var eventGroup = galleryItemService.GetEventGroup();