internal Container([NotNull] string name, [NotNull] IContainer parent, [NotNull] ILockObject lockObject) { _lockObject = lockObject ?? throw new ArgumentNullException(nameof(parent)); _name = $"{parent}/{name ?? throw new ArgumentNullException(nameof(name))}"; _parent = parent ?? throw new ArgumentNullException(nameof(parent)); _eventSubject = new Subject <ContainerEvent>(_lockObject); _registrationTracker = new RegistrationTracker(this); // Subscribe to events from the parent container RegisterResource(_parent.Subscribe(_eventSubject)); // Creates a subscription to track infrastructure registrations RegisterResource(_eventSubject.Subscribe(_registrationTracker)); // Register the current container in the parent container _parent.RegisterResource(this); // Notifies parent container about the child container creation (_parent as Container)?._eventSubject.OnNext(ContainerEvent.NewContainer(this)); // Notifies about existing registrations in parent containers _eventSubject.OnNext(ContainerEvent.RegisterDependency(_parent, _parent.SelectMany(i => i))); }
public bool TryRegisterDependency(IEnumerable <FullKey> keys, IDependency dependency, ILifetime lifetime, out IToken dependencyToken) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (dependency == null) { throw new ArgumentNullException(nameof(dependency)); } var isRegistered = true; lock (_lockObject) { CheckIsNotDisposed(); var registeredKeys = new List <FullKey>(); var dependencyEntry = new Registration(this, _eventSubject, dependency, lifetime, Disposable.Create(() => UnregisterKeys(registeredKeys, dependency, lifetime)), registeredKeys); try { var dependenciesForTagAny = _registrationsTagAny; var dependencies = _registrations; foreach (var curKey in keys) { var type = curKey.Type.ToGenericType(); var key = type != curKey.Type ? new FullKey(type, curKey.Tag) : curKey; if (key.Tag == AnyTag) { isRegistered &= !dependenciesForTagAny.TryGetByType(key.Type, out _); if (isRegistered) { dependenciesForTagAny = dependenciesForTagAny.Set(key.Type, dependencyEntry); } } else { isRegistered &= !dependencies.TryGetByKey(key, out _); if (isRegistered) { dependencies = dependencies.Set(key, dependencyEntry); } } if (!isRegistered) { break; } registeredKeys.Add(key); } if (isRegistered) { _registrationsTagAny = dependenciesForTagAny; _registrations = dependencies; _eventSubject.OnNext(ContainerEvent.RegisterDependency(this, registeredKeys, dependency, lifetime)); } } catch (Exception error) { _eventSubject.OnNext(ContainerEvent.RegisterDependencyFailed(this, registeredKeys, dependency, lifetime, error)); isRegistered = false; throw; } finally { if (isRegistered) { dependencyToken = dependencyEntry; } else { dependencyEntry.Dispose(); dependencyToken = default(IToken); } } } return(isRegistered); }