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++; } } }