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;
}
}