Fluent API只生效一次(企业库)

时间:2015-07-24 20:24:11

标签: enterprise-library

我希望使用流利的api做下面的事情 在运行时修改配置;也许要考虑外部因素或环境变化。
https://msdn.microsoft.com/en-us/library/ff664363(PandP.50).aspx
但是我遇到了问题。问题与以下链接完全相同。 Change Enterprise Library configuration midway in a program

1 个答案:

答案 0 :(得分:1)

此代码适用于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());
    }
}

运行此命令后,将创建两个日志文件:BeforeChange.log和AfterChange.log

对于EntLib 5,代码非常相似,只是需要设置容器:

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

上述EntLib 5方法的缺点是第二个配置将配置日志记录,但也会消除已配置的任何其他块。解决方案是直接使用Unity并保留相同的容器,只需修改我们想要更改的块。在此示例中,FirstConfig()配置数据访问和日志记录,但仅限SecondConfig(重新)配置日志记录。

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