public IDisposable ServiceRegistrationCallback(Type serviceType, string contract, Action <IDisposable> callback)
        {
            var pair = Tuple.Create(serviceType, contract ?? string.Empty);

            if (!_callbackRegistry.ContainsKey(pair))
            {
                _callbackRegistry[pair] = new List <Action <IDisposable> >();
            }

            _callbackRegistry[pair].Add(callback);

            var disp = new ActionDisposable(() => {
                _callbackRegistry[pair].Remove(callback);
            });

            if (_registry.ContainsKey(pair))
            {
                foreach (var s in _registry[pair])
                {
                    callback(disp);
                }
            }

            return(disp);
        }
        public void Register(Func <object> factory, Type serviceType, string contract = null)
        {
            var pair = Tuple.Create(serviceType, contract ?? string.Empty);

            if (!_registry.ContainsKey(pair))
            {
                _registry[pair] = new List <Func <object> >();
            }

            _registry[pair].Add(factory);

            if (_callbackRegistry.ContainsKey(pair))
            {
                List <Action <IDisposable> > toRemove = null;

                foreach (var callback in _callbackRegistry[pair])
                {
                    var remove = false;
                    var disp   = new ActionDisposable(() => {
                        remove = true;
                    });

                    callback(disp);

                    if (remove)
                    {
                        if (toRemove == null)
                        {
                            toRemove = new List <Action <IDisposable> >();
                        }

                        toRemove.Add(callback);
                    }
                }

                if (toRemove != null)
                {
                    foreach (var c in toRemove)
                    {
                        _callbackRegistry[pair].Remove(c);
                    }
                }
            }
        }