Fluent builders are nicer to work with than attributes, although it sometimes feels weird if the defaults are nearly fine but not quite, and you wish you could just reach for a single attribute rather than having to traverse down 3 layers of builders to change a single property.
1. Create an abstract base class named MigrationBaseClass 2. Have all migrations classes inherit from MigrationBaseClass 3. Use .Net Reflection to get all types that inherit from MigrationBaseClass 4. Do something with these types.
(ETA: Though my favorite pattern here became using DI for this instead of reflection. For every IMigration have a `services.AddTransient<IMigration, SomeMigrationImplementationClass>()` somewhere and then your service to run all migrations can just request from DI `IEnumerable<IMigration>`. I can then put the Reflection into a unit test to make sure everything that implements IMigration is registered in the DI container. But using DI in the main assembly to register all the migrations rather than Reflection leaves more room to try to AOT compile the assembly in production builds.)