/// <summary> /// Stores the specified context in the cache. /// </summary> /// <param name="context">The context to store.</param> /// <param name="reference">The instance reference.</param> /// <exception cref="ArgumentNullException"><paramref name="context"/> is <see langword="null"/>.</exception> public void Remember(IContext context, InstanceReference reference) { Ensure.ArgumentNotNull(context, nameof(context)); var scope = context.GetScope(); var entry = new CacheEntry(context, reference); var weakScopeReference = new ReferenceEqualWeakReference(scope); var scopedEntries = this.entries.GetOrAdd( weakScopeReference, key => { if (scope is INotifyWhenDisposed notifyScope) { notifyScope.Disposed += (o, e) => this.Clear(key); } return(new ConcurrentDictionary <IBindingConfiguration, List <CacheEntry> >()); }); var cacheEntriesForBinding = scopedEntries.GetOrAdd(context.Binding.BindingConfiguration, new List <CacheEntry>()); lock (cacheEntriesForBinding) { cacheEntriesForBinding.Add(entry); } }
/// <summary> /// Stores the specified context in the cache. /// </summary> /// <param name="context">The context to store.</param> /// <param name="scope">The scope of the context.</param> /// <param name="reference">The instance reference.</param> /// <exception cref="ArgumentNullException"><paramref name="context"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="scope"/> is <see langword="null"/>.</exception> public void Remember(IContext context, object scope, InstanceReference reference) { Ensure.ArgumentNotNull(context, nameof(context)); Ensure.ArgumentNotNull(scope, nameof(scope)); var entry = new CacheEntry(context, reference); var weakScopeReference = new ReferenceEqualWeakReference(scope); var scopedEntries = this.entries.GetOrAdd( weakScopeReference, key => { // to reduce allocations, we use the argument of the delegate instead of // using the "scope" argument directly var scopeToAdd = ((ReferenceEqualWeakReference)key).Target; if (scopeToAdd is INotifyWhenDisposed notifyScope) { notifyScope.Disposed += (o, e) => this.Clear(scopeToAdd); } return(new ConcurrentDictionary <IBindingConfiguration, List <CacheEntry> >()); }); var cacheEntriesForBinding = scopedEntries.GetOrAdd(context.Binding.BindingConfiguration, new List <CacheEntry>()); lock (cacheEntriesForBinding) { cacheEntriesForBinding.Add(entry); } }
public void ReferencesIsEqualToTheInstanceItIsReferringTo() { var instance = new object(); var reference = new ReferenceEqualWeakReference(instance); reference.Equals(instance).Should().BeTrue(); reference.GetHashCode().Should().Be(instance.GetHashCode()); }
public void TwoReferencesReferencingTheSameObjectAreEqual() { var instance = new object(); var ref1 = new ReferenceEqualWeakReference(instance); var ref2 = new ReferenceEqualWeakReference(instance); ref1.Equals(ref2).Should().BeTrue(); ref1.GetHashCode().Should().Be(ref2.GetHashCode()); }
/// <summary> /// Stores the specified context in the cache. /// </summary> /// <param name="context">The context to store.</param> /// <param name="reference">The instance reference.</param> public void Remember(IContext context, InstanceReference reference) { var scope = context.GetScope(); var entry = new CacheEntry(context, reference); lock (this.entries) { var weakScopeReference = new ReferenceEqualWeakReference(scope); if (!this.entries.ContainsKey(weakScopeReference)) { this.entries[weakScopeReference] = new Multimap <IBindingConfiguration, CacheEntry>(); if (scope is INotifyWhenDisposed notifyScope) { notifyScope.Disposed += (o, e) => this.Clear(weakScopeReference); } } this.entries[weakScopeReference].Add(context.Binding.BindingConfiguration, entry); } }
/// <summary> /// Stores the specified context in the cache. /// </summary> /// <param name="context">The context to store.</param> /// <param name="reference">The instance reference.</param> public void Remember(IContext context, InstanceReference reference) { Ensure.ArgumentNotNull(context, "context"); var scope = context.GetScope(); var entry = new CacheEntry(context, reference); lock (this.entries) { var weakScopeReference = new ReferenceEqualWeakReference(scope); if (!this.entries.ContainsKey(weakScopeReference)) { this.entries[weakScopeReference] = new Multimap <IBinding, CacheEntry>(); var notifyScope = scope as INotifyWhenDisposed; if (notifyScope != null) { notifyScope.Disposed += (o, e) => this.Clear(weakScopeReference); } } this.entries[weakScopeReference].Add(context.Binding, entry); } }