Skip to content

Ability to replace ConfigurationManager with a custom config provider #2116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 16, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/NHibernate.Test/Async/NHSpecificTest/NH2420/Fixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using System.Data.Common;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Configuration;
using System.Transactions;
using NHibernate.Dialect;
using NHibernate.Driver;
Expand Down Expand Up @@ -43,9 +42,7 @@ private string FetchConnectionStringFromConfiguration()
string connectionStringName;
if (cfg.Properties.TryGetValue(Environment.ConnectionStringName, out connectionStringName))
{
var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
Assert.That(connectionStringSettings, Is.Not.Null);
connectionString = connectionStringSettings.ConnectionString;
connectionString = Cfg.Settings.ConfigurationManager.GetNamedConnectionString(connectionStringName);
Assert.That(connectionString, Is.Not.Null.Or.Empty);
return connectionString;
}
Expand Down
13 changes: 2 additions & 11 deletions src/NHibernate.Test/CfgTest/ConfigurationSchemaFixture.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Configuration;
using NHibernate.Event;
using NUnit.Framework;
using NHibernate.Cfg;
Expand Down Expand Up @@ -26,9 +25,7 @@ public void SessionFactoryIsRequiredWhenConfigurationIsNotLoadedFromAppConfig()
[Test]
public void FromAppConfigTest()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

IHibernateConfiguration hc = ConfigurationManager.GetSection("hibernate-configuration") as IHibernateConfiguration;
IHibernateConfiguration hc = Cfg.Settings.ConfigurationManager.GetConfiguration();
Assert.That(hc.ByteCodeProviderType, Is.EqualTo("lcg"));
Assert.IsTrue(hc.UseReflectionOptimizer);
Assert.AreEqual("NHibernate.Test", hc.SessionFactory.Name);
Expand All @@ -37,8 +34,6 @@ public void FromAppConfigTest()
[Test]
public void ByteCodeProvider()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

var xml =
@"<?xml version='1.0' encoding='utf-8' ?>
<hibernate-configuration xmlns='urn:nhibernate-configuration-2.2'>
Expand All @@ -54,9 +49,7 @@ public void ByteCodeProvider()
[Test]
public void IgnoreSystemOutOfAppConfig()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

IHibernateConfiguration hc = ConfigurationManager.GetSection("hibernate-configuration") as IHibernateConfiguration;
IHibernateConfiguration hc = Cfg.Settings.ConfigurationManager.GetConfiguration();
string xml =
@"<?xml version='1.0' encoding='utf-8' ?>
<hibernate-configuration xmlns='urn:nhibernate-configuration-2.2'>
Expand All @@ -75,8 +68,6 @@ public void IgnoreSystemOutOfAppConfig()
[Test]
public void ObjectsFactory()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

var xml =
@"<?xml version='1.0' encoding='utf-8' ?>
<hibernate-configuration xmlns='urn:nhibernate-configuration-2.2'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ public void ConnectionStringInSettingsOverrideNamedConnectionSTring()
[Test]
public void CanGetNamedConnectionStringFromConfiguration()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

Dictionary<string, string> settings = new Dictionary<string, string>();
settings.Add(Environment.ConnectionStringName, "DummyConnectionString");
MockConnectionProvider cp = new MockConnectionProvider();
Expand Down
4 changes: 0 additions & 4 deletions src/NHibernate.Test/Logging/LoggerProviderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,13 @@ public void LoggerProviderCanCreateLoggers_Obsolete()
[Test]
public void WhenNotConfiguredAndLog4NetExistsThenUseLog4NetFactory()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

// NoLoggingNHibernateLogger is internal
Assert.That(NHibernateLogger.For("pizza").GetType().Name, Is.Not.EqualTo("NoLoggingNHibernateLogger"));
}

