private void InspectLoadedAssemblies()
{
if (!_isInspectedTypes)
{
_isInspectedTypes = true;
try
{
var typeFactory = _serviceLocator.ResolveType<ITypeFactory>();
while (_pendingTypes.Count > 0)
{
var type = _pendingTypes.Dequeue();
ServiceLocatorRegistrationAttribute attribute;
if (AttributeHelper.TryGetAttribute(type, out attribute))
{
// CTL-780: support open generics
if (!type.IsGenericTypeEx() && (type.IsAbstractEx() || !attribute.InterfaceType.IsAssignableFromEx(type)))
{
var message = string.Format("The type '{0}' is abstract or can't be registered as '{1}'", type, attribute.InterfaceType);
if (!IgnoreRuntimeIncorrectUsageOfRegisterAttribute)
{
throw Log.ErrorAndCreateException<InvalidOperationException>(message);
}
Log.Warning(message);
}
else
{
switch (attribute.RegistrationMode)
{
case ServiceLocatorRegistrationMode.Transient:
case ServiceLocatorRegistrationMode.SingletonInstantiateWhenRequired:
_serviceLocator.RegisterTypeIfNotYetRegisteredWithTag(attribute.InterfaceType, type, attribute.Tag, attribute.RegistrationType);
break;
case ServiceLocatorRegistrationMode.SingletonInstantiateImmediately:
if (!_serviceLocator.IsTypeRegistered(attribute.InterfaceType))
{
var instance = typeFactory.CreateInstance(type);
if (instance == null)
{
Log.Error("Failed to instantiate type '{0}', cannot automatically register the instance", type.GetSafeFullName(false));
}
else
{
_serviceLocator.RegisterInstance(attribute.InterfaceType, instance, attribute.Tag);
}
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
}
catch (InvalidOperationException ex)
{
AutoRegisterTypesViaAttributes = false;
throw Log.ErrorAndCreateException<InvalidOperationException>(ex, "Failed to inspect the pending types");
}
finally
{
_isInspectedTypes = false;
}
}
}
#endregion