Ejemplo n.º 1
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)));
        }
Ejemplo n.º 2
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);
        }