I wish to do the below using the fluent api
Modify the configuration at run time; perhaps to take into account external factors or changes to the environment.
https://msdn.microsoft.com/en-us/library/ff664363(PandP.50).aspx
But I get into issues. The problem is exactly same as the below link.
Change Enterprise Library configuration midway in a program
This code works in Enterprise Library 6:
class Program
{
static void Main(string[] args)
{
FirstConfig();
Logger.Write("Before processing", "General"); //Some wrapper around EntLib logger methods
//Do some processing for some time
SecondConfig();
Logger.Write("After after processing", "General");
}
private static void FirstConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("First Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("First Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("BeforeChange.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
Logger.SetLogWriter(new LogWriterFactory(configSource).Create());
}
private static void SecondConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("Second Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("Second Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("AfterChange.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
// Dispose any existing loggers
Logger.Reset();
Logger.SetLogWriter(new LogWriterFactory(configSource).Create());
}
}
After running this there will be two log files created: BeforeChange.log and AfterChange.log
For EntLib 5 the code is very similar except that the container needs to be setup:
class Program
{
static void Main(string[] args)
{
FirstConfig();
Logger.Write("Before processing", "General"); //Some wrapper around EntLib logger methods
//Do some processing for some time
SecondConfig();
Logger.Write("After after processing", "General");
}
private static void FirstConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("First Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("First Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("BeforeChange.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
}
private static void SecondConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("Second Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("Second Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("AfterChange.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
// Dispose any existing loggers
Logger.Reset();
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
}
}
The downside of the above EntLib 5 approach is that the second configuration will configure logging but will also wipe out any other blocks that were already configured. The solution is to use Unity directly and keep the same container and just make modifications to the blocks we want changed. In this example FirstConfig() configures data access and logging but SecondConfig only (re)configures logging.
class Program
{
private static IUnityContainer container = new UnityContainer();
static void Main(string[] args)
{
FirstConfig();
Logger.Write("Before processing", "General"); //Some wrapper around EntLib logger methods
EnterpriseLibraryContainer.Current.GetInstance<Database>("MyDatabase");
//Do some processing for some time
SecondConfig();
// This would fail if we cleared the existing configuration because SecondConfig()
// does not configure the data access block
EnterpriseLibraryContainer.Current.GetInstance<Database>("MyDatabase");
Logger.Write("After after processing", "General");
}
private static void FirstConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("First Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("First Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("BeforeChange.log");
builder.ConfigureData()
.ForDatabaseNamed("MyDatabase")
.ThatIs.ASqlDatabase()
.WithConnectionString("server=(local); database=Northwind; Integrated Security=true;")
.AsDefault();
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
container.AddNewExtension<EnterpriseLibraryCoreExtension>();
// Create a configurator to use to configure our fluent configuration
var configurator = new UnityContainerConfigurator(container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, configSource);
// Use the configured container with fluent config as the Enterprise Library service locator
EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);
}
private static void SecondConfig()
{
var textFormatter = new FormatterBuilder()
.TextFormatterNamed("Second Text Formatter")
.UsingTemplate("{message}");
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed("General").WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("Second Listener")
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile("AfterChange.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
// Dispose any existing loggers
Logger.Reset();
var configurator = new UnityContainerConfigurator(container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, configSource);
}
}