Usando o ConfigurationManager para carregar a configuração de um local arbitrário

Estou desenvolvendo um componente de access a dados que será usado em um site que contém uma combinação de páginas ASP e ASP.NET clássicas e precisa de uma boa maneira de gerenciar suas configurações.

Eu gostaria de usar um ConfigurationSection personalizado e para as páginas do ASP.NET isso funciona muito bem. Mas quando o componente é chamado via interoperabilidade COM a partir de uma página ASP clássica, o componente não está sendo executado no contexto de uma solicitação ASP.NET e, portanto, não tem conhecimento de web.config.

Existe uma maneira de dizer ao ConfigurationManager para carregar apenas a configuração de um caminho arbitrário (por exemplo, ..\web.config se meu assembly estiver na pasta /bin )? Se houver, então, estou pensando que meu componente pode retornar a ele se o ConfigurationManager.GetSection padrão retornar null para minha seção customizada.

Quaisquer outras abordagens para isso seriam bem vindas!

Tente isto:

 System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap); 

Outra solução é replace o caminho do arquivo de configuração do ambiente padrão.

Eu acho que é a melhor solução para o carregamento de arquivos de configuração de caminho não-trivial, especificamente a melhor maneira de append arquivo de configuração para dll.

 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", ); 

Exemplo:

 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config"); 

Mais detalhes podem ser encontrados neste blog .

Além disso, essa outra resposta tem uma excelente solução, completa com o código para atualizar a configuração do aplicativo e um object IDisposable para reconfigurá-lo de volta ao seu estado original. Com essa solução, você pode manter a configuração temporária do aplicativo no escopo:

 using(AppConfig.Change(tempFileName)) { // tempFileName is used for the app config during this context } 

A resposta de Ishmaeel geralmente funciona, no entanto eu encontrei um problema, que é que usando OpenMappedMachineConfiguration parece perder seus grupos de seção herdados de machine.config. Isso significa que você pode acessar suas próprias seções personalizadas (que é tudo o que o OP queria), mas não as seções normais do sistema. Por exemplo, esse código não funcionará:

 ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap); MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup; // returns null 

Basicamente, se você colocar um relógio na configuration.SectionGroups , você verá que o system.net não está registrado como um SectionGroup, então é praticamente inacessível através dos canais normais.

Há duas maneiras que encontrei para contornar isso. O primeiro, que eu não gosto, é reimplementar os grupos de seções do sistema copiando-os do machine.config para o seu próprio web.config, por exemplo

   

Não tenho certeza se o aplicativo da web em si será executado corretamente depois disso, mas você pode acessar os sectionGroups corretamente.

A segunda solução é abrir seu web.config como uma configuração EXE, que provavelmente está mais próxima de sua function pretendida:

 ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath }; Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup; // returns valid object! 

Não ouso dizer que nenhuma das respostas fornecidas aqui, nem a minha ou a do Ishmaeel, estão usando essas funções como os designers do .NET pretendiam. Mas isso parece funcionar para mim.

Além da resposta de Ishmaeel, o método OpenMappedMachineConfiguration() sempre retornará um object Configuration . Portanto, para verificar se ele foi carregado, você deve verificar a propriedade HasFile em que true significa que veio de um arquivo.

Eu forneci os valores de configuração para o word hospedado .nET Compoent da seguinte forma.

Um componente do .NET Class Library sendo chamado / hospedado no MS Word. Para fornecer valores de configuração ao meu componente, criei winword.exe.config na pasta C: \ Arquivos de Programas \ Microsoft Office \ OFFICE11. Você deve ser capaz de ler valores de configurações como o faz no .NET tradicional.

 string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"]; 

Para o ASP.NET, use o WebConfigurationManager:

 var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/"); (..) config.AppSettings.Settings["xxxx"].Value; 

Use o processamento XML:

 var appPath = AppDomain.CurrentDomain.BaseDirectory; var configPath = Path.Combine(appPath, baseFileName);; var root = XElement.Load(configPath); // can call root.Elements(...) 

Isso deve fazer o truque:

 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config); 

Fonte: https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files