Exemplo n.º 1
0
        /// <summary>
        /// Возвращает гарантированно единственный экземпляр класса на уровне данного экземпляра ExtendedProperties и ключа, заданного в параметре propertyName,
        /// и создаваемый при первом обращении методом, переданным в параметре singletonConstructor.
        /// Данный метод не является потокобезопасным. Корректность работы метода гарантируется при однопоточном использовании.
        /// </summary>
        /// <param name="propertyName">Имя расширенного свойства, в котором хранится одиночный объект.</param>
        /// <param name="singletonConstructor">Метод, инициализирующий одиночный объект.</param>
        /// <param name="resetable">При переданном true, позволяет осуществить сброс singleton-свойства.</param>
        /// <returns></returns>
        public object GetSingleton(string propertyName, SingletonConstructor singletonConstructor, bool resetable)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentNullException("propertyName");
            }
            if (singletonConstructor == null)
            {
                throw new ArgumentNullException("singletonConstructor");
            }

            object singleton = null;

            //если свойство содержится в ExtendedProperties, возвращаем его
            //иначе - создаем и устанавливаем.
            if (this.ContainsProperty(propertyName))
            {
                //получаем объект-одиночку
                singleton = this.GetProperty(propertyName, null);

                //ругаемся, если он пустой
                if (singleton == null)
                {
                    throw new Exception(string.Format("Не задана ссылка на одиночный объект с названием {0}.", propertyName));
                }
            }
            else
            {
                //создаем объект одиночку, если он не задан.
                singleton = singletonConstructor(this.Holder);

                //ругаемся, если конструктор объекта вернул пустоту.
                if (singleton == null)
                {
                    throw new Exception(string.Format("Конструктор одиночного объекта с названием {0} вернул ссылку на пустой объект.", propertyName));
                }

                //устанавливаем объект-одиночку в коллекцию ExtendedProperteis.
                this.SetProperty(propertyName, singleton);
            }

            return(singleton);
        }
Exemplo n.º 2
0
        public void JobHostServiceProvider_SingletonAndScoped()
        {
            // Build JobHostServiceProvider
            var rootServices  = new ServiceCollection();
            var rootContainer = rootServices.BuildServiceProvider();
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();
            var jobHostServices = new ServiceCollection();

            jobHostServices.AddSingleton <SingletonConstructor>();
            jobHostServices.AddSingleton <SingletonFactory>(p => new SingletonFactory(p));

            jobHostServices.AddScoped <ScopedConstructor>();
            jobHostServices.AddScoped <ScopedFactory>(p => new ScopedFactory(p));

            IServiceProvider jobHostProvider = new JobHostServiceProvider(jobHostServices, rootContainer, rootScopeFactory);

            // Resolve some root services
            SingletonConstructor rootSingletonConstructor = jobHostProvider.GetService <SingletonConstructor>();
            SingletonFactory     rootSingletonFactory     = jobHostProvider.GetService <SingletonFactory>();
            ScopedConstructor    rootScopedConstructor    = jobHostProvider.GetService <ScopedConstructor>();
            ScopedFactory        rootScopedFactory        = jobHostProvider.GetService <ScopedFactory>();

            // Resolve some child scope services
            SingletonConstructor childSingletonConstructor1;
            SingletonFactory     childSingletonFactory1;
            ScopedConstructor    childScopedConstructor1;
            ScopedFactory        childScopedFactory1;

            using (var scope = jobHostProvider.CreateScope())
            {
                childSingletonConstructor1 = scope.ServiceProvider.GetService <SingletonConstructor>();
                childSingletonFactory1     = scope.ServiceProvider.GetService <SingletonFactory>();

                childScopedConstructor1 = scope.ServiceProvider.GetService <ScopedConstructor>();
                childScopedFactory1     = scope.ServiceProvider.GetService <ScopedFactory>();
            }

            // Do it again
            SingletonConstructor childSingletonConstructor2;
            SingletonFactory     childSingletonFactory2;
            ScopedConstructor    childScopedConstructor2;
            ScopedFactory        childScopedFactory2;

            using (var scope = jobHostProvider.CreateScope())
            {
                childSingletonConstructor2 = scope.ServiceProvider.GetService <SingletonConstructor>();
                childSingletonFactory2     = scope.ServiceProvider.GetService <SingletonFactory>();

                childScopedConstructor2 = scope.ServiceProvider.GetService <ScopedConstructor>();
                childScopedFactory2     = scope.ServiceProvider.GetService <ScopedFactory>();
            }

            // Ensure all ServiceProviders for Singletons are the same.
            Assert.Same(rootSingletonConstructor.ServiceProvider, childSingletonConstructor1.ServiceProvider);
            Assert.Same(childSingletonConstructor1.ServiceProvider, rootSingletonFactory.ServiceProvider);
            Assert.Same(rootSingletonFactory.ServiceProvider, childSingletonFactory1.ServiceProvider);

            // The root ServiceProviders for Scoped should also be the same.
            Assert.Same(childSingletonFactory1.ServiceProvider, rootScopedConstructor.ServiceProvider);
            Assert.Same(rootScopedConstructor.ServiceProvider, rootScopedFactory.ServiceProvider);

            // Root and child should not match for Scoped
            Assert.NotSame(rootScopedConstructor.ServiceProvider, childScopedConstructor1.ServiceProvider);
            Assert.NotSame(rootScopedFactory.ServiceProvider, childScopedFactory1.ServiceProvider);

            // Both Scopes should match
            Assert.Same(childScopedConstructor1.ServiceProvider, childScopedFactory1.ServiceProvider);
            Assert.Same(childScopedConstructor2.ServiceProvider, childScopedFactory2.ServiceProvider);

            // But not between scopes
            Assert.NotSame(childScopedConstructor1.ServiceProvider, childScopedConstructor2.ServiceProvider);
            Assert.NotSame(childScopedFactory1.ServiceProvider, childScopedFactory2.ServiceProvider);

            // Roots and Singletons are not disposed
            rootSingletonConstructor.DoSomething();
            rootSingletonFactory.DoSomething();
            rootScopedConstructor.DoSomething();
            rootScopedFactory.DoSomething();
            childSingletonConstructor1.DoSomething();
            childSingletonFactory1.DoSomething();
            childSingletonConstructor2.DoSomething();
            childSingletonFactory2.DoSomething();

            // Child scopes are disposed.
            Assert.Throws <ContainerException>(() => childScopedConstructor1.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedFactory1.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedConstructor2.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedFactory2.DoSomething());
        }
