Enterprise Library 5 Гибридная конфигурация

Мы используем Enterprise Library 5.0 и хотели бы использовать блок приложения Logging для записи сообщений журнала/трассировки в базу данных. Выполнение всей конфигурации в файле web.config работает как чемпион.

Однако при запуске приложения нам необходимо указать строку подключения к базе данных, которую регистратор использует динамически. Мы подумали, что сможем применить гибридный подход, используя Ent Lib 5.0 Fluent API для программной регистрации строки подключения, а затем объединив ее со значениями конфигурации из файла web.config. Это позволило бы нам перенастроить способ и место написания сообщений трассировки без изменения кода.

Вот что мы пробовали:

var dynamicConnectionString = "..."  // value determined elsewhere

var builder = new ConfigurationSourceBuilder();
builder.ConfigureData()
    .ForDatabaseNamed( "TestDB" ).ThatIs.ASqlDatabase()
    .WithConnectionString( dynamicConnectionString );

var configSource = new SystemConfigurationSource();
// the line below throws an ArgumentException with the message
// 'Cannot add a ConfigurationSection with the same name that already exists'
builder.UpdateConfigurationWithReplace( configSource );
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer( configSource );

В файле web.config для нашего тестового проекта мы определяем только раздел loggingConfiguration следующим образом:

<loggingConfiguration ...>
    <listeners>
        <add databaseInstanceName="TestDB" ... />
    </listeners>
    <formatters>...</formatters>
    <categorySources>...</categorySources>
    <specialSources>...</specialSources>
</loggingConfiguration>

Если я проверяю объект построителя в отладчике, он имеет только 1 определенный раздел: раздел connectionStrings, который содержит одну запись connectionString со значениями, которые я указал в коде. Файл web.config не вообще содержит раздел connectionStrings.

По иронии судьбы, если я использую Immediate/Watch Window и проверяю System.Configuration.ConfigurationManager.ConnectionStrings, он сообщает, что уже определено 1 соединение... соединение по умолчанию ("data source=.\SQLExpress;Integrated Security=SSPI;AttacheDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true").

Если я добавлю <connectionStrings><clear /></connectionStrings> для очистки унаследованных значений, при повторной отладке я все еще получаю то же исключение, что и раньше, и VS уведомляет меня об обновлении файла web.config (если я перезагружу файл, раздел <connectionStrings> был удален).

Чего мне здесь не хватает! Это не может быть так сложно!


person KyKo    schedule 13.11.2015    source источник


Ответы (1)


Подумав об этом на выходных и немного покопавшись, я нашел Запись в блоге, которая помогла мне решить мои проблемы. Вот как это работает для меня:

var builder = new ConfigurationSourceBuilder();
// Configure the dataSource (connection string)
builder.ConfigureData()
    .ForDatabaseNamed( "TestDB" )
        .ThatIs.ASqlDatabase()
        // this would be determined at runtime; not statically defined
        .WithConnectionString( @"Data Source=.\SQLExpress;Initial Catalog=Logging;Integrated Security=True" )
    .AsDefault();

// create a new config source
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace( configSource );

IUnityContainer container = new UnityContainer();

// load the default configuration information from the config file
// i.e. ConfigurationSourceFactory.Create()
// and add it to the container
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 file and fluent config as the Enterprise Library service locator
EnterpriseLibraryContainer.Current = new UnityServiceLocator( container );

// Write a log entry using the Logger facade
LogEntry logEntry = new LogEntry
{
    EventId = 180,
    Priority = 1,
    Message = "Message",
    Categories = { "AccessAudit" }
};

Logger.Write( logEntry );

Надеюсь, это поможет кому-то еще в будущем.

person KyKo    schedule 16.11.2015
comment
Рад, что вы нашли блог полезным. - person Randy supports Monica; 12.02.2016