예제 #1
0
        /// <summary>
        ///     Отменяет регистрацию компонента
        /// </summary>
        /// <param name="component"> компонент, который должен быть убран из контейнера </param>
        /// <remarks>
        ///     <note>Очевидно что, такой метод обязан присутствовать в интерфейсе контейнера, однако его использование в задачах помимо тестирования,
        ///         обозначает недостатки архитектуры приложения, так как в нормальном варианте использования контейнер меняет свое поведение по принципу наращивания
        ///         обслуживаемых классов и компонентов, тогда как удаление части компонент может привести к неожиданным эффектам в случае кэширования более
        ///         ранеей выдвачи клиентской стороной</note>
        /// </remarks>
        public void Unregister(IComponentDefinition component)
        {
            lock (this) {
                if (null == component)
                {
                    return;
                }
                if (!Components.Contains(component))
                {
                    return;
                }
                Components.Remove(component);
                ByTypeCache[component.ServiceType].Remove(component);
                if (component.Name.IsNotEmpty())
                {
                    ByNameCache[component.Name].Remove(component);
                }
                foreach (var componentDefinition in OutgoingCache.ToArray())
                {
                    if (Equals(componentDefinition.Value, component))
                    {
                        DropObject(componentDefinition.Key);
                        OutgoingCache.Remove(componentDefinition.Key);
                    }
                }
                if (Lifestyle.PerThread == component.Lifestyle)
                {
                    foreach (var threadCache in ThreadOutgoingCache.ToArray())
                    {
                        foreach (var componentDefinition in threadCache.Value.ToArray())
                        {
                            if (Equals(componentDefinition.Value, component))
                            {
                                DropObject(componentDefinition.Key);
                                OutgoingCache.Remove(componentDefinition.Key);
                            }
                        }
                    }
                }
                if (Lifestyle.Pooled == component.Lifestyle)
                {
                    if (Pool.ContainsKey(component))
                    {
                        foreach (var obj in Pool[component])
                        {
                            DropObject(obj);
                        }
                        Pool.Remove(component);
                    }
                }

                // hook for extensions - UnRegisterComponent extensions can do something after it's
                // native unregistration
                ProcessExtensions(new ContainerContext {
                    Operation = ContainerOperation.UnregisterComponent, Component = component
                });
            }
        }
예제 #2
0
        /// <summary>
        ///     Возвращает объект контейнеру
        /// </summary>
        /// <param name="obj"> Объект, ранее созданнй контейнером </param>
        /// <remarks>
        ///     <invariant>Метод позволяет контейнеру высвобождать собственные ресурсы и вызывает
        ///         <see cref="IContainerBound.OnContainerRelease" />
        ///         метод,
        ///         работает это только для
        ///         <see cref="Lifestyle.Pooled" />
        ///         и
        ///         <see cref="Lifestyle.PerThread" />
        ///         , для остальных данный метод игнорируется</invariant>
        /// </remarks>
        public void Release(object obj)
        {
            lock (this) {
                if (!OutgoingCache.ContainsKey(obj))
                {
                    return;
                }
                var component = OutgoingCache[obj];
                switch (component.Lifestyle)
                {
                case Lifestyle.Extension:                         //extensions not must be released
                    goto case Lifestyle.Transient;

                case Lifestyle.Default:                         // default is transient
                    goto case Lifestyle.Transient;

                case Lifestyle.Transient:                         //transient not have to be released
                    return;

                case Lifestyle.Pooled:
                    // pool ion release not disposed, but moved to pool
                    if (!Pool.ContainsKey(component))
                    {
                        Pool[component] = new Stack <object>();
                    }
                    Pool[component].Push(obj);
                    break;

                case Lifestyle.PerThread:
                    //per thread removed from thread cache and OnContainerRelease called
                    //and it can be released only in calling thread
                    if (!ThreadOutgoingCache.ContainsKey(Thread.CurrentThread))
                    {
                        throw new ContainerException("try to realease thread object from not configured thread");
                    }
                    if (!ThreadOutgoingCache[Thread.CurrentThread].ContainsKey(obj))
                    {
                        throw new ContainerException("try to release thread object on not it's thread");
                    }
                    ThreadOutgoingCache[Thread.CurrentThread].Remove(obj);
                    DropObject(obj);
                    break;

                case Lifestyle.Singleton:
                    //singletons cannot be released - they will still alive
                    return;
                }
                OutgoingCache.Remove(obj);
            }
        }