Exemplo n.º 3
0
 /// <summary>
 /// Возвращает гарантированно единственный экземпляр класса на уровне данного экземпляра ExtendedProperties и ключа, заданного в параметре propertyName,
 /// и создаваемый при первом обращении методом, переданным в параметре singletonConstructor.
 /// Данный метод не является потокобезопасным. Корректность работы метода гарантируется при однопоточном использовании.
 /// </summary>
 /// <typeparam name="T">Тип объекта-одиночки.</typeparam>
 /// <param name="propertyName">Имя расширенного свойства, в котором хранится одиночный объект.</param>
 /// <param name="singletonConstructor">Метод, инициализирующий одиночный объект.</param>
 /// <param name="resetable">При переданном true, позволяет осуществить сброс singleton-свойства.</param>
 /// <returns></returns>
 public T GetSingleton <T>(string propertyName, SingletonConstructor singletonConstructor, bool resetable)
 {
     return((T)this.GetSingleton(propertyName, singletonConstructor, resetable));
 }
Exemplo n.º 4
0
 /// <summary>
 /// Возвращает гарантированно единственный экземпляр класса на уровне данного экземпляра ExtendedProperties и ключа, заданного в параметре propertyName,
 /// и создаваемый при первом обращении методом, переданным в параметре singletonConstructor.
 /// Данный метод не является потокобезопасным. Корректность работы метода гарантируется при однопоточном использовании.
 /// </summary>
 /// <typeparam name="T">Тип объекта-одиночки.</typeparam>
 /// <param name="propertyName">Имя расширенного свойства, в котором хранится одиночный объект.</param>
 /// <param name="singletonConstructor">Метод, инициализирующий одиночный объект.</param>
 /// <returns></returns>
 public T GetSingleton <T>(string propertyName, SingletonConstructor singletonConstructor)
 {
     return((T)this.GetSingleton(propertyName, singletonConstructor));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Возвращает гарантированно единственный экземпляр класса на уровне данного экземпляра ExtendedProperties и ключа, заданного в параметре propertyName,
 /// и создаваемый при первом обращении методом, переданным в параметре singletonConstructor.
 /// Данный метод не является потокобезопасным. Корректность работы метода гарантируется при однопоточном использовании.
 /// </summary>
 /// <param name="propertyName">Имя расширенного свойства, в котором хранится одиночный объект.</param>
 /// <param name="singletonConstructor">Метод, инициализирующий одиночный объект.</param>
 /// <returns></returns>
 public object GetSingleton(string propertyName, SingletonConstructor singletonConstructor)
 {
     return(this.GetSingleton(propertyName, singletonConstructor, false));
 }