/// <summary> /// Registers a specific instance of an service. /// </summary> /// <param name="serviceType">Type of the service.</param> /// <param name="instance">The specific instance to register.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <param name="originalContainer">The original container where the instance was found in.</param> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="instance"/> is <c>null</c>.</exception> internal void RegisterInstance(Type serviceType, object instance, object tag, object originalContainer) { Argument.IsNotNull("serviceType", serviceType); Argument.IsNotNull("instance", instance); Log.Debug("Registering type '{0}' to instance of type '{1}'", serviceType.FullName, instance.GetType().FullName); if (originalContainer == null) { originalContainer = this; } var registeredTypeInfo = new RegisteredTypeInfo(serviceType, instance.GetType(), tag, RegistrationType.Singleton, originalContainer); lock (_syncObject) { var serviceInfo = new ServiceInfo(serviceType, tag); _registeredInstances[serviceInfo] = new RegisteredInstanceInfo(serviceType, instance, RegistrationType.Singleton, tag, originalContainer); _registeredTypes[serviceInfo] = registeredTypeInfo; if (AutomaticallyKeepContainersSynchronized) { ExportToExternalContainers(); } } TypeRegistered.SafeInvoke(this, new TypeRegisteredEventArgs(registeredTypeInfo.DeclaringType, registeredTypeInfo.ImplementingType, tag, RegistrationType.Singleton)); Log.Debug("Registered type '{0}' to instance of type '{1}'", serviceType.FullName, instance.GetType().FullName); }
/// <summary> /// Determines whether the specified service type is registered. /// </summary> /// <param name="serviceType">The type of the service.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <returns><c>true</c> if the specified service type is registered; otherwise, <c>false</c>.</returns> /// <remarks>Note that the actual implementation lays in the hands of the IoC technique being used.</remarks> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> public bool IsTypeRegistered(Type serviceType, object tag = null) { Argument.IsNotNull("serviceType", serviceType); var serviceInfo = new ServiceInfo(serviceType, tag); lock (_syncObject) { if (_registeredInstances.ContainsKey(serviceInfo)) { return(true); } if (_registeredTypes.ContainsKey(serviceInfo)) { return(true); } foreach (var externalContainerKeyValuePair in _externalContainers) { var registrationInfo = externalContainerKeyValuePair.Value.GetRegistrationInfo(externalContainerKeyValuePair.Key, serviceType); if (registrationInfo != null) { // Now we know the container, register it as typeof(object), we will re-register as soon as the actual type is known _registeredTypes[serviceInfo] = new RegisteredTypeInfo(serviceType, typeof(object), tag, registrationInfo.RegistrationType, externalContainerKeyValuePair.Value); return(true); } } // Last resort var eventArgs = new MissingTypeEventArgs(serviceType); MissingType.SafeInvoke(this, eventArgs); if (eventArgs.ImplementingInstance != null) { Log.Debug("Late registering type '{0}' to instance of type '{1}' via MissingTypeEventArgs.ImplementingInstance", serviceType.FullName, eventArgs.ImplementingInstance.GetType().FullName); RegisterInstance(serviceType, eventArgs.ImplementingInstance, eventArgs.Tag, this); return(true); } if (eventArgs.ImplementingType != null) { Log.Debug("Late registering type '{0}' to type '{1}' via MissingTypeEventArgs.ImplementingType", serviceType.FullName, eventArgs.ImplementingType.FullName); RegisterType(serviceType, eventArgs.ImplementingType, eventArgs.Tag, eventArgs.RegistrationType, true, this); return(true); } } return(false); }
/// <summary> /// Registers the specific implementing type for the service type. /// </summary> /// <param name="serviceType">Type of the service.</param> /// <param name="serviceImplementationType">Type of the implementing.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <param name="registrationType">The registration type.</param> /// <param name="registerIfAlreadyRegistered">if set to <c>true</c>, an older type registration is overwritten by this new one.</param> /// <param name="originalContainer">The original container where the type was found in.</param> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="serviceImplementationType"/> is <c>null</c>.</exception> internal void RegisterType(Type serviceType, Type serviceImplementationType, object tag, RegistrationType registrationType, bool registerIfAlreadyRegistered, object originalContainer) { Argument.IsNotNull("serviceType", serviceType); Argument.IsNotNull("implementingType", serviceImplementationType); /* TODO: This code have to be here to ensure the right usage of non-generic overloads of register methods. * TODO: If it is finally accepted then remove it from ServiceLocatorAutoRegistrationManager * if (serviceImplementationType.IsAbstractEx() || !serviceType.IsAssignableFromEx(serviceImplementationType)) * { * string message = string.Format("The type '{0}' is abstract or can't be registered as '{1}'", serviceImplementationType, serviceType); * Log.Error(message); * throw new InvalidOperationException(message); * } */ // Outside lock scope for event RegisteredTypeInfo registeredTypeInfo = null; lock (_syncObject) { if (!registerIfAlreadyRegistered && IsTypeRegistered(serviceType, tag)) { //Log.Debug("Type '{0}' already registered, will not overwrite registration", serviceType.FullName); return; } var serviceInfo = new ServiceInfo(serviceType, tag); if (_registeredInstances.ContainsKey(serviceInfo)) { _registeredInstances.Remove(serviceInfo); } Log.Debug("Registering type '{0}' to type '{1}'", serviceType.FullName, serviceImplementationType.FullName); registeredTypeInfo = new RegisteredTypeInfo(serviceType, serviceImplementationType, tag, registrationType, originalContainer); _registeredTypes[serviceInfo] = registeredTypeInfo; if (AutomaticallyKeepContainersSynchronized) { ExportToExternalContainers(); } } TypeRegistered.SafeInvoke(this, new TypeRegisteredEventArgs(registeredTypeInfo.DeclaringType, registeredTypeInfo.ImplementingType, tag, registeredTypeInfo.RegistrationType)); Log.Debug("Registered type '{0}' to type '{1}'", serviceType.FullName, serviceImplementationType.FullName); }
/// <summary> /// Registers the specific implementing type for the service type. /// </summary> /// <param name="serviceType">Type of the service.</param> /// <param name="serviceImplementationType">Type of the implementing.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <param name="registrationType">The registration type.</param> /// <param name="registerIfAlreadyRegistered">if set to <c>true</c>, an older type registration is overwritten by this new one.</param> /// <param name="originalContainer">The original container where the type was found in.</param> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="serviceImplementationType"/> is <c>null</c>.</exception> internal void RegisterType(Type serviceType, Type serviceImplementationType, object tag, RegistrationType registrationType, bool registerIfAlreadyRegistered, object originalContainer) { Argument.IsNotNull("serviceType", serviceType); Argument.IsNotNull("implementingType", serviceImplementationType); /* TODO: This code have to be here to ensure the right usage of non-generic overloads of register methods. * TODO: If it is finally accepted then remove it from ServiceLocatorAutoRegistrationManager if (serviceImplementationType.IsAbstractEx() || !serviceType.IsAssignableFromEx(serviceImplementationType)) { string message = string.Format("The type '{0}' is abstract or can't be registered as '{1}'", serviceImplementationType, serviceType); Log.Error(message); throw new InvalidOperationException(message); } */ // Outside lock scope for event RegisteredTypeInfo registeredTypeInfo = null; lock (_syncObject) { if (!registerIfAlreadyRegistered && IsTypeRegistered(serviceType, tag)) { //Log.Debug("Type '{0}' already registered, will not overwrite registration", serviceType.FullName); return; } var serviceInfo = new ServiceInfo(serviceType, tag); if (_registeredInstances.ContainsKey(serviceInfo)) { _registeredInstances.Remove(serviceInfo); } Log.Debug("Registering type '{0}' to type '{1}'", serviceType.FullName, serviceImplementationType.FullName); registeredTypeInfo = new RegisteredTypeInfo(serviceType, serviceImplementationType, tag, registrationType, originalContainer); _registeredTypes[serviceInfo] = registeredTypeInfo; if (AutomaticallyKeepContainersSynchronized) { ExportToExternalContainers(); } } TypeRegistered.SafeInvoke(this, new TypeRegisteredEventArgs(registeredTypeInfo.DeclaringType, registeredTypeInfo.ImplementingType, tag, registeredTypeInfo.RegistrationType)); Log.Debug("Registered type '{0}' to type '{1}'", serviceType.FullName, serviceImplementationType.FullName); }
/// <summary> /// Registers a specific instance of an service. /// </summary> /// <param name="serviceType">Type of the service.</param> /// <param name="instance">The specific instance to register.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <param name="originalContainer">The original container where the instance was found in.</param> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="instance"/> is <c>null</c>.</exception> internal void RegisterInstance(Type serviceType, object instance, object tag, object originalContainer) { Argument.IsNotNull("serviceType", serviceType); Argument.IsNotNull("instance", instance); Log.Debug("Registering type '{0}' to instance of type '{1}'", serviceType.FullName, instance.GetType().FullName); if (originalContainer == null) { originalContainer = this; } var registeredTypeInfo = new RegisteredTypeInfo(serviceType, instance.GetType(), tag, RegistrationType.Singleton, originalContainer); lock (_syncObject) { var serviceInfo = new ServiceInfo(serviceType, tag); _registeredInstances[serviceInfo] = new RegisteredInstanceInfo(serviceType, instance, RegistrationType.Singleton, tag, originalContainer); _registeredTypes[serviceInfo] = registeredTypeInfo; if (AutomaticallyKeepContainersSynchronized) { ExportToExternalContainers(); } } TypeRegistered.SafeInvoke(this, new TypeRegisteredEventArgs(registeredTypeInfo.DeclaringType, registeredTypeInfo.ImplementingType, tag, RegistrationType.Singleton)); Log.Debug("Registered type '{0}' to instance of type '{1}'", serviceType.FullName, instance.GetType().FullName); }
/// <summary> /// Determines whether the specified service type is registered. /// </summary> /// <param name="serviceType">The type of the service.</param> /// <param name="tag">The tag to register the service with. The default value is <c>null</c>.</param> /// <returns><c>true</c> if the specified service type is registered; otherwise, <c>false</c>.</returns> /// <remarks>Note that the actual implementation lays in the hands of the IoC technique being used.</remarks> /// <exception cref="ArgumentNullException">The <paramref name="serviceType"/> is <c>null</c>.</exception> public bool IsTypeRegistered(Type serviceType, object tag = null) { Argument.IsNotNull("serviceType", serviceType); var serviceInfo = new ServiceInfo(serviceType, tag); lock (_syncObject) { if (_registeredInstances.ContainsKey(serviceInfo)) { return true; } if (_registeredTypes.ContainsKey(serviceInfo)) { return true; } foreach (var externalContainerKeyValuePair in _externalContainers) { var registrationInfo = externalContainerKeyValuePair.Value.GetRegistrationInfo(externalContainerKeyValuePair.Key, serviceType); if (registrationInfo != null) { // Now we know the container, register it as typeof(object), we will re-register as soon as the actual type is known _registeredTypes[serviceInfo] = new RegisteredTypeInfo(serviceType, typeof(object), tag, registrationInfo.RegistrationType, externalContainerKeyValuePair.Value); return true; } } // Last resort var eventArgs = new MissingTypeEventArgs(serviceType); MissingType.SafeInvoke(this, eventArgs); if (eventArgs.ImplementingInstance != null) { Log.Debug("Late registering type '{0}' to instance of type '{1}' via MissingTypeEventArgs.ImplementingInstance", serviceType.FullName, eventArgs.ImplementingInstance.GetType().FullName); RegisterInstance(serviceType, eventArgs.ImplementingInstance, eventArgs.Tag, this); return true; } if (eventArgs.ImplementingType != null) { Log.Debug("Late registering type '{0}' to type '{1}' via MissingTypeEventArgs.ImplementingType", serviceType.FullName, eventArgs.ImplementingType.FullName); RegisterType(serviceType, eventArgs.ImplementingType, eventArgs.Tag, eventArgs.RegistrationType, true, this); return true; } } return false; }