public IDisposable GetOrAdd <TScope, TService>( TScope scope, out TService service, out bool wasAdded, Func <TScope, TService> serviceFactory) { lock (registrations) { if (TryGet(scope, out service)) { wasAdded = false; return(DelegateDisposable.NoOp()); } service = serviceFactory(scope); if (service == null) { throw new ArgumentException( $"{nameof(service)} result is null for {typeof(TService).GetFriendlyFullName()}" + $" --- for scope '{scope}'.", nameof(serviceFactory)); } if (!registrations.TryGetValue(typeof(TScope), out Dictionary <object, object> scopes)) { scopes = new Dictionary <object, object>(8); registrations[typeof(TScope)] = scopes; } else { Debug.Assert(!scopes.ContainsKey(scope), "!scopes.ContainsKey(scope)"); } scopes[scope] = service; wasAdded = true; return(DelegateDisposable.With(scope, s => Remove(typeof(TScope), s))); } }