From 4aca1829b26dc7425ad5b2e280486f6e643c07e3 Mon Sep 17 00:00:00 2001 From: maca88 Date: Thu, 12 Jul 2018 20:06:15 +0200 Subject: [PATCH 01/16] Replace IObjectsFactory with IServiceProvider interface --- .../Async/CfgTest/SettingsFactoryFixture.cs | 82 ++++++++++++ .../Bytecode/ActivatorObjectFactoryFixture.cs | 79 ----------- .../Bytecode/DefaultServiceProviderFixture.cs | 75 +++++++++++ .../CfgTest/ConfigurationSchemaFixture.cs | 8 +- .../CfgTest/CustomObjectsFactoryTest.cs | 66 --------- .../CfgTest/CustomServiceProviderTest.cs | 56 ++++++++ .../CfgTest/SettingsFactoryFixture.cs | 125 +++++++++++++++++- .../NHSpecificTest/GH1547/Fixture.cs | 2 +- .../TypesTest/AbstractDateTimeTypeFixture.cs | 2 +- .../UtilityTest/PropertiesHelperTest.cs | 85 ++++++++++++ .../Async/Tool/hbm2ddl/SchemaUpdate.cs | 2 +- .../Async/Tool/hbm2ddl/SchemaValidator.cs | 2 +- .../Async/Type/CompositeCustomType.cs | 1 + .../Async/Type/CustomCollectionType.cs | 3 +- .../Bytecode/AbstractBytecodeProvider.cs | 11 +- .../Bytecode/ActivatorObjectsFactory.cs | 11 +- .../Bytecode/DefaultServiceProvider.cs | 119 +++++++++++++++++ .../HibernateObjectsFactoryException.cs | 18 --- .../HibernateServiceProviderException.cs | 18 +++ src/NHibernate/Bytecode/IBytecodeProvider.cs | 4 +- src/NHibernate/Bytecode/IObjectsFactory.cs | 6 +- src/NHibernate/Cfg/Configuration.cs | 2 +- .../Cfg/ConfigurationSchema/CfgXmlHelper.cs | 4 +- .../HibernateConfiguration.cs | 12 +- src/NHibernate/Cfg/Environment.cs | 50 +++---- src/NHibernate/Cfg/SettingsFactory.cs | 125 +++++++++--------- .../AuxiliaryDatabaseObjectFactory.cs | 2 +- .../Connection/ConnectionProvider.cs | 32 +++-- .../Connection/ConnectionProviderFactory.cs | 21 ++- .../Context/ICurrentSessionContext.cs | 3 +- src/NHibernate/Dialect/Dialect.cs | 19 ++- ...eflectionDriveConnectionCommandProvider.cs | 7 +- .../SQLExceptionConverterFactory.cs | 16 ++- .../Id/IdentifierGeneratorFactory.cs | 2 +- src/NHibernate/Impl/SessionFactoryImpl.cs | 9 +- .../LinqToHqlGeneratorsRegistryFactory.cs | 17 ++- src/NHibernate/Mapping/Collection.cs | 2 +- .../Properties/PropertyAccessorFactory.cs | 2 +- src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs | 2 +- .../Tool/hbm2ddl/SchemaValidator.cs | 2 +- src/NHibernate/Type/CompositeCustomType.cs | 3 +- src/NHibernate/Type/CustomCollectionType.cs | 5 +- src/NHibernate/Type/CustomType.cs | 2 +- src/NHibernate/Type/TypeFactory.cs | 2 +- src/NHibernate/Util/PropertiesHelper.cs | 33 +++++ .../Util/ServiceProviderExtensions.cs | 17 +++ src/NHibernate/nhibernate-configuration.xsd | 8 +- 47 files changed, 833 insertions(+), 341 deletions(-) create mode 100644 src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs delete mode 100644 src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs create mode 100644 src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs delete mode 100644 src/NHibernate.Test/CfgTest/CustomObjectsFactoryTest.cs create mode 100644 src/NHibernate.Test/CfgTest/CustomServiceProviderTest.cs create mode 100644 src/NHibernate/Bytecode/DefaultServiceProvider.cs delete mode 100644 src/NHibernate/Bytecode/HibernateObjectsFactoryException.cs create mode 100644 src/NHibernate/Bytecode/HibernateServiceProviderException.cs create mode 100644 src/NHibernate/Util/ServiceProviderExtensions.cs diff --git a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs new file mode 100644 index 00000000000..7a16087d09c --- /dev/null +++ b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using NHibernate.AdoNet; +using NHibernate.Bytecode; +using NHibernate.Cache; +using NHibernate.Cfg; +using NHibernate.Connection; +using NHibernate.Exceptions; +using NHibernate.Hql; +using NHibernate.Hql.Ast.ANTLR; +using NHibernate.Linq.Functions; +using NHibernate.Linq.Visitors; +using NHibernate.Transaction; +using NSubstitute; +using NUnit.Framework; +using Environment = NHibernate.Cfg.Environment; + +namespace NHibernate.Test.CfgTest +{ + using System.Threading.Tasks; + [TestFixture] + public class SettingsFactoryFixtureAsync + { + + [Test] + public async Task InvalidRegisteredServicesAsync() + { + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + await (InvalidRegisteredServiceAsync()); + } + + private Task InvalidRegisteredServiceAsync() + { + try + { + var originalSp = Environment.ServiceProvider; + + var sp = new DefaultServiceProvider(); + sp.Register(() => throw new InvalidOperationException()); + + Environment.ServiceProvider = sp; + + var properties = new Dictionary + { + {Environment.UseQueryCache, "true"} + }; + if (typeof(TService) != typeof(Dialect.Dialect)) + { + properties.Add(Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName); + } + + Assert.Throws( + () => new SettingsFactory().BuildSettings(properties), + $"HibernateException should be thrown for service {typeof(TService)}"); + + Environment.ServiceProvider = originalSp; + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + } +} diff --git a/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs b/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs deleted file mode 100644 index daba1084d9a..00000000000 --- a/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using NHibernate.Bytecode; -using NUnit.Framework; - -namespace NHibernate.Test.Bytecode -{ - [TestFixture] - public class ActivatorObjectFactoryFixture - { - public class WithOutPublicParameterLessCtor - { - public string Something { get; set; } - protected WithOutPublicParameterLessCtor() { } - - public WithOutPublicParameterLessCtor(string something) - { - Something = something; - } - } - - public class PublicParameterLessCtor - { - } - - public struct ValueType - { - public string Something { get; set; } - } - - protected virtual IObjectsFactory GetObjectsFactory() - { - return new ActivatorObjectsFactory(); - } - - [Test] - public void CreateInstanceDefCtor() - { - IObjectsFactory of = GetObjectsFactory(); - Assert.Throws(() => of.CreateInstance(null)); - Assert.Throws(() => of.CreateInstance(typeof(WithOutPublicParameterLessCtor))); - var instance = of.CreateInstance(typeof(PublicParameterLessCtor)); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - } - - - - [Test, Obsolete] - public void CreateInstanceWithNoPublicCtor() - { - IObjectsFactory of = GetObjectsFactory(); - Assert.Throws(() => of.CreateInstance(null, false)); - var instance = of.CreateInstance(typeof(WithOutPublicParameterLessCtor), true); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - } - - [Test, Obsolete] - public void CreateInstanceOfValueType() - { - IObjectsFactory of = GetObjectsFactory(); - var instance = of.CreateInstance(typeof(ValueType), true); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - } - - [Test, Obsolete] - public void CreateInstanceWithArguments() - { - IObjectsFactory of = GetObjectsFactory(); - Assert.Throws(() => of.CreateInstance(null, new[] {1})); - var value = "a value"; - var instance = of.CreateInstance(typeof(WithOutPublicParameterLessCtor), new[]{value}); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - Assert.That(((WithOutPublicParameterLessCtor)instance).Something, Is.EqualTo(value)); - } - } -} diff --git a/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs b/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs new file mode 100644 index 00000000000..0472d6cbed5 --- /dev/null +++ b/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs @@ -0,0 +1,75 @@ +using System; +using NHibernate.Bytecode; +using NUnit.Framework; + +namespace NHibernate.Test.Bytecode +{ + [TestFixture] + public class DefaultServiceProviderFixture + { + public class WithOutPublicParameterLessCtor + { + public string Something { get; set; } + protected WithOutPublicParameterLessCtor() { } + + public WithOutPublicParameterLessCtor(string something) + { + Something = something; + } + } + + public class PublicParameterLessCtor + { + } + + protected virtual IServiceProvider GetServiceProvider() + { + return new DefaultServiceProvider(); + } + + [Test] + public void CreateInstanceDefCtor() + { + var sp = GetServiceProvider(); + Assert.Throws(() => sp.GetService(null)); + Assert.Throws(() => sp.GetService(typeof(WithOutPublicParameterLessCtor))); + var instance = sp.GetService(typeof(PublicParameterLessCtor)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + } + + + [Test] + public void RegisterService() + { + var sp = new DefaultServiceProvider(); + + Assert.That(sp.GetService(typeof(IInterceptor)), Is.Null); + + sp.Register(); + var instance = sp.GetService(typeof(IInterceptor)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + + Assert.Throws(() => sp.Register(), "service should not be registered twice."); + Assert.Throws(() => sp.Register(), "non concrete implementation type should not be permitted."); + Assert.Throws(() => sp.Register(typeof(Dialect.Dialect), typeof(EmptyInterceptor)), "concrete implementation type should derive from service type."); + } + + [Test] + public void RegisterServiceCreator() + { + var sp = new DefaultServiceProvider(); + + Assert.That(sp.GetService(typeof(IInterceptor)), Is.Null); + + sp.Register(() => new EmptyInterceptor()); + var instance = sp.GetService(typeof(IInterceptor)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + + Assert.Throws(() => sp.Register(() => new EmptyInterceptor()), "service should not be registered twice."); + } + + } +} diff --git a/src/NHibernate.Test/CfgTest/ConfigurationSchemaFixture.cs b/src/NHibernate.Test/CfgTest/ConfigurationSchemaFixture.cs index 11c7a28d844..55e2bc33159 100644 --- a/src/NHibernate.Test/CfgTest/ConfigurationSchemaFixture.cs +++ b/src/NHibernate.Test/CfgTest/ConfigurationSchemaFixture.cs @@ -73,14 +73,14 @@ public void IgnoreSystemOutOfAppConfig() } [Test] - public void ObjectsFactory() + public void ServiceProvider() { Assume.That(TestsContext.ExecutingWithVsTest, Is.False); var xml = @" - + "; @@ -89,11 +89,11 @@ public void ObjectsFactory() using (var xtr = new XmlTextReader(xml, XmlNodeType.Document, null)) { hc = new HibernateConfiguration(xtr); - Assert.That(hc.ObjectsFactoryType, Is.Null); + Assert.That(hc.ServiceProviderType, Is.Null); } hc = HibernateConfiguration.FromAppConfig(xml); - Assert.That(hc.ObjectsFactoryType, Is.EqualTo("test")); + Assert.That(hc.ServiceProviderType, Is.EqualTo("test")); } [Test] diff --git a/src/NHibernate.Test/CfgTest/CustomObjectsFactoryTest.cs b/src/NHibernate.Test/CfgTest/CustomObjectsFactoryTest.cs deleted file mode 100644 index a1df5d19293..00000000000 --- a/src/NHibernate.Test/CfgTest/CustomObjectsFactoryTest.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using NHibernate.Bytecode; -using NUnit.Framework; -using Environment = NHibernate.Cfg.Environment; - -namespace NHibernate.Test.CfgTest -{ - [TestFixture] - public class CustomObjectsFactoryTest - { - private class MyObjectsFactory : IObjectsFactory - { - public object CreateInstance(System.Type type) - { - throw new NotImplementedException(); - } - - public object CreateInstance(System.Type type, bool nonPublic) - { - throw new NotImplementedException(); - } - - public object CreateInstance(System.Type type, params object[] ctorArgs) - { - throw new NotImplementedException(); - } - } - private class InvalidObjectsFactory - { - } - private class InvalidNoCtorObjectsFactory : MyObjectsFactory - { - public InvalidNoCtorObjectsFactory(string pizza) {} - } - - [Test] - public void WhenNoShortCutUsedThenCanBuildObjectsFactory() - { - var properties = new Dictionary { { Environment.PropertyBytecodeProvider, typeof(MyObjectsFactory).AssemblyQualifiedName } }; - Assert.That(() => Environment.BuildObjectsFactory(properties), Throws.Nothing); - } - - [Test] - public void WhenNoShortCutUsedThenCanBuildInstanceOfConfiguredObjectsFactory() - { - var properties = new Dictionary { { Environment.PropertyObjectsFactory, typeof(MyObjectsFactory).AssemblyQualifiedName } }; - Assert.That(Environment.BuildObjectsFactory(properties), Is.InstanceOf()); - } - - [Test] - public void WhenInvalidThenThrow() - { - var properties = new Dictionary { { Environment.PropertyObjectsFactory, typeof(InvalidObjectsFactory).AssemblyQualifiedName } }; - Assert.That(() => Environment.BuildObjectsFactory(properties), Throws.TypeOf()); - } - - [Test] - public void WhenNoDefaultCtorThenThrow() - { - var properties = new Dictionary { { Environment.PropertyObjectsFactory, typeof(InvalidNoCtorObjectsFactory).AssemblyQualifiedName } }; - Assert.That(() => Environment.BuildObjectsFactory(properties), Throws.TypeOf() - .And.InnerException.Message.Contains("constructor was not found")); - } - } -} diff --git a/src/NHibernate.Test/CfgTest/CustomServiceProviderTest.cs b/src/NHibernate.Test/CfgTest/CustomServiceProviderTest.cs new file mode 100644 index 00000000000..fe19faa2fd0 --- /dev/null +++ b/src/NHibernate.Test/CfgTest/CustomServiceProviderTest.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using NHibernate.Bytecode; +using NUnit.Framework; +using Environment = NHibernate.Cfg.Environment; + +namespace NHibernate.Test.CfgTest +{ + [TestFixture] + public class CustomServiceProviderTest + { + private class MyServiceProvider : IServiceProvider + { + public object GetService(System.Type serviceType) + { + throw new NotImplementedException(); + } + } + private class InvalidServiceProvider + { + } + private class InvalidNoCtorServiceProvider : MyServiceProvider + { + public InvalidNoCtorServiceProvider(string pizza) {} + } + + [Test] + public void WhenNoShortCutUsedThenCanBuildServiceProvider() + { + var properties = new Dictionary { { Environment.PropertyBytecodeProvider, typeof(MyServiceProvider).AssemblyQualifiedName } }; + Assert.That(() => Environment.BuildServiceProvider(properties), Throws.Nothing); + } + + [Test] + public void WhenNoShortCutUsedThenCanBuildInstanceOfConfiguredServiceProvider() + { + var properties = new Dictionary { { Environment.PropertyServiceProvider, typeof(MyServiceProvider).AssemblyQualifiedName } }; + Assert.That(Environment.BuildServiceProvider(properties), Is.InstanceOf()); + } + + [Test] + public void WhenInvalidThenThrow() + { + var properties = new Dictionary { { Environment.PropertyServiceProvider, typeof(InvalidServiceProvider).AssemblyQualifiedName } }; + Assert.That(() => Environment.BuildServiceProvider(properties), Throws.TypeOf()); + } + + [Test] + public void WhenNoDefaultCtorThenThrow() + { + var properties = new Dictionary { { Environment.PropertyServiceProvider, typeof(InvalidNoCtorServiceProvider).AssemblyQualifiedName } }; + Assert.That(() => Environment.BuildServiceProvider(properties), Throws.TypeOf() + .And.InnerException.Message.Contains("constructor was not found")); + } + } +} diff --git a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs index 640eb45cf80..102e1588a0d 100644 --- a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs @@ -1,6 +1,19 @@ +using System; using System.Collections.Generic; +using NHibernate.AdoNet; +using NHibernate.Bytecode; +using NHibernate.Cache; using NHibernate.Cfg; +using NHibernate.Connection; +using NHibernate.Exceptions; +using NHibernate.Hql; +using NHibernate.Hql.Ast.ANTLR; +using NHibernate.Linq.Functions; +using NHibernate.Linq.Visitors; +using NHibernate.Transaction; +using NSubstitute; using NUnit.Framework; +using Environment = NHibernate.Cfg.Environment; namespace NHibernate.Test.CfgTest { @@ -18,5 +31,115 @@ public void DefaultValueForKeyWords() Assert.That(settings.IsKeywordsImportEnabled); Assert.That(!settings.IsAutoQuoteEnabled); } + + [Test] + public void DefaultServices() + { + var properties = new Dictionary + { + {Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName}, + {Environment.UseQueryCache, "true"} + }; + var settings = new SettingsFactory().BuildSettings(properties); + Assert.That(settings.BatcherFactory, Is.TypeOf()); + Assert.That(settings.CacheProvider, Is.TypeOf()); + Assert.That(settings.ConnectionProvider, Is.TypeOf()); + Assert.That(settings.Dialect, Is.TypeOf()); + Assert.That(settings.LinqToHqlGeneratorsRegistry, Is.TypeOf()); + Assert.That(settings.QueryCacheFactory, Is.TypeOf()); + Assert.That(settings.QueryModelRewriterFactory, Is.Null); + Assert.That(settings.QueryTranslatorFactory, Is.TypeOf()); + Assert.That(settings.QueryCacheFactory, Is.TypeOf()); + Assert.That(settings.SqlExceptionConverter, Is.TypeOf()); + Assert.That(settings.TransactionFactory, Is.TypeOf()); + } + + [Test] + public void RegisteredServices() + { + var originalSp = Environment.ServiceProvider; + + var batcherFactory = Substitute.For(); + var cacheProvider = Substitute.For(); + var connectionProvider = Substitute.For(); + var dialect = new Dialect.MsSql2005Dialect(); + var linqToHqlRegistry = Substitute.For(); + var queryCacheFactory = Substitute.For(); + var queryModelRewriterFactory = Substitute.For(); + var queryTranslatorFactory = Substitute.For(); + var sqlExceptionConverter = Substitute.For(); + var transactionFactory = Substitute.For(); + + var sp = new DefaultServiceProvider(); + sp.Register(() => batcherFactory); + sp.Register(() => cacheProvider); + sp.Register(() => connectionProvider); + sp.Register(() => dialect); + sp.Register(() => linqToHqlRegistry); + sp.Register(() => queryCacheFactory); + sp.Register(() => queryModelRewriterFactory); + sp.Register(() => queryTranslatorFactory); + sp.Register(() => sqlExceptionConverter); + sp.Register(() => transactionFactory); + + Environment.ServiceProvider = sp; + + var properties = new Dictionary + { + {Environment.UseQueryCache, "true"} + }; + var settings = new SettingsFactory().BuildSettings(properties); + Assert.That(settings.BatcherFactory, Is.EqualTo(batcherFactory)); + Assert.That(settings.CacheProvider, Is.EqualTo(cacheProvider)); + Assert.That(settings.ConnectionProvider, Is.EqualTo(connectionProvider)); + Assert.That(settings.Dialect, Is.EqualTo(dialect)); + Assert.That(settings.LinqToHqlGeneratorsRegistry, Is.EqualTo(linqToHqlRegistry)); + Assert.That(settings.QueryCacheFactory, Is.EqualTo(queryCacheFactory)); + Assert.That(settings.QueryModelRewriterFactory, Is.EqualTo(queryModelRewriterFactory)); + Assert.That(settings.QueryTranslatorFactory, Is.EqualTo(queryTranslatorFactory)); + Assert.That(settings.SqlExceptionConverter, Is.EqualTo(sqlExceptionConverter)); + Assert.That(settings.TransactionFactory, Is.EqualTo(transactionFactory)); + + Environment.ServiceProvider = originalSp; + } + + [Test] + public void InvalidRegisteredServices() + { + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + InvalidRegisteredService(); + } + + private void InvalidRegisteredService() + { + var originalSp = Environment.ServiceProvider; + + var sp = new DefaultServiceProvider(); + sp.Register(() => throw new InvalidOperationException()); + + Environment.ServiceProvider = sp; + + var properties = new Dictionary + { + {Environment.UseQueryCache, "true"} + }; + if (typeof(TService) != typeof(Dialect.Dialect)) + { + properties.Add(Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName); + } + + Assert.Throws( + () => new SettingsFactory().BuildSettings(properties), + $"HibernateException should be thrown for service {typeof(TService)}"); + + Environment.ServiceProvider = originalSp; + } } -} \ No newline at end of file +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs index 22267fb030c..f310e1db94b 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs @@ -132,7 +132,7 @@ public partial class DriverForSubstitutedCommand : IDriver public DriverForSubstitutedCommand() { - _driverImplementation = (IDriver) Cfg.Environment.ObjectsFactory.CreateInstance(DriverClass); + _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass); } DbCommand IDriver.GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) diff --git a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs index d04cc6693aa..87d4855b274 100644 --- a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs +++ b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs @@ -534,7 +534,7 @@ public class ClientDriverWithParamsStats : IDriver public ClientDriverWithParamsStats() { - _driverImplementation = (IDriver) Cfg.Environment.ObjectsFactory.CreateInstance(DriverClass); + _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass); } private static void Inc(T type, IDictionary dic) diff --git a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs index 188d6e9aef5..cb3bec4627a 100644 --- a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs +++ b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using NHibernate.Bytecode; +using NHibernate.Connection; using NHibernate.Util; using NUnit.Framework; @@ -42,5 +44,88 @@ public void WhenValidInt64ValueThenValue() { Assert.That(PropertiesHelper.GetInt64("myProp", new Dictionary { { "myProp", long.MaxValue.ToString() } }, 5), Is.EqualTo(long.MaxValue)); } + + [Test] + public void GetInstanceByDefault() + { + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DebugConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); + } + + [Test] + public void GetInstanceByRegistration() + { + var originalSp = Cfg.Environment.ServiceProvider; + var sp = new DefaultServiceProvider(); + sp.Register(); + Cfg.Environment.ServiceProvider = sp; + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DebugConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); + + Cfg.Environment.ServiceProvider = originalSp; + } + + [Test] + public void GetInstanceByProperty() + { + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary {{ "conn", typeof(DriverConnectionProvider).AssemblyQualifiedName } }, + typeof(DebugConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); + } + + [Test] + public void GetInstanceByInvalidDefault() + { + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(PropertiesHelperTest)); + }); + } + + [Test] + public void GetInstanceByInvalidRegistration() + { + var originalSp = Cfg.Environment.ServiceProvider; + var sp = new DefaultServiceProvider(); + sp.Register(typeof(IConnectionProvider), () => new PropertiesHelperTest()); + Cfg.Environment.ServiceProvider = sp; + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DriverConnectionProvider)); + }); + Cfg.Environment.ServiceProvider = originalSp; + } + + [Test] + public void GetInstanceByInvalidProperty() + { + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(PropertiesHelperTest).AssemblyQualifiedName}}, + typeof(DriverConnectionProvider)); + }); + } } } diff --git a/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs b/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs index 893f48e9a57..028a90e1322 100644 --- a/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs +++ b/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs @@ -78,7 +78,7 @@ public partial class SchemaUpdate { cfg.SetNamingStrategy( (INamingStrategy) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs b/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs index 78a3ead7995..e420e4ead8f 100644 --- a/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs +++ b/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs @@ -48,7 +48,7 @@ public partial class SchemaValidator { cfg.SetNamingStrategy( (INamingStrategy) - Cfg.Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Async/Type/CompositeCustomType.cs b/src/NHibernate/Async/Type/CompositeCustomType.cs index 10e6590f7a6..70bf795ce62 100644 --- a/src/NHibernate/Async/Type/CompositeCustomType.cs +++ b/src/NHibernate/Async/Type/CompositeCustomType.cs @@ -16,6 +16,7 @@ using NHibernate.Engine; using NHibernate.SqlTypes; using NHibernate.UserTypes; +using NHibernate.Util; using System.Collections.Generic; namespace NHibernate.Type diff --git a/src/NHibernate/Async/Type/CustomCollectionType.cs b/src/NHibernate/Async/Type/CustomCollectionType.cs index fa65efdd02d..e42987ab936 100644 --- a/src/NHibernate/Async/Type/CustomCollectionType.cs +++ b/src/NHibernate/Async/Type/CustomCollectionType.cs @@ -14,6 +14,7 @@ using NHibernate.Engine; using NHibernate.Persister.Collection; using NHibernate.UserTypes; +using NHibernate.Util; namespace NHibernate.Type { @@ -39,4 +40,4 @@ public override Task ReplaceElementsAsync(object original, object target } } } -} \ No newline at end of file +} diff --git a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs index b112877c212..6e457cb3d23 100644 --- a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs +++ b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs @@ -6,6 +6,9 @@ namespace NHibernate.Bytecode { public abstract class AbstractBytecodeProvider : IBytecodeProvider, IInjectableProxyFactoryFactory, IInjectableCollectionTypeFactoryClass { +#pragma warning disable 618 + private static readonly IObjectsFactory ObjectFactory = new ActivatorObjectsFactory(); +#pragma warning restore 618 protected System.Type proxyFactoryFactory; private ICollectionTypeFactory collectionTypeFactory; private System.Type collectionTypeFactoryClass = typeof(Type.DefaultCollectionTypeFactory); @@ -20,7 +23,7 @@ public virtual IProxyFactoryFactory ProxyFactoryFactory { try { - return (IProxyFactoryFactory) Cfg.Environment.ObjectsFactory.CreateInstance(proxyFactoryFactory); + return (IProxyFactoryFactory) Cfg.Environment.ServiceProvider.GetService(proxyFactoryFactory); } catch (Exception e) { @@ -35,8 +38,8 @@ public virtual IProxyFactoryFactory ProxyFactoryFactory public abstract IReflectionOptimizer GetReflectionOptimizer(System.Type clazz, IGetter[] getters, ISetter[] setters); // Since 5.2 - [Obsolete("Please use NHibernate.Cfg.Environment.ObjectsFactory instead")] - public virtual IObjectsFactory ObjectsFactory => Cfg.Environment.ObjectsFactory; + [Obsolete("Please use NHibernate.Cfg.Environment.ServiceProvider instead")] + public virtual IObjectsFactory ObjectsFactory => ObjectFactory; public virtual ICollectionTypeFactory CollectionTypeFactory { @@ -47,7 +50,7 @@ public virtual ICollectionTypeFactory CollectionTypeFactory try { collectionTypeFactory = - (ICollectionTypeFactory) Cfg.Environment.ObjectsFactory.CreateInstance(collectionTypeFactoryClass); + (ICollectionTypeFactory) Cfg.Environment.ServiceProvider.GetInstance(collectionTypeFactoryClass); } catch (Exception e) { diff --git a/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs b/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs index 561d5b3afe4..8b087ccaff8 100644 --- a/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs +++ b/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs @@ -2,22 +2,23 @@ namespace NHibernate.Bytecode { - public class ActivatorObjectsFactory: IObjectsFactory + // Since v5.2 + [Obsolete("This type has no more usages and will be removed in a future version")] + public class ActivatorObjectsFactory : +#pragma warning disable 618 + IObjectsFactory +#pragma warning restore 618 { public object CreateInstance(System.Type type) { return Activator.CreateInstance(type); } - // Since v5.2 - [Obsolete("This method has no more usages and will be removed in a future version")] public object CreateInstance(System.Type type, bool nonPublic) { return Activator.CreateInstance(type, nonPublic); } - // Since v5.2 - [Obsolete("This method has no more usages and will be removed in a future version")] public object CreateInstance(System.Type type, params object[] ctorArgs) { return Activator.CreateInstance(type, ctorArgs); diff --git a/src/NHibernate/Bytecode/DefaultServiceProvider.cs b/src/NHibernate/Bytecode/DefaultServiceProvider.cs new file mode 100644 index 00000000000..3028c74b7da --- /dev/null +++ b/src/NHibernate/Bytecode/DefaultServiceProvider.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NHibernate.Bytecode +{ + /// + /// The default NHibernate service provider that uses to instantiate + /// services by default. + /// + public class DefaultServiceProvider : IServiceProvider + { + private readonly ConcurrentDictionary> _registeredTypeProviders = + new ConcurrentDictionary>(); + + /// + public object GetService(System.Type serviceType) + { + if (serviceType == null) + { + throw new ArgumentNullException(nameof(serviceType)); + } + + if (_registeredTypeProviders.TryGetValue(serviceType, out var serviceProvider)) + { + return serviceProvider(); + } + + if (serviceType.IsInterface || serviceType.IsAbstract) + { + return null; + } + + return Activator.CreateInstance(serviceType); + } + + /// + /// Register the specified delegate that will be called when the + /// type is requested. + /// + /// The type to register. + /// The delegate taht creates the instance. + public void Register(Func instanceCreator) + { + Register(typeof(TService), () => instanceCreator()); + } + + /// + /// Register the specified delegate that will be called when the + /// type is requested. + /// + /// The type to register. + /// The delegate that creates the instance. + public void Register(System.Type serviceType, Func instanceCreator) + { + if (serviceType == null) + { + throw new ArgumentNullException(nameof(serviceType)); + } + + if (instanceCreator == null) + { + throw new ArgumentNullException(nameof(instanceCreator)); + } + + if (!_registeredTypeProviders.TryAdd(serviceType, instanceCreator)) + { + throw new InvalidOperationException($"Service type {serviceType} is already registered."); + } + } + + /// + /// Register that an instance of will be returned when an + /// instance of type is requested. + /// + /// The type to register. + /// The concrete type that will be registered. + public void Register() where TImplementation : class + { + Register(typeof(TService), typeof(TImplementation)); + } + + /// + /// Register that an instance of will be returned when an + /// instance of type is requested. + /// + public void Register(System.Type serviceType, System.Type implementationType) + { + if (serviceType == null) + { + throw new ArgumentNullException(nameof(serviceType)); + } + if (implementationType == null) + { + throw new ArgumentNullException(nameof(implementationType)); + } + if (!serviceType.IsAssignableFrom(implementationType)) + { + throw new InvalidOperationException( + $"Implementation type {implementationType} is not assignable to service type {serviceType}."); + } + + if (implementationType.IsAbstract || implementationType.IsInterface) + { + throw new InvalidOperationException($"Implementation type {implementationType} is not a concrete type."); + } + + if (implementationType.GetConstructors().All(o => o.GetParameters().Length > 0)) + { + throw new InvalidOperationException($"Implementation type {implementationType} does not have a parameterless constructor."); + } + + Register(serviceType, () => Activator.CreateInstance(implementationType)); + } + } +} diff --git a/src/NHibernate/Bytecode/HibernateObjectsFactoryException.cs b/src/NHibernate/Bytecode/HibernateObjectsFactoryException.cs deleted file mode 100644 index f4551474bd0..00000000000 --- a/src/NHibernate/Bytecode/HibernateObjectsFactoryException.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace NHibernate.Bytecode -{ - /// - /// Thrown if NHibernate can't instantiate the type. - /// - [Serializable] - public class HibernateObjectsFactoryException : HibernateException - { - public HibernateObjectsFactoryException() {} - public HibernateObjectsFactoryException(string message) : base(message) {} - public HibernateObjectsFactoryException(string message, Exception inner) : base(message, inner) {} - - protected HibernateObjectsFactoryException(SerializationInfo info, StreamingContext context) : base(info, context) {} - } -} diff --git a/src/NHibernate/Bytecode/HibernateServiceProviderException.cs b/src/NHibernate/Bytecode/HibernateServiceProviderException.cs new file mode 100644 index 00000000000..a4570100059 --- /dev/null +++ b/src/NHibernate/Bytecode/HibernateServiceProviderException.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.Serialization; + +namespace NHibernate.Bytecode +{ + /// + /// Thrown if NHibernate can't instantiate the type. + /// + [Serializable] + public class HibernateServiceProviderException : HibernateException + { + public HibernateServiceProviderException() {} + public HibernateServiceProviderException(string message) : base(message) {} + public HibernateServiceProviderException(string message, Exception inner) : base(message, inner) {} + + protected HibernateServiceProviderException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +} diff --git a/src/NHibernate/Bytecode/IBytecodeProvider.cs b/src/NHibernate/Bytecode/IBytecodeProvider.cs index 2b9b4c29aa5..baffd17c7ec 100644 --- a/src/NHibernate/Bytecode/IBytecodeProvider.cs +++ b/src/NHibernate/Bytecode/IBytecodeProvider.cs @@ -28,7 +28,7 @@ public interface IBytecodeProvider /// For entities and its implementations. /// // Since 5.2 - [Obsolete("Please use NHibernate.Cfg.Environment.ObjectsFactory instead")] + [Obsolete("Please use NHibernate.Cfg.Environment.ServiceProvider instead")] IObjectsFactory ObjectsFactory { get; } /// @@ -48,4 +48,4 @@ public interface IBytecodeProvider // Not ported //ClassTransformer getTransformer(ClassFilter classFilter, FieldFilter fieldFilter); } -} \ No newline at end of file +} diff --git a/src/NHibernate/Bytecode/IObjectsFactory.cs b/src/NHibernate/Bytecode/IObjectsFactory.cs index 27a8ee26ec1..4f8b5b93288 100644 --- a/src/NHibernate/Bytecode/IObjectsFactory.cs +++ b/src/NHibernate/Bytecode/IObjectsFactory.cs @@ -5,6 +5,8 @@ namespace NHibernate.Bytecode /// /// Interface for instantiating NHibernate dependencies. /// + // Since v5.2 + [Obsolete("This type has no more usages and will be removed in a future version")] public interface IObjectsFactory { /// @@ -20,8 +22,6 @@ public interface IObjectsFactory /// The type of object to create. /// true if a public or nonpublic default constructor can match; false if only a public default constructor can match. /// A reference to the created object. - // Since v5.2 - [Obsolete("This method has no more usages and will be removed in a future version")] object CreateInstance(System.Type type, bool nonPublic); /// @@ -31,8 +31,6 @@ public interface IObjectsFactory /// The type of object to create. /// An array of constructor arguments. /// A reference to the created object. - // Since v5.2 - [Obsolete("This method has no more usages and will be removed in a future version")] object CreateInstance(System.Type type, params object[] ctorArgs); } } diff --git a/src/NHibernate/Cfg/Configuration.cs b/src/NHibernate/Cfg/Configuration.cs index 6e92eaf9f9f..f9a5309df3a 100644 --- a/src/NHibernate/Cfg/Configuration.cs +++ b/src/NHibernate/Cfg/Configuration.cs @@ -1908,7 +1908,7 @@ public void SetListeners(ListenerType type, string[] listenerClasses) { try { - listeners[i] = Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(listenerClasses[i])); + listeners[i] = Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(listenerClasses[i])); } catch (Exception e) { diff --git a/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs b/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs index d2cb08ecdd2..c4d5e8d1098 100644 --- a/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs +++ b/src/NHibernate/Cfg/ConfigurationSchema/CfgXmlHelper.cs @@ -35,7 +35,7 @@ static CfgXmlHelper() nsMgr.AddNamespace(CfgNamespacePrefix, CfgSchemaXMLNS); ByteCodeProviderExpression = XPathExpression.Compile(RootPrefixPath + "bytecode-provider", nsMgr); - ObjectsFactoryExpression = XPathExpression.Compile(RootPrefixPath + "objects-factory", nsMgr); + ServiceProviderExpression = XPathExpression.Compile(RootPrefixPath + "service-provider", nsMgr); ReflectionOptimizerExpression = XPathExpression.Compile(RootPrefixPath + "reflection-optimizer", nsMgr); SessionFactoryExpression = XPathExpression.Compile(RootPrefixPath + "session-factory", nsMgr); SessionFactoryPropertiesExpression = XPathExpression.Compile(RootPrefixPath + "session-factory/" + ChildPrefixPath + "property", nsMgr); @@ -49,7 +49,7 @@ static CfgXmlHelper() /// XPath expression for bytecode-provider property. public static readonly XPathExpression ByteCodeProviderExpression; /// XPath expression for objects-factory property. - public static readonly XPathExpression ObjectsFactoryExpression; + public static readonly XPathExpression ServiceProviderExpression; /// XPath expression for reflection-optimizer property. public static readonly XPathExpression ReflectionOptimizerExpression; /// XPath expression for session-factory whole node. diff --git a/src/NHibernate/Cfg/ConfigurationSchema/HibernateConfiguration.cs b/src/NHibernate/Cfg/ConfigurationSchema/HibernateConfiguration.cs index 5208e7428e8..c3670f78899 100644 --- a/src/NHibernate/Cfg/ConfigurationSchema/HibernateConfiguration.cs +++ b/src/NHibernate/Cfg/ConfigurationSchema/HibernateConfiguration.cs @@ -77,7 +77,7 @@ private XmlReaderSettings GetSettings() private void Parse(XPathNavigator navigator, bool fromAppConfig) { ParseByteCodeProvider(navigator, fromAppConfig); - ParseObjectsFactory(navigator, fromAppConfig); + ParseServiceProvider(navigator, fromAppConfig); ParseReflectionOptimizer(navigator, fromAppConfig); XPathNavigator xpn = navigator.SelectSingleNode(CfgXmlHelper.SessionFactoryExpression); if (xpn != null) @@ -111,19 +111,19 @@ private void ParseByteCodeProvider(XPathNavigator navigator, bool fromAppConfig) } } - private void ParseObjectsFactory(XPathNavigator navigator, bool fromAppConfig) + private void ParseServiceProvider(XPathNavigator navigator, bool fromAppConfig) { - var xpn = navigator.SelectSingleNode(CfgXmlHelper.ObjectsFactoryExpression); + var xpn = navigator.SelectSingleNode(CfgXmlHelper.ServiceProviderExpression); if (xpn != null) { if (fromAppConfig) { xpn.MoveToFirstAttribute(); - ObjectsFactoryType = xpn.Value; + ServiceProviderType = xpn.Value; } else { - LogWarnIgnoredProperty("objects-factory"); + LogWarnIgnoredProperty("service-provider"); } } } @@ -166,7 +166,7 @@ public string ByteCodeProviderType /// /// Default value . // 6.0 TODO add to IHibernateConfiguration - public string ObjectsFactoryType { get; private set; } + public string ServiceProviderType { get; private set; } private bool useReflectionOptimizer = true; /// diff --git a/src/NHibernate/Cfg/Environment.cs b/src/NHibernate/Cfg/Environment.cs index 46121071367..e5462edd030 100644 --- a/src/NHibernate/Cfg/Environment.cs +++ b/src/NHibernate/Cfg/Environment.cs @@ -202,9 +202,9 @@ public static string Version public const string PropertyUseReflectionOptimizer = "use_reflection_optimizer"; /// - /// Set the used to instantiate NHibernate's objects. + /// Set the used to instantiate NHibernate's objects. /// - public const string PropertyObjectsFactory = "objects_factory"; + public const string PropertyServiceProvider = "service_provider"; public const string UseProxyValidator = "use_proxy_validator"; public const string ProxyFactoryFactoryClass = "proxyfactory.factory_class"; @@ -313,7 +313,7 @@ public static void InitializeGlobalProperties(IHibernateConfiguration config) GlobalProperties[PropertyUseReflectionOptimizer] = config.UseReflectionOptimizer.ToString(); if (config is HibernateConfiguration nhConfig) { - GlobalProperties[PropertyObjectsFactory] = nhConfig.ObjectsFactoryType; + GlobalProperties[PropertyServiceProvider] = nhConfig.ServiceProviderType; } if (config.SessionFactory != null) { @@ -331,7 +331,7 @@ public static void InitializeGlobalProperties(IHibernateConfiguration config) VerifyProperties(GlobalProperties); BytecodeProviderInstance = BuildBytecodeProvider(GlobalProperties); - ObjectsFactory = BuildObjectsFactory(GlobalProperties); + ServiceProvider = BuildServiceProvider(GlobalProperties); EnableReflectionOptimizer = PropertiesHelper.GetBoolean(PropertyUseReflectionOptimizer, GlobalProperties); if (EnableReflectionOptimizer) @@ -388,16 +388,7 @@ public static IDictionary Properties public static IBytecodeProvider BytecodeProvider { get { return BytecodeProviderInstance; } - set - { - BytecodeProviderInstance = value; - // 6.0 TODO: remove following code. -#pragma warning disable 618 - var objectsFactory = BytecodeProviderInstance.ObjectsFactory; -#pragma warning restore 618 - if (objectsFactory != null) - ObjectsFactory = objectsFactory; - } + set { BytecodeProviderInstance = value; } } /// @@ -413,7 +404,7 @@ public static IBytecodeProvider BytecodeProvider /// is created, otherwise the change may not take effect. /// For entities see and its implementations. /// - public static IObjectsFactory ObjectsFactory { get; set; } = new ActivatorObjectsFactory(); + public static IServiceProvider ServiceProvider { get; set; } = new DefaultServiceProvider(); /// /// Whether to enable the use of reflection optimizer @@ -454,20 +445,17 @@ private static IBytecodeProvider BuildBytecodeProvider(string providerName) } } - public static IObjectsFactory BuildObjectsFactory(IDictionary properties) + public static IServiceProvider BuildServiceProvider(IDictionary properties) { - var typeAssemblyQualifiedName = PropertiesHelper.GetString(PropertyObjectsFactory, properties, null); + var typeAssemblyQualifiedName = PropertiesHelper.GetString(PropertyServiceProvider, properties, null); if (typeAssemblyQualifiedName == null) { - // 6.0 TODO: use default value of ObjectsFactory property -#pragma warning disable 618 - var objectsFactory = BytecodeProvider.ObjectsFactory ?? ObjectsFactory; -#pragma warning restore 618 - log.Info("Objects factory class : {0}", objectsFactory.GetType()); - return objectsFactory; + var serviceProvider = new DefaultServiceProvider(); + log.Info("Service provider class : {0}", serviceProvider.GetType()); + return serviceProvider; } - log.Info("Custom objects factory class : {0}", typeAssemblyQualifiedName); - return CreateCustomObjectsFactory(typeAssemblyQualifiedName); + log.Info("Custom service provider class : {0}", typeAssemblyQualifiedName); + return CreateCustomServiceProvider(typeAssemblyQualifiedName); } private static IBytecodeProvider CreateCustomBytecodeProvider(string assemblyQualifiedName) @@ -498,31 +486,31 @@ private static IBytecodeProvider CreateCustomBytecodeProvider(string assemblyQua } } - private static IObjectsFactory CreateCustomObjectsFactory(string assemblyQualifiedName) + private static IServiceProvider CreateCustomServiceProvider(string assemblyQualifiedName) { try { var type = ReflectHelper.ClassForName(assemblyQualifiedName); try { - return (IObjectsFactory) Activator.CreateInstance(type); + return (IServiceProvider) Activator.CreateInstance(type); } catch (MissingMethodException ex) { - throw new HibernateObjectsFactoryException("Public constructor was not found for " + type, ex); + throw new HibernateServiceProviderException("Public constructor was not found for " + type, ex); } catch (InvalidCastException ex) { - throw new HibernateObjectsFactoryException(type + "Type does not implement " + typeof(IObjectsFactory), ex); + throw new HibernateServiceProviderException(type + "Type does not implement " + typeof(IServiceProvider), ex); } catch (Exception ex) { - throw new HibernateObjectsFactoryException("Unable to instantiate: " + type, ex); + throw new HibernateServiceProviderException("Unable to instantiate: " + type, ex); } } catch (Exception e) { - throw new HibernateObjectsFactoryException("Unable to create the instance of objects factory; check inner exception for detail", e); + throw new HibernateServiceProviderException("Unable to create the instance of service provider; check inner exception for detail", e); } } diff --git a/src/NHibernate/Cfg/SettingsFactory.cs b/src/NHibernate/Cfg/SettingsFactory.cs index dd3195350c4..39d2a85b9e3 100644 --- a/src/NHibernate/Cfg/SettingsFactory.cs +++ b/src/NHibernate/Cfg/SettingsFactory.cs @@ -24,7 +24,7 @@ namespace NHibernate.Cfg public sealed class SettingsFactory { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(SettingsFactory)); - private static readonly string DefaultCacheProvider = typeof(NoCacheProvider).AssemblyQualifiedName; + private static readonly System.Type DefaultCacheProvider = typeof(NoCacheProvider); public Settings BuildSettings(IDictionary properties) { @@ -210,19 +210,11 @@ public Settings BuildSettings(IDictionary properties) if (useQueryCache) { - string queryCacheFactoryClassName = PropertiesHelper.GetString(Environment.QueryCacheFactory, properties, - typeof (StandardQueryCacheFactory).FullName); - log.Info("query cache factory: {0}", queryCacheFactoryClassName); - try - { - settings.QueryCacheFactory = - (IQueryCacheFactory) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(queryCacheFactoryClassName)); - } - catch (Exception cnfe) - { - throw new HibernateException("could not instantiate IQueryCacheFactory: " + queryCacheFactoryClassName, cnfe); - } + settings.QueryCacheFactory = PropertiesHelper.GetInstance( + Environment.QueryCacheFactory, + properties, + typeof(StandardQueryCacheFactory)); + log.Info("query cache factory: {0}", settings.QueryCacheFactory.GetType().AssemblyQualifiedName); } string sessionFactoryName = PropertiesHelper.GetString(Environment.SessionFactoryName, properties, null); @@ -312,31 +304,42 @@ public Settings BuildSettings(IDictionary properties) private static IBatcherFactory CreateBatcherFactory(IDictionary properties, int batchSize, IConnectionProvider connectionProvider) { - System.Type tBatcher = typeof (NonBatchingBatcherFactory); - string batcherClass = PropertiesHelper.GetString(Environment.BatchStrategy, properties, null); + System.Type tBatcher = null; + var batcherClass = PropertiesHelper.GetString(Environment.BatchStrategy, properties, null); if (string.IsNullOrEmpty(batcherClass)) { if (batchSize > 0) { // try to get the BatcherFactory from the Drive if not available use NonBatchingBatcherFactory - IEmbeddedBatcherFactoryProvider ebfp = connectionProvider.Driver as IEmbeddedBatcherFactoryProvider; - if (ebfp != null && ebfp.BatcherFactoryClass != null) + if (connectionProvider.Driver is IEmbeddedBatcherFactoryProvider ebfp && ebfp.BatcherFactoryClass != null) + { tBatcher = ebfp.BatcherFactoryClass; + } } } else { tBatcher = ReflectHelper.ClassForName(batcherClass); } - log.Info("Batcher factory: {0}", tBatcher.AssemblyQualifiedName); + + IBatcherFactory instance = null; try { - return (IBatcherFactory) Environment.ObjectsFactory.CreateInstance(tBatcher); + if (tBatcher == null) + { + instance = (IBatcherFactory) Environment.ServiceProvider.GetService(typeof(IBatcherFactory)); + } + if (instance == null) + { + instance = (IBatcherFactory) Environment.ServiceProvider.GetInstance(tBatcher ?? typeof(NonBatchingBatcherFactory)); + } } catch (Exception cnfe) { throw new HibernateException("Could not instantiate BatcherFactory: " + batcherClass, cnfe); } + log.Info("Batcher factory: {0}", instance.GetType().AssemblyQualifiedName); + return instance; } private static string EnabledDisabled(bool value) @@ -346,36 +349,23 @@ private static string EnabledDisabled(bool value) private static ICacheProvider CreateCacheProvider(IDictionary properties) { - string cacheClassName = PropertiesHelper.GetString(Environment.CacheProvider, properties, DefaultCacheProvider); - log.Info("cache provider: {0}", cacheClassName); - try - { - return - (ICacheProvider) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(cacheClassName)); - } - catch (Exception e) - { - throw new HibernateException("could not instantiate CacheProvider: " + cacheClassName, e); - } + var instance = PropertiesHelper.GetInstance( + Environment.CacheProvider, + properties, + DefaultCacheProvider); + log.Info("cache provider: {0}", instance.GetType().AssemblyQualifiedName); + return instance; } // visibility changed and static modifier added until complete H3.2 porting of SettingsFactory private static IQueryTranslatorFactory CreateQueryTranslatorFactory(IDictionary properties) { - string className = PropertiesHelper.GetString( - Environment.QueryTranslator, properties, typeof(Hql.Ast.ANTLR.ASTQueryTranslatorFactory).FullName); - log.Info("Query translator: {0}", className); - try - { - return - (IQueryTranslatorFactory) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(className)); - } - catch (Exception cnfe) - { - throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe); - } + var instance = PropertiesHelper.GetInstance( + Environment.QueryTranslator, + properties, + typeof(Hql.Ast.ANTLR.ASTQueryTranslatorFactory)); + log.Info("Query translator: {0}", instance.GetType().AssemblyQualifiedName); + return instance; } private static System.Type CreateLinqQueryProviderType(IDictionary properties) @@ -395,30 +385,37 @@ private static System.Type CreateLinqQueryProviderType(IDictionary properties) { - string className = PropertiesHelper.GetString( - Environment.TransactionStrategy, properties, typeof(AdoNetWithSystemTransactionFactory).FullName); - log.Info("Transaction factory: {0}", className); - - try - { - var transactionFactory = - (ITransactionFactory) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(className)); - transactionFactory.Configure(properties); - return transactionFactory; - } - catch (Exception cnfe) - { - throw new HibernateException("could not instantiate TransactionFactory: " + className, cnfe); - } + var instance = PropertiesHelper.GetInstance( + Environment.TransactionStrategy, + properties, + typeof(AdoNetWithSystemTransactionFactory)); + log.Info("Transaction factory: {0}", instance.GetType().AssemblyQualifiedName); + return instance; } private static IQueryModelRewriterFactory CreateQueryModelRewriterFactory(IDictionary properties) { - string className = PropertiesHelper.GetString(Environment.QueryModelRewriterFactory, properties, null); + var className = PropertiesHelper.GetString(Environment.QueryModelRewriterFactory, properties, null); if (className == null) - return null; + { + try + { + var instance = + (IQueryModelRewriterFactory) + Environment.ServiceProvider.GetService(typeof(IQueryModelRewriterFactory)); + if (instance == null) + { + return null; + } + log.Info("Query model rewriter factory factory: {0}", instance.GetType().AssemblyQualifiedName); + return instance; + } + catch (Exception cnfe) + { + throw new HibernateException("could not instantiate IQueryModelRewriterFactory", cnfe); + } + } log.Info("Query model rewriter factory factory: {0}", className); @@ -426,7 +423,7 @@ private static IQueryModelRewriterFactory CreateQueryModelRewriterFactory(IDicti { return (IQueryModelRewriterFactory) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(className)); + Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(className)); } catch (Exception cnfe) { diff --git a/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs b/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs index c6cb90ef954..f09eb41f699 100644 --- a/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs +++ b/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs @@ -42,7 +42,7 @@ private static IAuxiliaryDatabaseObject CreateCustomObject(Mappings mappings, Hb System.Type customType = ReflectHelper.ClassForName(className); IAuxiliaryDatabaseObject customObject = - (IAuxiliaryDatabaseObject) Environment.ObjectsFactory.CreateInstance(customType); + (IAuxiliaryDatabaseObject) Environment.ServiceProvider.GetInstance(customType); foreach (string dialectName in databaseObjectSchema.FindDialectScopeNames()) { diff --git a/src/NHibernate/Connection/ConnectionProvider.cs b/src/NHibernate/Connection/ConnectionProvider.cs index 0d908f1f672..02509277959 100644 --- a/src/NHibernate/Connection/ConnectionProvider.cs +++ b/src/NHibernate/Connection/ConnectionProvider.cs @@ -94,24 +94,34 @@ protected virtual string GetNamedConnectionString(IDictionary se /// protected virtual void ConfigureDriver(IDictionary settings) { - string driverClass; - if (!settings.TryGetValue(Environment.ConnectionDriver, out driverClass)) - { - throw new HibernateException("The " + Environment.ConnectionDriver + - " must be specified in the NHibernate configuration section."); - } - else + if (!settings.TryGetValue(Environment.ConnectionDriver, out var driverClass)) { try { - driver = - (IDriver) Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(driverClass)); - driver.Configure(settings); + driver = (IDriver) Environment.ServiceProvider.GetService(typeof(IDriver)); + if (driver != null) + { + driver.Configure(settings); + return; + } } catch (Exception e) { - throw new HibernateException("Could not create the driver from " + driverClass + ".", e); + throw new HibernateException($"Could not create the driver from {typeof(IDriver)}.", e); } + throw new HibernateException( + $"The {Environment.ConnectionDriver} must be specified in the NHibernate configuration section."); + } + + try + { + driver = + (IDriver) Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(driverClass)); + driver.Configure(settings); + } + catch (Exception e) + { + throw new HibernateException($"Could not create the driver from {driverClass}.", e); } } diff --git a/src/NHibernate/Connection/ConnectionProviderFactory.cs b/src/NHibernate/Connection/ConnectionProviderFactory.cs index b950389dfc8..c976c496cef 100644 --- a/src/NHibernate/Connection/ConnectionProviderFactory.cs +++ b/src/NHibernate/Connection/ConnectionProviderFactory.cs @@ -17,15 +17,14 @@ public static class ConnectionProviderFactory public static IConnectionProvider NewConnectionProvider(IDictionary settings) { IConnectionProvider connections; - string providerClass; - if (settings.TryGetValue(Environment.ConnectionProvider, out providerClass)) + if (settings.TryGetValue(Environment.ConnectionProvider, out var providerClass)) { try { log.Info("Initializing connection provider: {0}", providerClass); connections = (IConnectionProvider) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(providerClass)); + Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(providerClass)); } catch (Exception e) { @@ -39,8 +38,20 @@ public static IConnectionProvider NewConnectionProvider(IDictionary /// An allowing to set its session factory. Implementing - /// this interface allows the to be used for instantiating the + /// this interface allows the to be used for instantiating the /// session context. /// public interface ISessionFactoryAwareCurrentSessionContext : ICurrentSessionContext diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs index 1dcdac383f0..684c3da679f 100644 --- a/src/NHibernate/Dialect/Dialect.cs +++ b/src/NHibernate/Dialect/Dialect.cs @@ -169,9 +169,22 @@ public static Dialect GetDialect(IDictionary props) { if (props == null) throw new ArgumentNullException(nameof(props)); - string dialectName; - if (props.TryGetValue(Environment.Dialect, out dialectName) == false) + if (props.TryGetValue(Environment.Dialect, out var dialectName) == false) + { + try + { + var dialect = (Dialect) Environment.ServiceProvider.GetService(typeof(Dialect)); + if (dialect != null) + { + return dialect; + } + } + catch (Exception e) + { + throw new HibernateException($"Could not instantiate dialect class {typeof(Dialect)}", e); + } throw new InvalidOperationException("Could not find the dialect in the configuration"); + } if (dialectName == null) { return GetDialect(); @@ -184,7 +197,7 @@ private static Dialect InstantiateDialect(string dialectName, IDictionary properties) { - string registry; - if (properties.TryGetValue(Environment.LinqToHqlGeneratorsRegistry, out registry)) + if (properties.TryGetValue(Environment.LinqToHqlGeneratorsRegistry, out var registry)) { try { log.Info("Initializing LinqToHqlGeneratorsRegistry: {0}", registry); - return (ILinqToHqlGeneratorsRegistry) Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(registry)); + return (ILinqToHqlGeneratorsRegistry) Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(registry)); } catch (Exception e) { @@ -26,7 +25,17 @@ public static ILinqToHqlGeneratorsRegistry CreateGeneratorsRegistry(IDictionary< throw new HibernateException("Could not instantiate LinqToHqlGeneratorsRegistry: " + registry, e); } } - return new DefaultLinqToHqlGeneratorsRegistry(); + try + { + return (ILinqToHqlGeneratorsRegistry) + Environment.ServiceProvider.GetService(typeof(ILinqToHqlGeneratorsRegistry)) ?? + new DefaultLinqToHqlGeneratorsRegistry(); + } + catch (Exception e) + { + log.Fatal(e, "Could not instantiate LinqToHqlGeneratorsRegistry"); + throw new HibernateException($"Could not instantiate LinqToHqlGeneratorsRegistry: {typeof(ILinqToHqlGeneratorsRegistry)}", e); + } } } } diff --git a/src/NHibernate/Mapping/Collection.cs b/src/NHibernate/Mapping/Collection.cs index de4c97a58f2..4fb70edefaf 100644 --- a/src/NHibernate/Mapping/Collection.cs +++ b/src/NHibernate/Mapping/Collection.cs @@ -152,7 +152,7 @@ public object Comparer { try { - comparer = Cfg.Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(ComparerClassName)); + comparer = Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(ComparerClassName)); } catch (Exception ex) { diff --git a/src/NHibernate/Properties/PropertyAccessorFactory.cs b/src/NHibernate/Properties/PropertyAccessorFactory.cs index 4a65b5015bf..a086e9715cd 100644 --- a/src/NHibernate/Properties/PropertyAccessorFactory.cs +++ b/src/NHibernate/Properties/PropertyAccessorFactory.cs @@ -260,7 +260,7 @@ private static IPropertyAccessor ResolveCustomAccessor(string accessorName) try { - var result = (IPropertyAccessor) Cfg.Environment.ObjectsFactory.CreateInstance(accessorClass); + var result = (IPropertyAccessor) Cfg.Environment.ServiceProvider.GetInstance(accessorClass); accessors[accessorName] = result; return result; } diff --git a/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs b/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs index 681a9555f62..ebf2c561158 100644 --- a/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs +++ b/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs @@ -105,7 +105,7 @@ public static void Main(string[] args) { cfg.SetNamingStrategy( (INamingStrategy) - Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs b/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs index cfe3d94ff72..a7935e960e6 100644 --- a/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs +++ b/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs @@ -60,7 +60,7 @@ public static void Main(string[] args) { cfg.SetNamingStrategy( (INamingStrategy) - Cfg.Environment.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Type/CompositeCustomType.cs b/src/NHibernate/Type/CompositeCustomType.cs index 1588ab4cbd7..0f180a10df3 100644 --- a/src/NHibernate/Type/CompositeCustomType.cs +++ b/src/NHibernate/Type/CompositeCustomType.cs @@ -6,6 +6,7 @@ using NHibernate.Engine; using NHibernate.SqlTypes; using NHibernate.UserTypes; +using NHibernate.Util; using System.Collections.Generic; namespace NHibernate.Type @@ -28,7 +29,7 @@ public CompositeCustomType(System.Type userTypeClass, IDictionary paramet try { - userType = (IUserType) Cfg.Environment.ObjectsFactory.CreateInstance(userTypeClass); + userType = (IUserType) Cfg.Environment.ServiceProvider.GetInstance(userTypeClass); } catch (ArgumentNullException ane) { diff --git a/src/NHibernate/Type/TypeFactory.cs b/src/NHibernate/Type/TypeFactory.cs index cd416deddb6..840a4ec5b0b 100644 --- a/src/NHibernate/Type/TypeFactory.cs +++ b/src/NHibernate/Type/TypeFactory.cs @@ -542,7 +542,7 @@ public static IType HeuristicType(string typeName, IDictionary p { try { - type = (IType) Environment.ObjectsFactory.CreateInstance(typeClass); + type = (IType) Environment.ServiceProvider.GetInstance(typeClass); } catch (Exception e) { diff --git a/src/NHibernate/Util/PropertiesHelper.cs b/src/NHibernate/Util/PropertiesHelper.cs index da80f5b0860..1e246c769a9 100644 --- a/src/NHibernate/Util/PropertiesHelper.cs +++ b/src/NHibernate/Util/PropertiesHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NHibernate.Cfg; namespace NHibernate.Util { @@ -75,5 +76,37 @@ public static IDictionary ToDictionary(string property, string d } return map; } + + /// + /// Get an instance of type by using the . + /// + /// The type to instantiate. + /// The configuration property name. + /// The configuration properties. + /// The default type to instantiate. + /// The instance of the type. + public static TService GetInstance(string property, IDictionary properties, System.Type defaultType) + { + var className = GetString(property, properties, null); + try + { + if (className != null) + { + return (TService) Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(className)); + } + + var instance = (TService) Cfg.Environment.ServiceProvider.GetService(typeof(TService)); + if (instance != null) + { + return instance; + } + + return (TService) Cfg.Environment.ServiceProvider.GetInstance(defaultType); + } + catch (Exception e) + { + throw new HibernateException($"could not instantiate {typeof(TService).Name}: {className ?? defaultType.AssemblyQualifiedName}", e); + } + } } } diff --git a/src/NHibernate/Util/ServiceProviderExtensions.cs b/src/NHibernate/Util/ServiceProviderExtensions.cs new file mode 100644 index 00000000000..d00f6bc3843 --- /dev/null +++ b/src/NHibernate/Util/ServiceProviderExtensions.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NHibernate.Util +{ + internal static class ServiceProviderExtensions + { + public static object GetInstance(this IServiceProvider serviceProvider, System.Type serviceType) + { + // 6.0 TODO throw a meaningful exception instead of using the Activator + return serviceProvider.GetService(serviceType) ?? Activator.CreateInstance(serviceType); + } + } +} diff --git a/src/NHibernate/nhibernate-configuration.xsd b/src/NHibernate/nhibernate-configuration.xsd index 1ccdfca4e4d..0f8dec65325 100644 --- a/src/NHibernate/nhibernate-configuration.xsd +++ b/src/NHibernate/nhibernate-configuration.xsd @@ -21,11 +21,11 @@ - + - Specify the AssemblyQualifiedName of your custom objects-factory (implementation of IObjectsFactory). - Note: the objects-factory will be effective only when specified in the app.config or web.config. + Specify the AssemblyQualifiedName of your custom service-provider (implementation of IServiceProvider). + Note: the service-provider will be effective only when specified in the app.config or web.config. @@ -349,7 +349,7 @@ - + From 98485e05d97e3fe331d93a7268e8cd65467130b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 11:20:21 +0200 Subject: [PATCH 02/16] fixup! Replace IObjectsFactory with IServiceProvider interface Fix dropped line --- src/NHibernate/Cfg/SettingsFactory.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NHibernate/Cfg/SettingsFactory.cs b/src/NHibernate/Cfg/SettingsFactory.cs index 39d2a85b9e3..c60efecae5b 100644 --- a/src/NHibernate/Cfg/SettingsFactory.cs +++ b/src/NHibernate/Cfg/SettingsFactory.cs @@ -389,6 +389,7 @@ private static ITransactionFactory CreateTransactionFactory(IDictionary Date: Wed, 1 Aug 2018 12:41:33 +0200 Subject: [PATCH 03/16] fixup! Replace IObjectsFactory with IServiceProvider interface Refactor many instantiations --- src/NHibernate/Cfg/SettingsFactory.cs | 40 ++--------- .../Connection/ConnectionProvider.cs | 35 +++------- .../Connection/ConnectionProviderFactory.cs | 53 ++++----------- src/NHibernate/Dialect/Dialect.cs | 56 ++++----------- .../LinqToHqlGeneratorsRegistryFactory.cs | 31 ++------- src/NHibernate/Util/PropertiesHelper.cs | 68 ++++++++++--------- 6 files changed, 81 insertions(+), 202 deletions(-) diff --git a/src/NHibernate/Cfg/SettingsFactory.cs b/src/NHibernate/Cfg/SettingsFactory.cs index c60efecae5b..6b7caadaff9 100644 --- a/src/NHibernate/Cfg/SettingsFactory.cs +++ b/src/NHibernate/Cfg/SettingsFactory.cs @@ -396,40 +396,12 @@ private static ITransactionFactory CreateTransactionFactory(IDictionary properties) { - var className = PropertiesHelper.GetString(Environment.QueryModelRewriterFactory, properties, null); - - if (className == null) - { - try - { - var instance = - (IQueryModelRewriterFactory) - Environment.ServiceProvider.GetService(typeof(IQueryModelRewriterFactory)); - if (instance == null) - { - return null; - } - log.Info("Query model rewriter factory factory: {0}", instance.GetType().AssemblyQualifiedName); - return instance; - } - catch (Exception cnfe) - { - throw new HibernateException("could not instantiate IQueryModelRewriterFactory", cnfe); - } - } - - log.Info("Query model rewriter factory factory: {0}", className); - - try - { - return - (IQueryModelRewriterFactory) - Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(className)); - } - catch (Exception cnfe) - { - throw new HibernateException("could not instantiate IQueryModelRewriterFactory: " + className, cnfe); - } + var instance = PropertiesHelper.GetInstance( + Environment.QueryModelRewriterFactory, + properties, + null); + log.Info("Query model rewriter factory factory: '{0}'", instance?.GetType().AssemblyQualifiedName ?? "none"); + return instance; } } } diff --git a/src/NHibernate/Connection/ConnectionProvider.cs b/src/NHibernate/Connection/ConnectionProvider.cs index 02509277959..6c0878be702 100644 --- a/src/NHibernate/Connection/ConnectionProvider.cs +++ b/src/NHibernate/Connection/ConnectionProvider.cs @@ -94,35 +94,16 @@ protected virtual string GetNamedConnectionString(IDictionary se /// protected virtual void ConfigureDriver(IDictionary settings) { - if (!settings.TryGetValue(Environment.ConnectionDriver, out var driverClass)) - { - try - { - driver = (IDriver) Environment.ServiceProvider.GetService(typeof(IDriver)); - if (driver != null) - { - driver.Configure(settings); - return; - } - } - catch (Exception e) - { - throw new HibernateException($"Could not create the driver from {typeof(IDriver)}.", e); - } + driver = PropertiesHelper.GetInstance( + Environment.ConnectionDriver, + settings, + null); + if (driver == null) throw new HibernateException( - $"The {Environment.ConnectionDriver} must be specified in the NHibernate configuration section."); - } + $"The {Environment.ConnectionDriver} must be specified in the NHibernate configuration section," + + "or Environment.ServiceProvider must be setup in order to resolve it."); - try - { - driver = - (IDriver) Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(driverClass)); - driver.Configure(settings); - } - catch (Exception e) - { - throw new HibernateException($"Could not create the driver from {driverClass}.", e); - } + driver.Configure(settings); } /// diff --git a/src/NHibernate/Connection/ConnectionProviderFactory.cs b/src/NHibernate/Connection/ConnectionProviderFactory.cs index c976c496cef..9c6a71fb341 100644 --- a/src/NHibernate/Connection/ConnectionProviderFactory.cs +++ b/src/NHibernate/Connection/ConnectionProviderFactory.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using NHibernate.Util; @@ -13,48 +12,20 @@ public static class ConnectionProviderFactory { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ConnectionProviderFactory)); - // cannot be instantiated public static IConnectionProvider NewConnectionProvider(IDictionary settings) { - IConnectionProvider connections; - if (settings.TryGetValue(Environment.ConnectionProvider, out var providerClass)) - { - try - { - log.Info("Initializing connection provider: {0}", providerClass); - connections = - (IConnectionProvider) - Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(providerClass)); - } - catch (Exception e) - { - log.Fatal(e, "Could not instantiate connection provider"); - throw new HibernateException("Could not instantiate connection provider: " + providerClass, e); - } - } - else if (settings.ContainsKey(Environment.ConnectionString) || settings.ContainsKey(Environment.ConnectionStringName)) - { - connections = new DriverConnectionProvider(); - } - else - { - try - { - connections = (IConnectionProvider) Environment.ServiceProvider.GetService(typeof(IConnectionProvider)); - } - catch (Exception e) - { - log.Fatal(e, "Could not instantiate connection provider"); - throw new HibernateException($"Could not instantiate connection provider: {typeof(IConnectionProvider)}", e); - } - if (connections == null) - { - log.Info("No connection provider specified, UserSuppliedConnectionProvider will be used."); - connections = new UserSuppliedConnectionProvider(); - } - } - connections.Configure(settings); - return connections; + var defaultConnectionProvider = + settings.ContainsKey(Environment.ConnectionString) || + settings.ContainsKey(Environment.ConnectionStringName) + ? typeof(DriverConnectionProvider) + : typeof(UserSuppliedConnectionProvider); + var connectionProvider = PropertiesHelper.GetInstance( + Environment.ConnectionProvider, + settings, + defaultConnectionProvider); + log.Info("Connection provider: '{0}'", connectionProvider.GetType().AssemblyQualifiedName); + connectionProvider.Configure(settings); + return connectionProvider; } } } diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs index 684c3da679f..93577b7ffbd 100644 --- a/src/NHibernate/Dialect/Dialect.cs +++ b/src/NHibernate/Dialect/Dialect.cs @@ -146,16 +146,7 @@ protected Dialect() /// The specified Dialect public static Dialect GetDialect() { - string dialectName; - try - { - dialectName = Environment.Properties[Environment.Dialect]; - } - catch (Exception e) - { - throw new HibernateException("The dialect was not set. Set the property 'dialect'.", e); - } - return InstantiateDialect(dialectName, Environment.Properties); + return GetDialect(Environment.Properties); } /// @@ -169,42 +160,19 @@ public static Dialect GetDialect(IDictionary props) { if (props == null) throw new ArgumentNullException(nameof(props)); - if (props.TryGetValue(Environment.Dialect, out var dialectName) == false) - { - try - { - var dialect = (Dialect) Environment.ServiceProvider.GetService(typeof(Dialect)); - if (dialect != null) - { - return dialect; - } - } - catch (Exception e) - { - throw new HibernateException($"Could not instantiate dialect class {typeof(Dialect)}", e); - } + if (props.TryGetValue(Environment.Dialect, out var dialectName) && dialectName == null) + props = Environment.Properties; + + var dialect = PropertiesHelper.GetInstance( + Environment.Dialect, + props, + null); + + if (dialect == null) throw new InvalidOperationException("Could not find the dialect in the configuration"); - } - if (dialectName == null) - { - return GetDialect(); - } - - return InstantiateDialect(dialectName, props); - } - private static Dialect InstantiateDialect(string dialectName, IDictionary props) - { - try - { - var dialect = (Dialect) Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(dialectName)); - dialect.Configure(props); - return dialect; - } - catch (Exception e) - { - throw new HibernateException("Could not instantiate dialect class " + dialectName, e); - } + dialect.Configure(props); + return dialect; } /// diff --git a/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryFactory.cs b/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryFactory.cs index 84b00a8bd09..f30960cb2a1 100644 --- a/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryFactory.cs +++ b/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryFactory.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using NHibernate.Util; @@ -12,30 +11,12 @@ public sealed class LinqToHqlGeneratorsRegistryFactory public static ILinqToHqlGeneratorsRegistry CreateGeneratorsRegistry(IDictionary properties) { - if (properties.TryGetValue(Environment.LinqToHqlGeneratorsRegistry, out var registry)) - { - try - { - log.Info("Initializing LinqToHqlGeneratorsRegistry: {0}", registry); - return (ILinqToHqlGeneratorsRegistry) Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(registry)); - } - catch (Exception e) - { - log.Fatal(e, "Could not instantiate LinqToHqlGeneratorsRegistry"); - throw new HibernateException("Could not instantiate LinqToHqlGeneratorsRegistry: " + registry, e); - } - } - try - { - return (ILinqToHqlGeneratorsRegistry) - Environment.ServiceProvider.GetService(typeof(ILinqToHqlGeneratorsRegistry)) ?? - new DefaultLinqToHqlGeneratorsRegistry(); - } - catch (Exception e) - { - log.Fatal(e, "Could not instantiate LinqToHqlGeneratorsRegistry"); - throw new HibernateException($"Could not instantiate LinqToHqlGeneratorsRegistry: {typeof(ILinqToHqlGeneratorsRegistry)}", e); - } + var instance = PropertiesHelper.GetInstance( + Environment.LinqToHqlGeneratorsRegistry, + properties, + typeof(DefaultLinqToHqlGeneratorsRegistry)); + log.Info("LinqToHqlGeneratorsRegistry: '{0}'", instance.GetType().AssemblyQualifiedName); + return instance; } } } diff --git a/src/NHibernate/Util/PropertiesHelper.cs b/src/NHibernate/Util/PropertiesHelper.cs index 1e246c769a9..f7a1f860e14 100644 --- a/src/NHibernate/Util/PropertiesHelper.cs +++ b/src/NHibernate/Util/PropertiesHelper.cs @@ -10,10 +10,10 @@ public static class PropertiesHelper { public static bool GetBoolean(string property, IDictionary properties, bool defaultValue) { - string toParse; - properties.TryGetValue(property, out toParse); - bool result; - return bool.TryParse(toParse, out result) ? result : defaultValue; + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + properties.TryGetValue(property, out var toParse); + return bool.TryParse(toParse, out var result) ? result : defaultValue; } public static bool GetBoolean(string property, IDictionary properties) @@ -23,33 +23,34 @@ public static bool GetBoolean(string property, IDictionary prope public static byte? GetByte(string property, IDictionary properties, byte? defaultValue) { - string toParse; - properties.TryGetValue(property, out toParse); - byte result; - return byte.TryParse(toParse, out result) ? result : defaultValue; + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + properties.TryGetValue(property, out var toParse); + return byte.TryParse(toParse, out var result) ? result : defaultValue; } public static int GetInt32(string property, IDictionary properties, int defaultValue) { - string toParse; - properties.TryGetValue(property, out toParse); - int result; - return int.TryParse(toParse, out result) ? result : defaultValue; + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + properties.TryGetValue(property, out var toParse); + return int.TryParse(toParse, out var result) ? result : defaultValue; } public static long GetInt64(string property, IDictionary properties, long defaultValue) { - string toParse; - properties.TryGetValue(property, out toParse); - long result; - return long.TryParse(toParse, out result) ? result : defaultValue; + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + properties.TryGetValue(property, out var toParse); + return long.TryParse(toParse, out var result) ? result : defaultValue; } public static string GetString(string property, IDictionary properties, string defaultValue) { - string value; - properties.TryGetValue(property, out value); - if(value == string.Empty) + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + properties.TryGetValue(property, out var value); + if (value == string.Empty) { value = null; } @@ -58,10 +59,11 @@ public static string GetString(string property, IDictionary prop public static IDictionary ToDictionary(string property, string delim, IDictionary properties) { - IDictionary map = new Dictionary(); + if (properties == null) + throw new ArgumentNullException(nameof(properties)); + var map = new Dictionary(); - string propValue; - if (properties.TryGetValue(property, out propValue)) + if (properties.TryGetValue(property, out var propValue)) { var tokens = new StringTokenizer(propValue, delim, false); using (var en = tokens.GetEnumerator()) @@ -84,28 +86,32 @@ public static IDictionary ToDictionary(string property, string d /// The configuration property name. /// The configuration properties. /// The default type to instantiate. - /// The instance of the type. - public static TService GetInstance(string property, IDictionary properties, System.Type defaultType) + /// The instance of the type, or if none is + /// configured and is . + public static TService GetInstance( + string property, IDictionary properties, System.Type defaultType) where TService : class { var className = GetString(property, properties, null); + System.Type type = null; try { - if (className != null) - { - return (TService) Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(className)); - } + type = className != null + ? ReflectHelper.ClassForName(className) + : typeof(TService); - var instance = (TService) Cfg.Environment.ServiceProvider.GetService(typeof(TService)); + var instance = (TService) Cfg.Environment.ServiceProvider.GetService(type); if (instance != null) { return instance; } - return (TService) Cfg.Environment.ServiceProvider.GetInstance(defaultType); + type = defaultType; + return defaultType != null ? (TService) Cfg.Environment.ServiceProvider.GetInstance(defaultType) : null; } catch (Exception e) { - throw new HibernateException($"could not instantiate {typeof(TService).Name}: {className ?? defaultType.AssemblyQualifiedName}", e); + throw new HibernateException( + $"Could not instantiate {typeof(TService).Name}: {type?.AssemblyQualifiedName ?? className}", e); } } } From ae4d2b4835977f6a8739c0834b35ff469dfda4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 12:47:30 +0200 Subject: [PATCH 04/16] fixup! Replace IObjectsFactory with IServiceProvider interface Remove undue warning deactivation --- src/NHibernate/Bytecode/ActivatorObjectsFactory.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs b/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs index 8b087ccaff8..d95016d65db 100644 --- a/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs +++ b/src/NHibernate/Bytecode/ActivatorObjectsFactory.cs @@ -4,10 +4,7 @@ namespace NHibernate.Bytecode { // Since v5.2 [Obsolete("This type has no more usages and will be removed in a future version")] - public class ActivatorObjectsFactory : -#pragma warning disable 618 - IObjectsFactory -#pragma warning restore 618 + public class ActivatorObjectsFactory : IObjectsFactory { public object CreateInstance(System.Type type) { From c52ec3b0a3b5d6565d75bf37c8c15318eb18c438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 12:59:32 +0200 Subject: [PATCH 05/16] fixup! Replace IObjectsFactory with IServiceProvider interface Avoid a possible breaking change --- src/NHibernate/Cfg/Environment.cs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/NHibernate/Cfg/Environment.cs b/src/NHibernate/Cfg/Environment.cs index e5462edd030..10efd567a3f 100644 --- a/src/NHibernate/Cfg/Environment.cs +++ b/src/NHibernate/Cfg/Environment.cs @@ -388,7 +388,35 @@ public static IDictionary Properties public static IBytecodeProvider BytecodeProvider { get { return BytecodeProviderInstance; } - set { BytecodeProviderInstance = value; } + set + { + BytecodeProviderInstance = value; + + // 6.0 TODO: remove following code. +#pragma warning disable 618 + var objectsFactory = BytecodeProviderInstance.ObjectsFactory; + if (objectsFactory != null && !(objectsFactory is ActivatorObjectsFactory)) + ServiceProvider = new ObjectsFactoryWrapper(objectsFactory); +#pragma warning restore 618 + } + } + + // Since its creation + [Obsolete("Transition class")] + private class ObjectsFactoryWrapper : IServiceProvider + { + private readonly IObjectsFactory _objectsFactory; + public ObjectsFactoryWrapper(IObjectsFactory objectsFactory) + { + _objectsFactory = objectsFactory; + } + + public object GetService(System.Type serviceType) + { + if (serviceType.IsAbstract || serviceType.IsInterface) + return null; + return _objectsFactory.CreateInstance(serviceType); + } } /// From d72268fabc58d982c004f97b16bb5679a02e95c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 13:01:23 +0200 Subject: [PATCH 06/16] fixup! Replace IObjectsFactory with IServiceProvider interface Avoid corrupting following tests in case of failure --- .../Async/CfgTest/SettingsFactoryFixture.cs | 18 +++++++++++++---- .../CfgTest/SettingsFactoryFixture.cs | 20 ++++++++++++------- .../UtilityTest/PropertiesHelperTest.cs | 20 ++++++++++++++----- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs index 7a16087d09c..1d714cf1af5 100644 --- a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs @@ -50,8 +50,6 @@ private Task InvalidRegisteredServiceAsync() { try { - var originalSp = Environment.ServiceProvider; - var sp = new DefaultServiceProvider(); sp.Register(() => throw new InvalidOperationException()); @@ -69,8 +67,6 @@ private Task InvalidRegisteredServiceAsync() Assert.Throws( () => new SettingsFactory().BuildSettings(properties), $"HibernateException should be thrown for service {typeof(TService)}"); - - Environment.ServiceProvider = originalSp; return Task.CompletedTask; } catch (Exception ex) @@ -78,5 +74,19 @@ private Task InvalidRegisteredServiceAsync() return Task.FromException(ex); } } + + private IServiceProvider _originalSp; + + [SetUp] + public void Setup() + { + _originalSp = Environment.ServiceProvider; + } + + [TearDown] + public void TearDown() + { + Environment.ServiceProvider = _originalSp; + } } } diff --git a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs index 102e1588a0d..455fcfe7fdc 100644 --- a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs @@ -57,8 +57,6 @@ public void DefaultServices() [Test] public void RegisteredServices() { - var originalSp = Environment.ServiceProvider; - var batcherFactory = Substitute.For(); var cacheProvider = Substitute.For(); var connectionProvider = Substitute.For(); @@ -99,8 +97,6 @@ public void RegisteredServices() Assert.That(settings.QueryTranslatorFactory, Is.EqualTo(queryTranslatorFactory)); Assert.That(settings.SqlExceptionConverter, Is.EqualTo(sqlExceptionConverter)); Assert.That(settings.TransactionFactory, Is.EqualTo(transactionFactory)); - - Environment.ServiceProvider = originalSp; } [Test] @@ -119,8 +115,6 @@ public void InvalidRegisteredServices() private void InvalidRegisteredService() { - var originalSp = Environment.ServiceProvider; - var sp = new DefaultServiceProvider(); sp.Register(() => throw new InvalidOperationException()); @@ -138,8 +132,20 @@ private void InvalidRegisteredService() Assert.Throws( () => new SettingsFactory().BuildSettings(properties), $"HibernateException should be thrown for service {typeof(TService)}"); + } + + private IServiceProvider _originalSp; - Environment.ServiceProvider = originalSp; + [SetUp] + public void Setup() + { + _originalSp = Environment.ServiceProvider; + } + + [TearDown] + public void TearDown() + { + Environment.ServiceProvider = _originalSp; } } } diff --git a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs index cb3bec4627a..05eaad1f831 100644 --- a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs +++ b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using NHibernate.Bytecode; using NHibernate.Connection; @@ -59,7 +60,6 @@ public void GetInstanceByDefault() [Test] public void GetInstanceByRegistration() { - var originalSp = Cfg.Environment.ServiceProvider; var sp = new DefaultServiceProvider(); sp.Register(); Cfg.Environment.ServiceProvider = sp; @@ -69,8 +69,6 @@ public void GetInstanceByRegistration() typeof(DebugConnectionProvider)); Assert.That(instance, Is.Not.Null); Assert.That(instance, Is.TypeOf()); - - Cfg.Environment.ServiceProvider = originalSp; } [Test] @@ -100,7 +98,6 @@ public void GetInstanceByInvalidDefault() [Test] public void GetInstanceByInvalidRegistration() { - var originalSp = Cfg.Environment.ServiceProvider; var sp = new DefaultServiceProvider(); sp.Register(typeof(IConnectionProvider), () => new PropertiesHelperTest()); Cfg.Environment.ServiceProvider = sp; @@ -112,7 +109,6 @@ public void GetInstanceByInvalidRegistration() new Dictionary(), typeof(DriverConnectionProvider)); }); - Cfg.Environment.ServiceProvider = originalSp; } [Test] @@ -127,5 +123,19 @@ public void GetInstanceByInvalidProperty() typeof(DriverConnectionProvider)); }); } + + private IServiceProvider _originalSp; + + [SetUp] + public void Setup() + { + _originalSp = Cfg.Environment.ServiceProvider; + } + + [TearDown] + public void TearDown() + { + Cfg.Environment.ServiceProvider = _originalSp; + } } } From 131830b43d35afc502952afa87f2700f8a749cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 13:02:52 +0200 Subject: [PATCH 07/16] fixup! Replace IObjectsFactory with IServiceProvider interface Keep tests for an obsolete class, till it gets dropped --- .../Bytecode/ActivatorObjectFactoryFixture.cs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs diff --git a/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs b/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs new file mode 100644 index 00000000000..513b02ea34f --- /dev/null +++ b/src/NHibernate.Test/Bytecode/ActivatorObjectFactoryFixture.cs @@ -0,0 +1,79 @@ +using System; +using NHibernate.Bytecode; +using NUnit.Framework; + +namespace NHibernate.Test.Bytecode +{ + [TestFixture, Obsolete] + public class ActivatorObjectFactoryFixture + { + public class WithOutPublicParameterLessCtor + { + public string Something { get; set; } + protected WithOutPublicParameterLessCtor() { } + + public WithOutPublicParameterLessCtor(string something) + { + Something = something; + } + } + + public class PublicParameterLessCtor + { + } + + public struct ValueType + { + public string Something { get; set; } + } + + protected virtual IObjectsFactory GetObjectsFactory() + { + return new ActivatorObjectsFactory(); + } + + [Test] + public void CreateInstanceDefCtor() + { + IObjectsFactory of = GetObjectsFactory(); + Assert.Throws(() => of.CreateInstance(null)); + Assert.Throws(() => of.CreateInstance(typeof(WithOutPublicParameterLessCtor))); + var instance = of.CreateInstance(typeof(PublicParameterLessCtor)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + } + + + + [Test, Obsolete] + public void CreateInstanceWithNoPublicCtor() + { + IObjectsFactory of = GetObjectsFactory(); + Assert.Throws(() => of.CreateInstance(null, false)); + var instance = of.CreateInstance(typeof(WithOutPublicParameterLessCtor), true); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + } + + [Test, Obsolete] + public void CreateInstanceOfValueType() + { + IObjectsFactory of = GetObjectsFactory(); + var instance = of.CreateInstance(typeof(ValueType), true); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + } + + [Test, Obsolete] + public void CreateInstanceWithArguments() + { + IObjectsFactory of = GetObjectsFactory(); + Assert.Throws(() => of.CreateInstance(null, new[] {1})); + var value = "a value"; + var instance = of.CreateInstance(typeof(WithOutPublicParameterLessCtor), new[]{value}); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + Assert.That(((WithOutPublicParameterLessCtor)instance).Something, Is.EqualTo(value)); + } + } +} From 79b5c5a36fb932b5c5b58c194d00c0b2c18d51f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 13:12:09 +0200 Subject: [PATCH 08/16] fixup! Replace IObjectsFactory with IServiceProvider interface Fix regression: must use GetService instead of GetInstance for ICurrentSessionContext, since it is optional and GetInstance does not support it. --- src/NHibernate/Impl/SessionFactoryImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Impl/SessionFactoryImpl.cs b/src/NHibernate/Impl/SessionFactoryImpl.cs index dc6f1c7999b..672fa9b5a4c 100644 --- a/src/NHibernate/Impl/SessionFactoryImpl.cs +++ b/src/NHibernate/Impl/SessionFactoryImpl.cs @@ -1290,7 +1290,7 @@ private ICurrentSessionContext BuildCurrentSessionContext() } else { - context = (ICurrentSessionContext) Environment.ServiceProvider.GetInstance( + context = (ICurrentSessionContext) Environment.ServiceProvider.GetService( implClass ?? typeof(ICurrentSessionContext)); } if (context is ISessionFactoryAwareCurrentSessionContext sessionFactoryAwareContext) From e61274a6465b3d787b411384379d6e0f29e44381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 1 Aug 2018 13:19:01 +0200 Subject: [PATCH 09/16] fixup! Replace IObjectsFactory with IServiceProvider interface Throw explicitly on an error case. --- .../Util/ServiceProviderExtensions.cs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/NHibernate/Util/ServiceProviderExtensions.cs b/src/NHibernate/Util/ServiceProviderExtensions.cs index d00f6bc3843..730b34a80f7 100644 --- a/src/NHibernate/Util/ServiceProviderExtensions.cs +++ b/src/NHibernate/Util/ServiceProviderExtensions.cs @@ -1,17 +1,28 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using NHibernate.Bytecode; namespace NHibernate.Util { internal static class ServiceProviderExtensions { + /// + /// Get a service, throwing if it cannot be resolved. + /// + /// The service provider. + /// The service interface, base class or concrete implementation class. + /// The service instance. + /// thrown if is . + /// thrown if the service cannot be resolved. public static object GetInstance(this IServiceProvider serviceProvider, System.Type serviceType) { - // 6.0 TODO throw a meaningful exception instead of using the Activator - return serviceProvider.GetService(serviceType) ?? Activator.CreateInstance(serviceType); + if (serviceType == null) + throw new ArgumentNullException(nameof(serviceType)); + var service = serviceProvider.GetService(serviceType); + + if (service == null) + throw new HibernateServiceProviderException( + $"Unable to resolve an instance for {serviceType.AssemblyQualifiedName}"); + return service; } } } From 2b2950c063215b971566391fab816ed02b05d2f6 Mon Sep 17 00:00:00 2001 From: maca88 Date: Fri, 3 Aug 2018 21:07:58 +0200 Subject: [PATCH 10/16] Removed registration logic from DefaultServiceProvider and renamed it to ActivatorServiceProvider --- .../Async/CfgTest/SettingsFactoryFixture.cs | 2 +- .../ActivatorServiceProviderFixture.cs | 41 ++++++++++ .../Bytecode/DefaultServiceProviderFixture.cs | 75 ------------------- .../CfgTest/SettingsFactoryFixture.cs | 4 +- .../CfgTest/SimpleServiceProvider.cs} | 8 +- .../UtilityTest/PropertiesHelperTest.cs | 5 +- .../Bytecode/ActivatorServiceProvider.cs | 32 ++++++++ src/NHibernate/Cfg/Environment.cs | 4 +- 8 files changed, 83 insertions(+), 88 deletions(-) create mode 100644 src/NHibernate.Test/Bytecode/ActivatorServiceProviderFixture.cs delete mode 100644 src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs rename src/{NHibernate/Bytecode/DefaultServiceProvider.cs => NHibernate.Test/CfgTest/SimpleServiceProvider.cs} (93%) create mode 100644 src/NHibernate/Bytecode/ActivatorServiceProvider.cs diff --git a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs index 1d714cf1af5..d28fee05b34 100644 --- a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs @@ -50,7 +50,7 @@ private Task InvalidRegisteredServiceAsync() { try { - var sp = new DefaultServiceProvider(); + var sp = new SimpleServiceProvider(); sp.Register(() => throw new InvalidOperationException()); Environment.ServiceProvider = sp; diff --git a/src/NHibernate.Test/Bytecode/ActivatorServiceProviderFixture.cs b/src/NHibernate.Test/Bytecode/ActivatorServiceProviderFixture.cs new file mode 100644 index 00000000000..7fa3fb633c8 --- /dev/null +++ b/src/NHibernate.Test/Bytecode/ActivatorServiceProviderFixture.cs @@ -0,0 +1,41 @@ +using System; +using NHibernate.Bytecode; +using NUnit.Framework; + +namespace NHibernate.Test.Bytecode +{ + [TestFixture] + public class ActivatorServiceProviderFixture + { + public class WithOutPublicParameterLessCtor + { + public string Something { get; set; } + protected WithOutPublicParameterLessCtor() { } + + public WithOutPublicParameterLessCtor(string something) + { + Something = something; + } + } + + public class PublicParameterLessCtor + { + } + + protected virtual IServiceProvider GetServiceProvider() + { + return new ActivatorServiceProvider(); + } + + [Test] + public void CreateInstanceDefCtor() + { + var sp = GetServiceProvider(); + Assert.Throws(() => sp.GetService(null)); + Assert.Throws(() => sp.GetService(typeof(WithOutPublicParameterLessCtor))); + var instance = sp.GetService(typeof(PublicParameterLessCtor)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.InstanceOf()); + } + } +} diff --git a/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs b/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs deleted file mode 100644 index 0472d6cbed5..00000000000 --- a/src/NHibernate.Test/Bytecode/DefaultServiceProviderFixture.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using NHibernate.Bytecode; -using NUnit.Framework; - -namespace NHibernate.Test.Bytecode -{ - [TestFixture] - public class DefaultServiceProviderFixture - { - public class WithOutPublicParameterLessCtor - { - public string Something { get; set; } - protected WithOutPublicParameterLessCtor() { } - - public WithOutPublicParameterLessCtor(string something) - { - Something = something; - } - } - - public class PublicParameterLessCtor - { - } - - protected virtual IServiceProvider GetServiceProvider() - { - return new DefaultServiceProvider(); - } - - [Test] - public void CreateInstanceDefCtor() - { - var sp = GetServiceProvider(); - Assert.Throws(() => sp.GetService(null)); - Assert.Throws(() => sp.GetService(typeof(WithOutPublicParameterLessCtor))); - var instance = sp.GetService(typeof(PublicParameterLessCtor)); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - } - - - [Test] - public void RegisterService() - { - var sp = new DefaultServiceProvider(); - - Assert.That(sp.GetService(typeof(IInterceptor)), Is.Null); - - sp.Register(); - var instance = sp.GetService(typeof(IInterceptor)); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - - Assert.Throws(() => sp.Register(), "service should not be registered twice."); - Assert.Throws(() => sp.Register(), "non concrete implementation type should not be permitted."); - Assert.Throws(() => sp.Register(typeof(Dialect.Dialect), typeof(EmptyInterceptor)), "concrete implementation type should derive from service type."); - } - - [Test] - public void RegisterServiceCreator() - { - var sp = new DefaultServiceProvider(); - - Assert.That(sp.GetService(typeof(IInterceptor)), Is.Null); - - sp.Register(() => new EmptyInterceptor()); - var instance = sp.GetService(typeof(IInterceptor)); - Assert.That(instance, Is.Not.Null); - Assert.That(instance, Is.InstanceOf()); - - Assert.Throws(() => sp.Register(() => new EmptyInterceptor()), "service should not be registered twice."); - } - - } -} diff --git a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs index 455fcfe7fdc..ca863ab91e3 100644 --- a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs @@ -68,7 +68,7 @@ public void RegisteredServices() var sqlExceptionConverter = Substitute.For(); var transactionFactory = Substitute.For(); - var sp = new DefaultServiceProvider(); + var sp = new SimpleServiceProvider(); sp.Register(() => batcherFactory); sp.Register(() => cacheProvider); sp.Register(() => connectionProvider); @@ -115,7 +115,7 @@ public void InvalidRegisteredServices() private void InvalidRegisteredService() { - var sp = new DefaultServiceProvider(); + var sp = new SimpleServiceProvider(); sp.Register(() => throw new InvalidOperationException()); Environment.ServiceProvider = sp; diff --git a/src/NHibernate/Bytecode/DefaultServiceProvider.cs b/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs similarity index 93% rename from src/NHibernate/Bytecode/DefaultServiceProvider.cs rename to src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs index 3028c74b7da..cc9691be83f 100644 --- a/src/NHibernate/Bytecode/DefaultServiceProvider.cs +++ b/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs @@ -5,13 +5,9 @@ using System.Text; using System.Threading.Tasks; -namespace NHibernate.Bytecode +namespace NHibernate.Test.CfgTest { - /// - /// The default NHibernate service provider that uses to instantiate - /// services by default. - /// - public class DefaultServiceProvider : IServiceProvider + public class SimpleServiceProvider : IServiceProvider { private readonly ConcurrentDictionary> _registeredTypeProviders = new ConcurrentDictionary>(); diff --git a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs index 05eaad1f831..91a557a63c3 100644 --- a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs +++ b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NHibernate.Bytecode; using NHibernate.Connection; +using NHibernate.Test.CfgTest; using NHibernate.Util; using NUnit.Framework; @@ -60,7 +61,7 @@ public void GetInstanceByDefault() [Test] public void GetInstanceByRegistration() { - var sp = new DefaultServiceProvider(); + var sp = new SimpleServiceProvider(); sp.Register(); Cfg.Environment.ServiceProvider = sp; var instance = PropertiesHelper.GetInstance( @@ -98,7 +99,7 @@ public void GetInstanceByInvalidDefault() [Test] public void GetInstanceByInvalidRegistration() { - var sp = new DefaultServiceProvider(); + var sp = new SimpleServiceProvider(); sp.Register(typeof(IConnectionProvider), () => new PropertiesHelperTest()); Cfg.Environment.ServiceProvider = sp; Assert.Throws( diff --git a/src/NHibernate/Bytecode/ActivatorServiceProvider.cs b/src/NHibernate/Bytecode/ActivatorServiceProvider.cs new file mode 100644 index 00000000000..caa699bef5d --- /dev/null +++ b/src/NHibernate/Bytecode/ActivatorServiceProvider.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NHibernate.Bytecode +{ + /// + /// The default NHibernate service provider that uses to instantiate + /// services. + /// + public class ActivatorServiceProvider : IServiceProvider + { + /// + public object GetService(System.Type serviceType) + { + if (serviceType == null) + { + throw new ArgumentNullException(nameof(serviceType)); + } + + if (serviceType.IsInterface || serviceType.IsAbstract) + { + return null; + } + + return Activator.CreateInstance(serviceType); + } + } +} diff --git a/src/NHibernate/Cfg/Environment.cs b/src/NHibernate/Cfg/Environment.cs index 10efd567a3f..6db6b0f23fd 100644 --- a/src/NHibernate/Cfg/Environment.cs +++ b/src/NHibernate/Cfg/Environment.cs @@ -432,7 +432,7 @@ public object GetService(System.Type serviceType) /// is created, otherwise the change may not take effect. /// For entities see and its implementations. /// - public static IServiceProvider ServiceProvider { get; set; } = new DefaultServiceProvider(); + public static IServiceProvider ServiceProvider { get; set; } = new ActivatorServiceProvider(); /// /// Whether to enable the use of reflection optimizer @@ -478,7 +478,7 @@ public static IServiceProvider BuildServiceProvider(IDictionary var typeAssemblyQualifiedName = PropertiesHelper.GetString(PropertyServiceProvider, properties, null); if (typeAssemblyQualifiedName == null) { - var serviceProvider = new DefaultServiceProvider(); + var serviceProvider = new ActivatorServiceProvider(); log.Info("Service provider class : {0}", serviceProvider.GetType()); return serviceProvider; } From b25693756031577aee8961b7a341b1a34de3031e Mon Sep 17 00:00:00 2001 From: maca88 Date: Sat, 4 Aug 2018 17:40:18 +0200 Subject: [PATCH 11/16] Added a fallback mechanism for internal types when the IoC container requires an explicit registration for concrete types --- .../CfgTest/SettingsFactoryFixture.cs | 7 ++ .../CfgTest/SimpleServiceProvider.cs | 13 ++- .../UtilityTest/PropertiesHelperTest.cs | 110 +++++++++++++++++- src/NHibernate/Util/PropertiesHelper.cs | 10 +- .../Util/ServiceProviderExtensions.cs | 29 ++++- 5 files changed, 158 insertions(+), 11 deletions(-) diff --git a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs index ca863ab91e3..f9bc66f579c 100644 --- a/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/CfgTest/SettingsFactoryFixture.cs @@ -32,6 +32,13 @@ public void DefaultValueForKeyWords() Assert.That(!settings.IsAutoQuoteEnabled); } + [Test] + public void DefaultServicesWithExplicitServiceProvider() + { + Environment.ServiceProvider = new SimpleServiceProvider(true); + DefaultServices(); + } + [Test] public void DefaultServices() { diff --git a/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs b/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs index cc9691be83f..9d35f38de3b 100644 --- a/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs +++ b/src/NHibernate.Test/CfgTest/SimpleServiceProvider.cs @@ -11,6 +11,17 @@ public class SimpleServiceProvider : IServiceProvider { private readonly ConcurrentDictionary> _registeredTypeProviders = new ConcurrentDictionary>(); + private readonly bool _explicit; + + public SimpleServiceProvider() + { + + } + + public SimpleServiceProvider(bool @explicit) + { + _explicit = @explicit; + } /// public object GetService(System.Type serviceType) @@ -25,7 +36,7 @@ public object GetService(System.Type serviceType) return serviceProvider(); } - if (serviceType.IsInterface || serviceType.IsAbstract) + if (_explicit || serviceType.IsInterface || serviceType.IsAbstract) { return null; } diff --git a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs index 91a557a63c3..c005ca50937 100644 --- a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs +++ b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NHibernate.Bytecode; using NHibernate.Connection; +using NHibernate.Linq.Functions; using NHibernate.Test.CfgTest; using NHibernate.Util; using NUnit.Framework; @@ -58,6 +59,42 @@ public void GetInstanceByDefault() Assert.That(instance, Is.TypeOf()); } + [Test] + public void GetInstanceByDefaultNull() + { + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + null); + Assert.That(instance, Is.Null); + } + + [Test] + public void GetInstanceByDefaultWithExplicitServiceProvider() + { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DriverConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); + } + + [Test] + public void GetExternalInstanceByDefaultWithExplicitServiceProvider() + { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DebugConnectionProvider)); + }); + } + [Test] public void GetInstanceByRegistration() { @@ -77,12 +114,38 @@ public void GetInstanceByProperty() { var instance = PropertiesHelper.GetInstance( "conn", - new Dictionary {{ "conn", typeof(DriverConnectionProvider).AssemblyQualifiedName } }, + new Dictionary {{"conn", typeof(DriverConnectionProvider).AssemblyQualifiedName}}, + typeof(DebugConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); + } + + [Test] + public void GetInstanceByPropertyWithExplicitServiceProvider() + { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(DriverConnectionProvider).AssemblyQualifiedName}}, typeof(DebugConnectionProvider)); Assert.That(instance, Is.Not.Null); Assert.That(instance, Is.TypeOf()); } + [Test] + public void GetExternalInstanceByPropertyWithExplicitServiceProvider() + { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(DebugConnectionProvider).AssemblyQualifiedName}}, + typeof(DriverConnectionProvider)); + }); + } + [Test] public void GetInstanceByInvalidDefault() { @@ -113,14 +176,55 @@ public void GetInstanceByInvalidRegistration() } [Test] - public void GetInstanceByInvalidProperty() + public void GetInstanceByInvalidPropertyClassType() + { + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(DefaultLinqToHqlGeneratorsRegistry).AssemblyQualifiedName}}, + typeof(DriverConnectionProvider)); + }); + } + + [Test] + public void GetInstanceByInvalidPropertyClassTypeWithExplicitServiceProvider() + { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(DefaultLinqToHqlGeneratorsRegistry).AssemblyQualifiedName}}, + typeof(DriverConnectionProvider)); + }); + } + + [Test] + public void GetInstanceByInvalidPropertyClassName() + { + Assert.Throws( + () => + { + PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", "test"}}, + typeof(DriverConnectionProvider)); + }); + } + + [Test] + public void GetInstanceByInvalidPropertyClassNameWithExplicitServiceProvider() { + Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); Assert.Throws( () => { PropertiesHelper.GetInstance( "conn", - new Dictionary {{"conn", typeof(PropertiesHelperTest).AssemblyQualifiedName}}, + new Dictionary {{"conn", "test"}}, typeof(DriverConnectionProvider)); }); } diff --git a/src/NHibernate/Util/PropertiesHelper.cs b/src/NHibernate/Util/PropertiesHelper.cs index f7a1f860e14..c7bfd730694 100644 --- a/src/NHibernate/Util/PropertiesHelper.cs +++ b/src/NHibernate/Util/PropertiesHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NHibernate.Bytecode; using NHibernate.Cfg; namespace NHibernate.Util @@ -95,10 +96,13 @@ public static TService GetInstance( System.Type type = null; try { - type = className != null - ? ReflectHelper.ClassForName(className) - : typeof(TService); + if (className != null) + { + type = ReflectHelper.ClassForName(className); + return (TService) Cfg.Environment.ServiceProvider.GetInstance(type); + } + type = typeof(TService); var instance = (TService) Cfg.Environment.ServiceProvider.GetService(type); if (instance != null) { diff --git a/src/NHibernate/Util/ServiceProviderExtensions.cs b/src/NHibernate/Util/ServiceProviderExtensions.cs index 730b34a80f7..17821a7b594 100644 --- a/src/NHibernate/Util/ServiceProviderExtensions.cs +++ b/src/NHibernate/Util/ServiceProviderExtensions.cs @@ -1,10 +1,13 @@ using System; +using System.Reflection; using NHibernate.Bytecode; namespace NHibernate.Util { internal static class ServiceProviderExtensions { + private static readonly string InternalAssemblyName = typeof(ServiceProviderExtensions).Assembly.GetName().ToString(); + /// /// Get a service, throwing if it cannot be resolved. /// @@ -18,11 +21,29 @@ public static object GetInstance(this IServiceProvider serviceProvider, System.T if (serviceType == null) throw new ArgumentNullException(nameof(serviceType)); var service = serviceProvider.GetService(serviceType); + if (service != null) + { + return service; + } + + // Some IoC containers require explicit registration for concete types. In order to avoid registering all NHibernate types + // the Activator.CreateInstance is used for internal types, but the strictness is respected for external types. + Exception innerException = null; + if (serviceType.IsClass && !serviceType.IsAbstract && InternalAssemblyName.Equals(serviceType.Assembly.GetName().ToString())) + { + try + { + return Activator.CreateInstance(serviceType); + } + catch (Exception e) + { + innerException = e; + } + } - if (service == null) - throw new HibernateServiceProviderException( - $"Unable to resolve an instance for {serviceType.AssemblyQualifiedName}"); - return service; + throw new HibernateServiceProviderException( + $"Unable to resolve an instance for {serviceType.AssemblyQualifiedName}, " + + "make sure that the service is registered and a non-null value is returned for it.", innerException); } } } From 8cc22f80a3d6c94c699a3bfff177a1d8ac732fdd Mon Sep 17 00:00:00 2001 From: maca88 Date: Sat, 4 Aug 2018 18:06:57 +0200 Subject: [PATCH 12/16] Added the fallback also for external types --- .../UtilityTest/PropertiesHelperTest.cs | 28 ++++++++----------- .../Util/ServiceProviderExtensions.cs | 6 ++-- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs index c005ca50937..3b0087693bc 100644 --- a/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs +++ b/src/NHibernate.Test/UtilityTest/PropertiesHelperTest.cs @@ -85,14 +85,12 @@ public void GetInstanceByDefaultWithExplicitServiceProvider() public void GetExternalInstanceByDefaultWithExplicitServiceProvider() { Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); - Assert.Throws( - () => - { - PropertiesHelper.GetInstance( - "conn", - new Dictionary(), - typeof(DebugConnectionProvider)); - }); + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary(), + typeof(DebugConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); } [Test] @@ -136,14 +134,12 @@ public void GetInstanceByPropertyWithExplicitServiceProvider() public void GetExternalInstanceByPropertyWithExplicitServiceProvider() { Cfg.Environment.ServiceProvider = new SimpleServiceProvider(true); - Assert.Throws( - () => - { - PropertiesHelper.GetInstance( - "conn", - new Dictionary {{"conn", typeof(DebugConnectionProvider).AssemblyQualifiedName}}, - typeof(DriverConnectionProvider)); - }); + var instance = PropertiesHelper.GetInstance( + "conn", + new Dictionary {{"conn", typeof(DebugConnectionProvider).AssemblyQualifiedName}}, + typeof(DriverConnectionProvider)); + Assert.That(instance, Is.Not.Null); + Assert.That(instance, Is.TypeOf()); } [Test] diff --git a/src/NHibernate/Util/ServiceProviderExtensions.cs b/src/NHibernate/Util/ServiceProviderExtensions.cs index 17821a7b594..7d56b6eb19b 100644 --- a/src/NHibernate/Util/ServiceProviderExtensions.cs +++ b/src/NHibernate/Util/ServiceProviderExtensions.cs @@ -6,8 +6,6 @@ namespace NHibernate.Util { internal static class ServiceProviderExtensions { - private static readonly string InternalAssemblyName = typeof(ServiceProviderExtensions).Assembly.GetName().ToString(); - /// /// Get a service, throwing if it cannot be resolved. /// @@ -27,9 +25,9 @@ public static object GetInstance(this IServiceProvider serviceProvider, System.T } // Some IoC containers require explicit registration for concete types. In order to avoid registering all NHibernate types - // the Activator.CreateInstance is used for internal types, but the strictness is respected for external types. + // the Activator.CreateInstance is used for them. Exception innerException = null; - if (serviceType.IsClass && !serviceType.IsAbstract && InternalAssemblyName.Equals(serviceType.Assembly.GetName().ToString())) + if (serviceType.IsClass && !serviceType.IsAbstract) { try { From b31157aa8ecce3d8892d57e160023525d0dc20ca Mon Sep 17 00:00:00 2001 From: maca88 Date: Sat, 4 Aug 2018 21:31:03 +0200 Subject: [PATCH 13/16] Renamed GetInstance to GetMandatoryService --- src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs | 2 +- src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs | 2 +- src/NHibernate/Bytecode/AbstractBytecodeProvider.cs | 2 +- src/NHibernate/Cfg/Configuration.cs | 2 +- src/NHibernate/Cfg/SettingsFactory.cs | 2 +- .../Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs | 2 +- .../Driver/ReflectionDriveConnectionCommandProvider.cs | 4 ++-- src/NHibernate/Exceptions/SQLExceptionConverterFactory.cs | 2 +- src/NHibernate/Id/IdentifierGeneratorFactory.cs | 2 +- src/NHibernate/Mapping/Collection.cs | 2 +- src/NHibernate/Properties/PropertyAccessorFactory.cs | 2 +- src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs | 2 +- src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs | 2 +- src/NHibernate/Type/CompositeCustomType.cs | 2 +- src/NHibernate/Type/CustomCollectionType.cs | 2 +- src/NHibernate/Type/CustomType.cs | 2 +- src/NHibernate/Type/TypeFactory.cs | 2 +- src/NHibernate/Util/PropertiesHelper.cs | 4 ++-- src/NHibernate/Util/ServiceProviderExtensions.cs | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs b/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs index 028a90e1322..7217a0d2b4c 100644 --- a/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs +++ b/src/NHibernate/Async/Tool/hbm2ddl/SchemaUpdate.cs @@ -78,7 +78,7 @@ public partial class SchemaUpdate { cfg.SetNamingStrategy( (INamingStrategy) - Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs b/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs index e420e4ead8f..4cf2c112f14 100644 --- a/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs +++ b/src/NHibernate/Async/Tool/hbm2ddl/SchemaValidator.cs @@ -48,7 +48,7 @@ public partial class SchemaValidator { cfg.SetNamingStrategy( (INamingStrategy) - Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Cfg.Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs index 6e457cb3d23..656f4a20434 100644 --- a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs +++ b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs @@ -50,7 +50,7 @@ public virtual ICollectionTypeFactory CollectionTypeFactory try { collectionTypeFactory = - (ICollectionTypeFactory) Cfg.Environment.ServiceProvider.GetInstance(collectionTypeFactoryClass); + (ICollectionTypeFactory) Cfg.Environment.ServiceProvider.GetMandatoryService(collectionTypeFactoryClass); } catch (Exception e) { diff --git a/src/NHibernate/Cfg/Configuration.cs b/src/NHibernate/Cfg/Configuration.cs index f9a5309df3a..18037115983 100644 --- a/src/NHibernate/Cfg/Configuration.cs +++ b/src/NHibernate/Cfg/Configuration.cs @@ -1908,7 +1908,7 @@ public void SetListeners(ListenerType type, string[] listenerClasses) { try { - listeners[i] = Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(listenerClasses[i])); + listeners[i] = Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(listenerClasses[i])); } catch (Exception e) { diff --git a/src/NHibernate/Cfg/SettingsFactory.cs b/src/NHibernate/Cfg/SettingsFactory.cs index 6b7caadaff9..373c2b61496 100644 --- a/src/NHibernate/Cfg/SettingsFactory.cs +++ b/src/NHibernate/Cfg/SettingsFactory.cs @@ -331,7 +331,7 @@ private static IBatcherFactory CreateBatcherFactory(IDictionary } if (instance == null) { - instance = (IBatcherFactory) Environment.ServiceProvider.GetInstance(tBatcher ?? typeof(NonBatchingBatcherFactory)); + instance = (IBatcherFactory) Environment.ServiceProvider.GetMandatoryService(tBatcher ?? typeof(NonBatchingBatcherFactory)); } } catch (Exception cnfe) diff --git a/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs b/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs index f09eb41f699..7f55641b7e2 100644 --- a/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs +++ b/src/NHibernate/Cfg/XmlHbmBinding/AuxiliaryDatabaseObjectFactory.cs @@ -42,7 +42,7 @@ private static IAuxiliaryDatabaseObject CreateCustomObject(Mappings mappings, Hb System.Type customType = ReflectHelper.ClassForName(className); IAuxiliaryDatabaseObject customObject = - (IAuxiliaryDatabaseObject) Environment.ServiceProvider.GetInstance(customType); + (IAuxiliaryDatabaseObject) Environment.ServiceProvider.GetMandatoryService(customType); foreach (string dialectName in databaseObjectSchema.FindDialectScopeNames()) { diff --git a/src/NHibernate/Driver/ReflectionDriveConnectionCommandProvider.cs b/src/NHibernate/Driver/ReflectionDriveConnectionCommandProvider.cs index adb1a192600..5bff9350740 100644 --- a/src/NHibernate/Driver/ReflectionDriveConnectionCommandProvider.cs +++ b/src/NHibernate/Driver/ReflectionDriveConnectionCommandProvider.cs @@ -28,12 +28,12 @@ public ReflectionDriveConnectionCommandProvider(System.Type connectionType, Syst public DbConnection CreateConnection() { - return (DbConnection) Environment.ServiceProvider.GetInstance(connectionType); + return (DbConnection) Environment.ServiceProvider.GetMandatoryService(connectionType); } public DbCommand CreateCommand() { - return (DbCommand) Environment.ServiceProvider.GetInstance(commandType); + return (DbCommand) Environment.ServiceProvider.GetMandatoryService(commandType); } #endregion diff --git a/src/NHibernate/Exceptions/SQLExceptionConverterFactory.cs b/src/NHibernate/Exceptions/SQLExceptionConverterFactory.cs index fdea31b6171..3bce760d37d 100644 --- a/src/NHibernate/Exceptions/SQLExceptionConverterFactory.cs +++ b/src/NHibernate/Exceptions/SQLExceptionConverterFactory.cs @@ -115,7 +115,7 @@ private static ISQLExceptionConverter ConstructConverter(string converterClassNa } // Otherwise, try to use the no-arg constructor - return (ISQLExceptionConverter) Cfg.Environment.ServiceProvider.GetInstance(converterClass); + return (ISQLExceptionConverter) Cfg.Environment.ServiceProvider.GetMandatoryService(converterClass); } catch (Exception t) { diff --git a/src/NHibernate/Id/IdentifierGeneratorFactory.cs b/src/NHibernate/Id/IdentifierGeneratorFactory.cs index a238b20bf2d..d26ccd1f23e 100644 --- a/src/NHibernate/Id/IdentifierGeneratorFactory.cs +++ b/src/NHibernate/Id/IdentifierGeneratorFactory.cs @@ -219,7 +219,7 @@ public static IIdentifierGenerator Create(string strategy, IType type, IDictiona try { System.Type clazz = GetIdentifierGeneratorClass(strategy, dialect); - var idgen = (IIdentifierGenerator) Cfg.Environment.ServiceProvider.GetInstance(clazz); + var idgen = (IIdentifierGenerator) Cfg.Environment.ServiceProvider.GetMandatoryService(clazz); var conf = idgen as IConfigurable; if (conf != null) { diff --git a/src/NHibernate/Mapping/Collection.cs b/src/NHibernate/Mapping/Collection.cs index 4fb70edefaf..e7996afb2c7 100644 --- a/src/NHibernate/Mapping/Collection.cs +++ b/src/NHibernate/Mapping/Collection.cs @@ -152,7 +152,7 @@ public object Comparer { try { - comparer = Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(ComparerClassName)); + comparer = Cfg.Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(ComparerClassName)); } catch (Exception ex) { diff --git a/src/NHibernate/Properties/PropertyAccessorFactory.cs b/src/NHibernate/Properties/PropertyAccessorFactory.cs index a086e9715cd..3bcc891067a 100644 --- a/src/NHibernate/Properties/PropertyAccessorFactory.cs +++ b/src/NHibernate/Properties/PropertyAccessorFactory.cs @@ -260,7 +260,7 @@ private static IPropertyAccessor ResolveCustomAccessor(string accessorName) try { - var result = (IPropertyAccessor) Cfg.Environment.ServiceProvider.GetInstance(accessorClass); + var result = (IPropertyAccessor) Cfg.Environment.ServiceProvider.GetMandatoryService(accessorClass); accessors[accessorName] = result; return result; } diff --git a/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs b/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs index ebf2c561158..7c8ff27eaa9 100644 --- a/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs +++ b/src/NHibernate/Tool/hbm2ddl/SchemaUpdate.cs @@ -105,7 +105,7 @@ public static void Main(string[] args) { cfg.SetNamingStrategy( (INamingStrategy) - Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs b/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs index a7935e960e6..1445f15e2bf 100644 --- a/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs +++ b/src/NHibernate/Tool/hbm2ddl/SchemaValidator.cs @@ -60,7 +60,7 @@ public static void Main(string[] args) { cfg.SetNamingStrategy( (INamingStrategy) - Cfg.Environment.ServiceProvider.GetInstance(ReflectHelper.ClassForName(args[i].Substring(9)))); + Cfg.Environment.ServiceProvider.GetMandatoryService(ReflectHelper.ClassForName(args[i].Substring(9)))); } } else diff --git a/src/NHibernate/Type/CompositeCustomType.cs b/src/NHibernate/Type/CompositeCustomType.cs index 0f180a10df3..51ed7af963a 100644 --- a/src/NHibernate/Type/CompositeCustomType.cs +++ b/src/NHibernate/Type/CompositeCustomType.cs @@ -29,7 +29,7 @@ public CompositeCustomType(System.Type userTypeClass, IDictionary paramet try { - userType = (IUserType) Cfg.Environment.ServiceProvider.GetInstance(userTypeClass); + userType = (IUserType) Cfg.Environment.ServiceProvider.GetMandatoryService(userTypeClass); } catch (ArgumentNullException ane) { diff --git a/src/NHibernate/Type/TypeFactory.cs b/src/NHibernate/Type/TypeFactory.cs index 840a4ec5b0b..d1c2819d48b 100644 --- a/src/NHibernate/Type/TypeFactory.cs +++ b/src/NHibernate/Type/TypeFactory.cs @@ -542,7 +542,7 @@ public static IType HeuristicType(string typeName, IDictionary p { try { - type = (IType) Environment.ServiceProvider.GetInstance(typeClass); + type = (IType) Environment.ServiceProvider.GetMandatoryService(typeClass); } catch (Exception e) { diff --git a/src/NHibernate/Util/PropertiesHelper.cs b/src/NHibernate/Util/PropertiesHelper.cs index c7bfd730694..e8bb57c2462 100644 --- a/src/NHibernate/Util/PropertiesHelper.cs +++ b/src/NHibernate/Util/PropertiesHelper.cs @@ -99,7 +99,7 @@ public static TService GetInstance( if (className != null) { type = ReflectHelper.ClassForName(className); - return (TService) Cfg.Environment.ServiceProvider.GetInstance(type); + return (TService) Cfg.Environment.ServiceProvider.GetMandatoryService(type); } type = typeof(TService); @@ -110,7 +110,7 @@ public static TService GetInstance( } type = defaultType; - return defaultType != null ? (TService) Cfg.Environment.ServiceProvider.GetInstance(defaultType) : null; + return defaultType != null ? (TService) Cfg.Environment.ServiceProvider.GetMandatoryService(defaultType) : null; } catch (Exception e) { diff --git a/src/NHibernate/Util/ServiceProviderExtensions.cs b/src/NHibernate/Util/ServiceProviderExtensions.cs index 7d56b6eb19b..8d09b2d8eec 100644 --- a/src/NHibernate/Util/ServiceProviderExtensions.cs +++ b/src/NHibernate/Util/ServiceProviderExtensions.cs @@ -14,7 +14,7 @@ internal static class ServiceProviderExtensions /// The service instance. /// thrown if is . /// thrown if the service cannot be resolved. - public static object GetInstance(this IServiceProvider serviceProvider, System.Type serviceType) + public static object GetMandatoryService(this IServiceProvider serviceProvider, System.Type serviceType) { if (serviceType == null) throw new ArgumentNullException(nameof(serviceType)); From cf3bbf667794a1dc704f3c3a057a51d0552a81ca Mon Sep 17 00:00:00 2001 From: maca88 Date: Sat, 4 Aug 2018 21:33:24 +0200 Subject: [PATCH 14/16] Fixed GetService usages --- src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs | 3 ++- src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs | 3 ++- src/NHibernate/Bytecode/AbstractBytecodeProvider.cs | 2 +- src/NHibernate/Impl/SessionFactoryImpl.cs | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs index f310e1db94b..383e0f85fdb 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH1547/Fixture.cs @@ -132,7 +132,8 @@ public partial class DriverForSubstitutedCommand : IDriver public DriverForSubstitutedCommand() { - _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass); + _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass) ?? + throw new InvalidOperationException($"Driver {DriverClass} is not registered."); } DbCommand IDriver.GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) diff --git a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs index 87d4855b274..d7082acdfde 100644 --- a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs +++ b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs @@ -534,7 +534,8 @@ public class ClientDriverWithParamsStats : IDriver public ClientDriverWithParamsStats() { - _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass); + _driverImplementation = (IDriver) Cfg.Environment.ServiceProvider.GetService(DriverClass) ?? + throw new InvalidOperationException($"Driver {DriverClass} is not registered."); } private static void Inc(T type, IDictionary dic) diff --git a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs index 656f4a20434..40be01625bb 100644 --- a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs +++ b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs @@ -23,7 +23,7 @@ public virtual IProxyFactoryFactory ProxyFactoryFactory { try { - return (IProxyFactoryFactory) Cfg.Environment.ServiceProvider.GetService(proxyFactoryFactory); + return (IProxyFactoryFactory) Cfg.Environment.ServiceProvider.GetMandatoryService(proxyFactoryFactory); } catch (Exception e) { diff --git a/src/NHibernate/Impl/SessionFactoryImpl.cs b/src/NHibernate/Impl/SessionFactoryImpl.cs index 672fa9b5a4c..0c6f1410fd7 100644 --- a/src/NHibernate/Impl/SessionFactoryImpl.cs +++ b/src/NHibernate/Impl/SessionFactoryImpl.cs @@ -1290,8 +1290,9 @@ private ICurrentSessionContext BuildCurrentSessionContext() } else { - context = (ICurrentSessionContext) Environment.ServiceProvider.GetService( - implClass ?? typeof(ICurrentSessionContext)); + context = (ICurrentSessionContext) (implClass != null + ? Environment.ServiceProvider.GetMandatoryService(implClass) + : Environment.ServiceProvider.GetService(typeof(ICurrentSessionContext))); } if (context is ISessionFactoryAwareCurrentSessionContext sessionFactoryAwareContext) { From 357b628ef246f2bb82a14d37bf26bb34710b37d8 Mon Sep 17 00:00:00 2001 From: maca88 Date: Sat, 4 Aug 2018 21:41:41 +0200 Subject: [PATCH 15/16] Regenerate async --- .../Async/CfgTest/SettingsFactoryFixture.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs index d28fee05b34..87efee1601c 100644 --- a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs +++ b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs @@ -32,6 +32,28 @@ namespace NHibernate.Test.CfgTest public class SettingsFactoryFixtureAsync { + [Test] + public void DefaultServices() + { + var properties = new Dictionary + { + {Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName}, + {Environment.UseQueryCache, "true"} + }; + var settings = new SettingsFactory().BuildSettings(properties); + Assert.That(settings.BatcherFactory, Is.TypeOf()); + Assert.That(settings.CacheProvider, Is.TypeOf()); + Assert.That(settings.ConnectionProvider, Is.TypeOf()); + Assert.That(settings.Dialect, Is.TypeOf()); + Assert.That(settings.LinqToHqlGeneratorsRegistry, Is.TypeOf()); + Assert.That(settings.QueryCacheFactory, Is.TypeOf()); + Assert.That(settings.QueryModelRewriterFactory, Is.Null); + Assert.That(settings.QueryTranslatorFactory, Is.TypeOf()); + Assert.That(settings.QueryCacheFactory, Is.TypeOf()); + Assert.That(settings.SqlExceptionConverter, Is.TypeOf()); + Assert.That(settings.TransactionFactory, Is.TypeOf()); + } + [Test] public async Task InvalidRegisteredServicesAsync() { From d52629bb28c1ed8678a31b86c4615ab03e3515e0 Mon Sep 17 00:00:00 2001 From: maca88 Date: Mon, 6 Aug 2018 22:41:15 +0200 Subject: [PATCH 16/16] Upgrade async generator to 0.8.2.10 --- Tools/packages.config | 2 +- .../Async/CfgTest/SettingsFactoryFixture.cs | 114 ------------------ .../Async/SessionBuilder/Fixture.cs | 45 ------- 3 files changed, 1 insertion(+), 160 deletions(-) delete mode 100644 src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs diff --git a/Tools/packages.config b/Tools/packages.config index 438a75071ab..0a0677ffb1e 100644 --- a/Tools/packages.config +++ b/Tools/packages.config @@ -7,7 +7,7 @@ - + diff --git a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs b/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs deleted file mode 100644 index 87efee1601c..00000000000 --- a/src/NHibernate.Test/Async/CfgTest/SettingsFactoryFixture.cs +++ /dev/null @@ -1,114 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using System.Collections.Generic; -using NHibernate.AdoNet; -using NHibernate.Bytecode; -using NHibernate.Cache; -using NHibernate.Cfg; -using NHibernate.Connection; -using NHibernate.Exceptions; -using NHibernate.Hql; -using NHibernate.Hql.Ast.ANTLR; -using NHibernate.Linq.Functions; -using NHibernate.Linq.Visitors; -using NHibernate.Transaction; -using NSubstitute; -using NUnit.Framework; -using Environment = NHibernate.Cfg.Environment; - -namespace NHibernate.Test.CfgTest -{ - using System.Threading.Tasks; - [TestFixture] - public class SettingsFactoryFixtureAsync - { - - [Test] - public void DefaultServices() - { - var properties = new Dictionary - { - {Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName}, - {Environment.UseQueryCache, "true"} - }; - var settings = new SettingsFactory().BuildSettings(properties); - Assert.That(settings.BatcherFactory, Is.TypeOf()); - Assert.That(settings.CacheProvider, Is.TypeOf()); - Assert.That(settings.ConnectionProvider, Is.TypeOf()); - Assert.That(settings.Dialect, Is.TypeOf()); - Assert.That(settings.LinqToHqlGeneratorsRegistry, Is.TypeOf()); - Assert.That(settings.QueryCacheFactory, Is.TypeOf()); - Assert.That(settings.QueryModelRewriterFactory, Is.Null); - Assert.That(settings.QueryTranslatorFactory, Is.TypeOf()); - Assert.That(settings.QueryCacheFactory, Is.TypeOf()); - Assert.That(settings.SqlExceptionConverter, Is.TypeOf()); - Assert.That(settings.TransactionFactory, Is.TypeOf()); - } - - [Test] - public async Task InvalidRegisteredServicesAsync() - { - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - await (InvalidRegisteredServiceAsync()); - } - - private Task InvalidRegisteredServiceAsync() - { - try - { - var sp = new SimpleServiceProvider(); - sp.Register(() => throw new InvalidOperationException()); - - Environment.ServiceProvider = sp; - - var properties = new Dictionary - { - {Environment.UseQueryCache, "true"} - }; - if (typeof(TService) != typeof(Dialect.Dialect)) - { - properties.Add(Environment.Dialect, typeof(Dialect.PostgreSQL83Dialect).FullName); - } - - Assert.Throws( - () => new SettingsFactory().BuildSettings(properties), - $"HibernateException should be thrown for service {typeof(TService)}"); - return Task.CompletedTask; - } - catch (Exception ex) - { - return Task.FromException(ex); - } - } - - private IServiceProvider _originalSp; - - [SetUp] - public void Setup() - { - _originalSp = Environment.ServiceProvider; - } - - [TearDown] - public void TearDown() - { - Environment.ServiceProvider = _originalSp; - } - } -} diff --git a/src/NHibernate.Test/Async/SessionBuilder/Fixture.cs b/src/NHibernate.Test/Async/SessionBuilder/Fixture.cs index bebdb8fe084..0cd255eae26 100644 --- a/src/NHibernate.Test/Async/SessionBuilder/Fixture.cs +++ b/src/NHibernate.Test/Async/SessionBuilder/Fixture.cs @@ -189,51 +189,6 @@ private void CanSetFlushMode(T sb) where T : ISessionBuilder FlushMode.Always, FlushMode.Auto, FlushMode.Commit, FlushMode.Manual); } - [Test] - public async Task CanSetInterceptorAsync() - { - var sb = Sfi.WithOptions(); - await (CanSetInterceptorAsync(sb)); - using (var s = sb.OpenSession()) - { - await (CanSetInterceptorAsync(s.SessionWithOptions())); - } - } - - private Task CanSetInterceptorAsync(T sb) where T : ISessionBuilder - { - try - { - var sbType = sb.GetType().Name; - // Do not use .Instance here, we want another instance. - var interceptor = new EmptyInterceptor(); - var options = DebugSessionFactory.GetCreationOptions(sb); - - Assert.AreEqual(Sfi.Interceptor, options.SessionInterceptor, $"{sbType}: Initial value"); - var fsb = sb.Interceptor(interceptor); - Assert.AreEqual(interceptor, options.SessionInterceptor, $"{sbType}: After call with an interceptor"); - Assert.AreEqual(sb, fsb, $"{sbType}: Unexpected fluent return after call with an interceptor"); - - if (sb is ISharedSessionBuilder ssb) - { - var fssb = ssb.Interceptor(); - Assert.AreEqual(EmptyInterceptor.Instance, options.SessionInterceptor, $"{sbType}: After call with shared interceptor"); - Assert.AreEqual(sb, fssb, $"{sbType}: Unexpected fluent return on shared"); - } - - Assert.Throws(() => sb.Interceptor(null), $"{sbType}: After call with null"); - - fsb = sb.NoInterceptor(); - Assert.AreEqual(EmptyInterceptor.Instance, options.SessionInterceptor, $"{sbType}: After no call"); - Assert.AreEqual(sb, fsb, $"{sbType}: Unexpected fluent return after no call"); - return Task.CompletedTask; - } - catch (Exception ex) - { - return Task.FromException(ex); - } - } - private void CanSet(T sb, Func setter, Func getter, Func shared, V initialValue, params V[] values) where T : ISessionBuilder {