Fluent API takes effect only once (Enterprise Library)

房东的猫 提交于 2019-12-25 06:04:15

问题


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


回答1:


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);
    }
}


来源:https://stackoverflow.com/questions/31619184/fluent-api-takes-effect-only-once-enterprise-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!