/// <summary> /// Implementation of <see cref="ITargetContainer.RegisterContainer(Type, ITargetContainer)" /> /// </summary> /// <param name="type"></param> /// <param name="container"></param> /// <remarks>This container implementation actually stores containers against the types that targets are registered /// against, rather than simply storing a dictionary of targets. This method allows you to add your own containers /// against type (instead of the default, which is <see cref="TargetListContainer"/>) so you can plug in some advanced /// behaviour into this container. /// /// For example, decorators are not actually <see cref="ITarget"/> implementations but specialised <see cref="ITargetContainer"/> /// instances into which the 'standard' targets are registered.</remarks> public virtual void RegisterContainer(Type type, ITargetContainer container) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (container == null) { throw new ArgumentNullException(nameof(container)); } this._targetContainers.TryGetValue(type, out ITargetContainer existing); // if there is already another container registered, we attempt to combine the two, prioritising // the new container over the old one but trying the reverse operation if that fails. if (existing != null) { // ask the 'new' one how it wishes to be combined with the other or, if that doesn't support // combining, then try the existing container and see if that can. // If neither can (NotSupportedException is expected here) then this // operation fails. try { this._targetContainers[type] = container.CombineWith(existing, type); } catch (NotSupportedException) { try { this._targetContainers[type] = existing.CombineWith(container, type); } catch (NotSupportedException) { throw new ArgumentException($"Cannot register the container because a container has already been registered for the type {type} and neither container supports the CombineWith operation"); } } } else // no existing container - simply add it in. { this._targetContainers[type] = container; } }