private void UnregisterKeys(List <FullKey> registeredKeys, IDependency dependency, ILifetime lifetime) { lock (_lockObject) { CheckIsNotDisposed(); foreach (var curKey in registeredKeys) { if (curKey.Tag == AnyTag) { TryUnregister(curKey.Type, ref _registrationsTagAny); } else { TryUnregister(curKey, ref _registrations); } } _eventSubject.OnNext(ContainerEvent.UnregisterDependency(this, registeredKeys, dependency, lifetime)); } }
/// <inheritdoc /> public void Dispose() { if (_isDisposed) { return; } try { // Notifies parent container about the child container disposing (_parent as Container)?._eventSubject.OnNext(ContainerEvent.DisposeContainer(this)); _parent.UnregisterResource(this); List <IDisposable> entriesToDispose; lock (_lockObject) { entriesToDispose = new List <IDisposable>(_registrations.Count + _registrationsTagAny.Count + _resources.Count); entriesToDispose.AddRange(_registrations.Select(i => i.Value)); entriesToDispose.AddRange(_registrationsTagAny.Select(i => i.Value)); entriesToDispose.AddRange(_resources); _registrations = Table <FullKey, Registration> .Empty; _registrationsTagAny = Table <ShortKey, Registration> .Empty; Reset(); _resources.Clear(); } // ReSharper disable once ForCanBeConvertedToForeach for (var index = 0; index < entriesToDispose.Count; index++) { entriesToDispose[index].Dispose(); } _eventSubject.OnCompleted(); } finally { _isDisposed = true; } }
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); }