public void AddExtensionAssembly()

in sources/Google.Solutions.IapDesktop.Core/ObjectModel/ServiceRegistry.cs [408:480]


        public void AddExtensionAssembly(Assembly assembly)
        {
            //
            // NB. By default, services are registered in this service registry, making
            // them visible to this and lower layers.
            //
            // Services can optionally register as "global" to be registered in the
            // root registry. This makes them visible across all layers. Their dependencies
            // are still resolved in this layer -- not in the root layer.
            //

            //
            // (1) First, register all transients. 
            //
            foreach (var type in assembly.GetTypes())
            {
                if (type.GetCustomAttribute<ServiceAttribute>() is ServiceAttribute attribute &&
                    attribute.Lifetime == ServiceLifetime.Transient)
                {
                    AddTransient(
                        attribute.ServiceInterface ?? type,
                        type);
                }
            }

            //
            // (2) Register stubs, but do not create instances yet because they
            //     might depend on another and we don't know what the right order
            //     would have to be.
            //
            var singletonsToInstantiate = new LinkedList<SingletonStub>();
            foreach (var type in assembly.GetTypes())
            {
                if (type.GetCustomAttribute<ServiceAttribute>() is ServiceAttribute attribute &&
                    attribute.Lifetime == ServiceLifetime.Singleton)
                {
                    var stub = new SingletonStub(() => CreateInstance(type));
                    if (!attribute.DelayCreation)
                    {
                        singletonsToInstantiate.AddLast(stub);
                    }

                    AddSingleton(
                        attribute.ServiceInterface ?? type,
                        stub);
                }
            }

            //
            // (3) Register categories.
            //
            foreach (var type in assembly.GetTypes())
            {
                if (type.GetCustomAttribute<ServiceAttribute>() is ServiceAttribute attribute &&
                    type.GetCustomAttribute<ServiceCategoryAttribute>() is ServiceCategoryAttribute categoryAttribute)
                {
                    AddServiceToCategory(
                        categoryAttribute.Category,
                        attribute.ServiceInterface ?? type);
                }
            }

            //
            // (4) Instantiate singletons that require eager creation.
            //
            // At this point, we've registered all services and categories,
            // so it's ok if one singleton depends on another singleton.
            //
            foreach (var singleton in singletonsToInstantiate)
            {
                var _ = singleton.Object;
            }
        }