[Test, Obsolete]
public void WhenNotConfiguredAndLog4NetExistsThenUseLog4NetFactory_Obsolete()
{
Assume.That(TestsContext.ExecutingWithVsTest, Is.False);

Assert.That(LoggerProvider.LoggerFor("pizza"), Is.Not.InstanceOf<NoLoggingInternalLogger>());

// works because this is the legacy provider with a legacy logger
Expand Down
5 changes: 1 addition & 4 deletions src/NHibernate.Test/NHSpecificTest/NH2420/Fixture.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Data.Common;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Configuration;
using System.Transactions;
using NHibernate.Dialect;
using NHibernate.Driver;
Expand Down Expand Up @@ -32,9 +31,7 @@ private string FetchConnectionStringFromConfiguration()
string connectionStringName;
if (cfg.Properties.TryGetValue(Environment.ConnectionStringName, out connectionStringName))
{
var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
Assert.That(connectionStringSettings, Is.Not.Null);
connectionString = connectionStringSettings.ConnectionString;
connectionString = Cfg.Settings.ConfigurationManager.GetNamedConnectionString(connectionStringName);
Assert.That(connectionString, Is.Not.Null.Or.Empty);
return connectionString;
}
Expand Down
25 changes: 6 additions & 19 deletions src/NHibernate.Test/TestsContext.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,33 @@
using NUnit.Framework;
#if NETCOREAPP2_0
using NUnit.Framework;

#if NETCOREAPP2_0
using System.Configuration;
using System.IO;
using log4net.Repository.Hierarchy;
using NHibernate.Cfg;
using NHibernate.Cfg.ConfigurationSchema;
#endif

namespace NHibernate.Test
{
#if NETCOREAPP2_0
[SetUpFixture]
#endif
public class TestsContext
{
public static bool ExecutingWithVsTest { get; } =
private static bool ExecutingWithVsTest { get; } =
System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name == "testhost";

#if NETCOREAPP2_0
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
//When .NET Core App 2.0 tests run from VS/VSTest the entry assembly is "testhost.dll"
//so we need to explicitly load the configuration
if (ExecutingWithVsTest)
{
Environment.InitializeGlobalProperties(GetTestAssemblyHibernateConfiguration());
var assemblyPath = Path.Combine(TestContext.CurrentContext.TestDirectory, Path.GetFileName(typeof(TestsContext).Assembly.Location));
Settings.ConfigurationManager = new SystemConfigurationManager(ConfigurationManager.OpenExeConfiguration(assemblyPath));
}

ConfigureLog4Net();
}

public static IHibernateConfiguration GetTestAssemblyHibernateConfiguration()
{
var assemblyPath =
Path.Combine(TestContext.CurrentContext.TestDirectory, Path.GetFileName(typeof(TestsContext).Assembly.Location));
var configuration = ConfigurationManager.OpenExeConfiguration(assemblyPath);
var section = configuration.GetSection(CfgXmlHelper.CfgSectionName);
return HibernateConfiguration.FromAppConfig(section.SectionInformation.GetRawXml());
}

private static void ConfigureLog4Net()
{
var hierarchy = (Hierarchy)log4net.LogManager.GetRepository(typeof(TestsContext).Assembly);
Expand All @@ -58,6 +45,6 @@ private static void ConfigureLog4Net()
hierarchy.Root.AddAppender(consoleAppender);
hierarchy.Configured = true;
}
#endif
}
}
#endif
1 change: 0 additions & 1 deletion src/NHibernate/Async/Connection/ConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

using System;
using System.Collections;
using System.Configuration;
using System.Data.Common;

using NHibernate.Driver;
Expand Down
13 changes: 13 additions & 0 deletions src/NHibernate/Cfg/AppSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace NHibernate.Cfg
{
/// <summary>
/// Configuration App Settings
/// </summary>
public static class AppSettings
{
/// <summary>
/// Type that implements <see cref="INHibernateLoggerFactory"/>
/// </summary>
public const string LoggerFactoryClassName = "nhibernate-logger";
}
}
16 changes: 16 additions & 0 deletions src/NHibernate/Cfg/ConfigurationProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace NHibernate.Cfg
{
/// <summary>
/// Base class for NHibernate configuration settings
/// </summary>
public abstract class ConfigurationProvider
{
public abstract IHibernateConfiguration GetConfiguration();
public abstract string GetNamedConnectionString(string name);

/// <summary>
/// Type that implements <see cref="INHibernateLoggerFactory"/>
/// </summary>
public abstract string GetLoggerFactoryClassName();
}
}
14 changes: 2 additions & 12 deletions src/NHibernate/Cfg/Environment.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;

using NHibernate.Bytecode;
Expand Down Expand Up @@ -370,19 +369,10 @@ public static void InitializeGlobalProperties(IHibernateConfiguration config)

