DotNetStarter - Assembly Scanning

Assembly scanning occurs to discover service registrations (RegistrationAttribute) and IStartupModule/ILocatorConfigure modules, but can also be extended with the DiscoverTypesAttribute for assemblies.

Below is the default for DotNetStarter to discover its needed types:

 using DotNetStarter.Abstractions;

 // this scans for types that implement IStartupModule, StartupModuleAttribute, and RegistrationAttribute usages
[assembly: DiscoverTypes(
    typeof(IStartupModule),
    typeof(StartupModuleAttribute),
    typeof(RegistrationAttribute)
)]

The default assembly scanner stores these in a dictionary for retrieval noted below:

 using DotNetStarter.Abstractions;

[StartupModule]
public class RegistrationConfiguration : ILocatorConfigure
{
    private static readonly Type RegistrationType = typeof(RegistrationAttribute);

    void ILocatorConfigure.Configure(ILocatorRegistry registry, ILocatorConfigureEngine args)
    {
        var scannedRegistrations = args.Configuration.AssemblyScanner.GetTypesFor(RegistrationType);
        var registrations = args.Configuration.DependencySorter
            .Sort<RegistrationAttribute>(scannedRegistrations.OfType<object>())
            .SelectMany(ConvertNodeToRegistration)
            .ToList();

        args.Configuration.RegistrationsModifier?.Modify(registrations);
        registrations.All(r => AddRegistration(r, registry));

        args.Configuration.Environment.Items.Set<ICollection<Registration>>(registrations);
    }

    private bool AddRegistration(Registration registration, ILocatorRegistry registry)
    {
        registry.Add
        (
            registration.ServiceType, // service
            registration.ImplementationType, // implementation
            lifecycle: registration.Lifecycle
        );

        return true;
    }

    private IEnumerable<Registration> ConvertNodeToRegistration(IDependencyNode node)
    {
        var implementationType = node.Node as Type;
        var attrs = implementationType.CustomAttribute(RegistrationType, false).OfType<RegistrationAttribute>();

        return attrs.Select(r => new Registration(r, implementationType));
    }
}