Example #1
0
        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));
            }
        }
Example #2
0
        /// <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;
            }
        }
Example #3
0
        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)));
        }
Example #4
0
        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);
        }