private static IHibernateConfiguration GetHibernateConfiguration()
{
object config = ConfigurationManager.GetSection(CfgXmlHelper.CfgSectionName);
if (config == null)
var nhConfig = Settings.ConfigurationManager.GetConfiguration();
if (nhConfig == null && log.IsInfoEnabled())
{
log.Info("{0} section not found in application configuration file", CfgXmlHelper.CfgSectionName);
return null;
}

var nhConfig = config as IHibernateConfiguration;
if (nhConfig == null)
{
log.Info(
"{0} section handler, in application configuration file, is not IHibernateConfiguration, section ignored",
CfgXmlHelper.CfgSectionName);
}

return nhConfig;
Expand Down
20 changes: 20 additions & 0 deletions src/NHibernate/Cfg/NullConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace NHibernate.Cfg
{
class NullConfigurationManager : ConfigurationProvider
{
public override IHibernateConfiguration GetConfiguration()
{
return null;
}

public override string GetNamedConnectionString(string name)
{
return null;
}

public override string GetLoggerFactoryClassName()
{
return null;
}
}
}
12 changes: 12 additions & 0 deletions src/NHibernate/Cfg/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ namespace NHibernate.Cfg
/// </summary>
public sealed class Settings
{
private static ConfigurationProvider _configurationManager = new StaticSystemConfigurationManager();

/// <summary>
/// Provides ability to override default <see cref="System.Configuration.ConfigurationManager"/> with custom implementation.
/// Can be set to null if all configuration is specified by code
/// </summary>
public static ConfigurationProvider ConfigurationManager
{
get => _configurationManager;
set => _configurationManager = value ?? new NullConfigurationManager();
}

public Settings()
{
MaximumFetchDepth = -1;
Expand Down
42 changes: 42 additions & 0 deletions src/NHibernate/Cfg/StaticSystemConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Configuration;
using System.Linq;
using NHibernate.Cfg.ConfigurationSchema;

namespace NHibernate.Cfg
{
class StaticSystemConfigurationManager : ConfigurationProvider
{
public override IHibernateConfiguration GetConfiguration()
{
//TODO 6.0: Throw if not null and not IHibernateConfiguration
return ConfigurationManager.GetSection(CfgXmlHelper.CfgSectionName) as IHibernateConfiguration;
}

public override string GetNamedConnectionString(string name)
{
return ConfigurationManager.ConnectionStrings[name]?.ConnectionString;
}

public override string GetLoggerFactoryClassName()
{
var name = AppSettings.LoggerFactoryClassName;
var value = ConfigurationManager.AppSettings[name];

//TODO 6.0: Return value right away. Don't do ignore case search and document it as possible breaking change.
if (value != null)
return value;

return GetAppSettingIgnoreCase(name);
}

//TODO 6.0: Remove it
private static string GetAppSettingIgnoreCase(string name)
{
var key = ConfigurationManager.AppSettings.Keys.Cast<string>().FirstOrDefault(k => name.Equals(k, StringComparison.OrdinalIgnoreCase));
return string.IsNullOrEmpty(key)
? null
: ConfigurationManager.AppSettings[key];
}
}
}
40 changes: 40 additions & 0 deletions src/NHibernate/Cfg/SystemConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Configuration;
using NHibernate.Cfg.ConfigurationSchema;

namespace NHibernate.Cfg
{
/// <summary>
/// Configuration manager that supports user provided configuration
/// </summary>
public class SystemConfigurationManager : ConfigurationProvider
{
private readonly System.Configuration.Configuration _configuration;

public SystemConfigurationManager(System.Configuration.Configuration configuration)
{
_configuration = configuration;
}

public override IHibernateConfiguration GetConfiguration()
{
ConfigurationSection configurationSection = _configuration.GetSection(CfgXmlHelper.CfgSectionName);
var xml = configurationSection?.SectionInformation.GetRawXml();
return xml == null ? null : HibernateConfiguration.FromAppConfig(xml);
}

public override string GetNamedConnectionString(string name)
{
return _configuration.ConnectionStrings.ConnectionStrings[name]?.ConnectionString;
}

public override string GetLoggerFactoryClassName()
{
return GetAppSetting(AppSettings.LoggerFactoryClassName);
}

private string GetAppSetting(string name)
{
return _configuration.AppSettings.Settings[name]?.Value;
}
}
}
8 changes: 3 additions & 5 deletions src/NHibernate/Connection/ConnectionProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections;
using System.Configuration;
using System.Data.Common;

using NHibernate.Driver;
Expand Down Expand Up @@ -77,10 +76,9 @@ protected virtual string GetNamedConnectionString(IDictionary<string, string> se
if(!settings.TryGetValue(Environment.ConnectionStringName, out connStringName))
return null;

ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[connStringName];
if (connectionStringSettings == null)
throw new HibernateException(string.Format("Could not find named connection string {0}", connStringName));
return connectionStringSettings.ConnectionString;
var connectionString = Cfg.Settings.ConfigurationManager.GetNamedConnectionString(connStringName)
?? throw new HibernateException(string.Format("Could not find named connection string {0}", connStringName));
return connectionString;
}

/// <summary>
Expand Down
Loading