Beispiel #1
0
        private IPolicySet SetOrUpdate(INamedType registration)
        {
            var collisions   = 0;
            var hashCode     = (registration.Type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
            var targetBucket = hashCode % _registrations.Buckets.Length;

            lock (_syncRoot)
            {
                for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                {
                    if (_registrations.Entries[i].HashCode != hashCode ||
                        _registrations.Entries[i].Key != registration.Type)
                    {
                        collisions++;
                        continue;
                    }

                    var existing = _registrations.Entries[i].Value;
                    if (existing.RequireToGrow)
                    {
                        existing = existing is HashRegistry <string, IPolicySet> registry
                                 ? new HashRegistry <string, IPolicySet>(registry)
                                 : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing);

                        _registrations.Entries[i].Value = existing;
                    }

                    return(existing.SetOrReplace(registration.Name, (IPolicySet)registration));
                }

                if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                {
                    _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_registrations);
                    targetBucket   = hashCode % _registrations.Buckets.Length;
                }

                _registrations.Entries[_registrations.Count].HashCode = hashCode;
                _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                _registrations.Entries[_registrations.Count].Key      = registration.Type;
                _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry {
                    [registration.Name] = (IPolicySet)registration
                };
                _registrations.Buckets[targetBucket] = _registrations.Count;
                _registrations.Count++;

                return(null);
            }
        }
        private IPolicySet GetOrAdd(Type type, string name)
        {
            var collisions   = 0;
            var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
            var targetBucket = hashCode % _policies.Buckets.Length;

            lock (_syncRoot)
            {
                for (var i = _policies.Buckets[targetBucket]; i >= 0; i = _policies.Entries[i].Next)
                {
                    if (_policies.Entries[i].HashCode != hashCode ||
                        _policies.Entries[i].Key != type)
                    {
                        collisions++;
                        continue;
                    }

                    var existing = _policies.Entries[i].Value;
                    if (existing.RequireToGrow)
                    {
                        existing = existing is HashRegistry <string, IPolicySet> registry
                                 ? new HashRegistry <string, IPolicySet>(registry)
                                 : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                         (LinkedRegistry)existing);

                        _policies.Entries[i].Value = existing;
                    }

                    return(existing.GetOrAdd(name, () => CreateRegistration(type, name)));
                }

                if (_policies.RequireToGrow || ListToHashCutoverPoint < collisions)
                {
                    _policies    = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_policies);
                    targetBucket = hashCode % _policies.Buckets.Length;
                }

                var registration = CreateRegistration(type, name);
                _policies.Entries[_policies.Count].HashCode = hashCode;
                _policies.Entries[_policies.Count].Next     = _policies.Buckets[targetBucket];
                _policies.Entries[_policies.Count].Key      = type;
                _policies.Entries[_policies.Count].Value    = new LinkedRegistry(name, registration);
                _policies.Buckets[targetBucket]             = _policies.Count;
                _policies.Count++;

                return(registration);
            }
        }
        /// <summary>
        /// Dispose this container instance.
        /// </summary>
        /// <remarks>
        /// This class doesn'type have a finalizer, so <paramref name="disposing"/> will always be true.</remarks>
        /// <param name="disposing">True if being called typeFrom the IDisposable.Dispose
        /// method, false if being called typeFrom a finalizer.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _parent?._lifetimeContainer?.Remove(this);
                _lifetimeContainer?.Dispose();

                foreach (IDisposable disposable in _extensions.OfType <IDisposable>().ToArray())
                {
                    disposable.Dispose();
                }

                _extensions.Clear();
                _policies = new HashRegistry <Type, IRegistry <string, IPolicySet> >(1);
            }
        }
        /// <summary>
        /// Dispose this container instance.
        /// </summary>
        /// <remarks>
        /// This class doesn'type have a finalizer, so <paramref name="disposing"/> will always be true.</remarks>
        /// <param name="disposing">True if being called typeFrom the IDisposable.Dispose
        /// method, false if being called typeFrom a finalizer.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                var exceptions = new List <Exception>();

                try
                {
                    _parent?._lifetimeContainer?.Remove(this);
                    _lifetimeContainer?.Dispose();
                }
                catch (Exception e)
                {
                    exceptions.Add(e);
                }

                foreach (IDisposable disposable in _extensions.OfType <IDisposable>().ToArray())
                {
                    try
                    {
                        disposable.Dispose();
                    }
                    catch (Exception e)
                    {
                        exceptions.Add(e);
                    }
                }

                _extensions.Clear();
                _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(1);

                if (exceptions.Count == 1)
                {
                    throw exceptions.First();
                }
                else if (exceptions.Count > 1)
                {
                    throw new AggregateException(exceptions);
                }
            }
        }
        /// <summary>
        /// Retrieves registration for requested named type
        /// </summary>
        /// <param name="type">Registration type</param>
        /// <param name="name">Registration name</param>
        /// <param name="create">Instruncts container if it should create registration if not found</param>
        /// <returns>Registration for requested named type or null if named type is not registered and
        /// <see cref="create"/> is false</returns>
        public INamedType Registration(Type type, string name, bool create = false)
        {
            for (var container = this; null != container; container = container._parent)
            {
                IPolicySet data;
                if (null == (data = container[type, name]))
                {
                    continue;
                }

                return((INamedType)data);
            }

            if (!create)
            {
                return(null);
            }

            var collisions   = 0;
            var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
            var targetBucket = hashCode % _registrations.Buckets.Length;

            lock (_syncRoot)
            {
                for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                {
                    if (_registrations.Entries[i].HashCode != hashCode ||
                        _registrations.Entries[i].Key != type)
                    {
                        collisions++;
                        continue;
                    }

                    var existing = _registrations.Entries[i].Value;
                    if (existing.RequireToGrow)
                    {
                        existing = existing is HashRegistry <string, IPolicySet> registry
                                 ? new HashRegistry <string, IPolicySet>(registry)
                                 : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                         (LinkedRegistry)existing);

                        _registrations.Entries[i].Value = existing;
                    }

                    return((INamedType)existing.GetOrAdd(name, () => CreateRegistration(type, name)));
                }

                if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                {
                    _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_registrations);
                    targetBucket   = hashCode % _registrations.Buckets.Length;
                }

                var registration = CreateRegistration(type, name);
                _registrations.Entries[_registrations.Count].HashCode = hashCode;
                _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                _registrations.Entries[_registrations.Count].Key      = type;
                _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry(name, registration);
                _registrations.Buckets[targetBucket] = _registrations.Count;
                _registrations.Count++;

                return((INamedType)registration);
            }
        }
        private IBuilderPolicy this[Type type, string name, Type interfaceType]
        {
            get
            {
                var        collisions   = 0;
                var        hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var        targetBucket = hashCode % _registrations.Buckets.Length;
                IPolicySet registration = null;
                lock (_syncRoot)
                {
                    for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                    {
                        if (_registrations.Entries[i].HashCode != hashCode ||
                            _registrations.Entries[i].Key != type)
                        {
                            collisions++;
                            continue;
                        }

                        var existing = _registrations.Entries[i].Value;
                        if (existing.RequireToGrow)
                        {
                            existing = existing is HashRegistry <string, IPolicySet> registry
                                     ? new HashRegistry <string, IPolicySet>(registry)
                                     : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                             (LinkedRegistry)existing);

                            _registrations.Entries[i].Value = existing;
                        }

                        registration = existing.GetOrAdd(name, () => CreateRegistration(type, name));
                        break;
                    }

                    if (null == registration)
                    {
                        if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                        {
                            _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_registrations);
                            targetBucket   = hashCode % _registrations.Buckets.Length;
                        }

                        registration = CreateRegistration(type, name);
                        _registrations.Entries[_registrations.Count].HashCode = hashCode;
                        _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                        _registrations.Entries[_registrations.Count].Key      = type;
                        _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry(name, registration);
                        _registrations.Buckets[targetBucket] = _registrations.Count;
                        _registrations.Count++;
                    }
                }

                return(registration.Get(interfaceType));
            }
            set
            {
                var collisions   = 0;
                var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var targetBucket = hashCode % _registrations.Buckets.Length;
                lock (_syncRoot)
                {
                    for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                    {
                        if (_registrations.Entries[i].HashCode != hashCode ||
                            _registrations.Entries[i].Key != type)
                        {
                            collisions++;
                            continue;
                        }

                        var existing = _registrations.Entries[i].Value;
                        if (existing.RequireToGrow)
                        {
                            existing = existing is HashRegistry <string, IPolicySet> registry
                                     ? new HashRegistry <string, IPolicySet>(registry)
                                     : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                             (LinkedRegistry)existing);

                            _registrations.Entries[i].Value = existing;
                        }

                        existing.GetOrAdd(name, () => CreateRegistration(type, name)).Set(interfaceType, value);
                        return;
                    }

                    if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                    {
                        _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_registrations);
                        targetBucket   = hashCode % _registrations.Buckets.Length;
                    }

                    var registration = CreateRegistration(type, name);
                    registration.Set(interfaceType, value);

                    _registrations.Entries[_registrations.Count].HashCode = hashCode;
                    _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                    _registrations.Entries[_registrations.Count].Key      = type;
                    _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry(name, registration);
                    _registrations.Buckets[targetBucket] = _registrations.Count;
                    _registrations.Count++;
                }
            }
        }
        private IPolicySet this[Type type, string name]
        {
            get
            {
                var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var targetBucket = hashCode % _registrations.Buckets.Length;
                for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                {
                    if (_registrations.Entries[i].HashCode != hashCode ||
                        _registrations.Entries[i].Key != type)
                    {
                        continue;
                    }

                    return(_registrations.Entries[i].Value?[name]);
                }

                return(null);
            }
            set
            {
                var hashCode     = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF;
                var targetBucket = hashCode % _registrations.Buckets.Length;
                var collisions   = 0;
                lock (_syncRoot)
                {
                    for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next)
                    {
                        if (_registrations.Entries[i].HashCode != hashCode ||
                            _registrations.Entries[i].Key != type)
                        {
                            collisions++;
                            continue;
                        }

                        var existing = _registrations.Entries[i].Value;
                        if (existing.RequireToGrow)
                        {
                            existing = existing is HashRegistry <string, IPolicySet> registry
                                ? new HashRegistry <string, IPolicySet>(registry)
                                : new HashRegistry <string, IPolicySet>(LinkedRegistry.ListToHashCutoverPoint * 2,
                                                                        (LinkedRegistry)existing);

                            _registrations.Entries[i].Value = existing;
                        }

                        existing[name] = value;
                        return;
                    }

                    if (_registrations.RequireToGrow || ListToHashCutoverPoint < collisions)
                    {
                        _registrations = new HashRegistry <Type, IRegistry <string, IPolicySet> >(_registrations);
                        targetBucket   = hashCode % _registrations.Buckets.Length;
                    }

                    _registrations.Entries[_registrations.Count].HashCode = hashCode;
                    _registrations.Entries[_registrations.Count].Next     = _registrations.Buckets[targetBucket];
                    _registrations.Entries[_registrations.Count].Key      = type;
                    _registrations.Entries[_registrations.Count].Value    = new LinkedRegistry(name, value);
                    _registrations.Buckets[targetBucket] = _registrations.Count;
                    _registrations.Count++;
                }
            }
        }