De cada 10 aplicações que desenvolvemos, 9 precisam de parâmetros de configuração. Normalmente utiliza-se o web.config (para aplicações ASP.Net) ou o app.config (para aplicações Console ou Windows) para armazenar as configurações. Normalmente vemos o seguinte:
<appsettings>
<add key="Parametro1" value="ValorDoParam1">
<add key="Parametro2" value="ValorDoParam2">
</appsettings>
Esta abordagem é simples e normalmente atende nossas necessidades. Porém ao utilizar esta abordagem temos os seguintes problemas:
- Este espaço é compartilhado, o que torna mais difícil e suscetível a erros a configuração e manutenção
- Todos os dados são armazenados como String e não possuem nenhum tipo de validação para o tipo que eles realmente representam
- Não é possível armazenar estruturas complexas, como objetos por exemplo
Esta alternativa nos permite criar seções dentro dos arquivos de configuração customizadas. Estas seções terão classes de fachada para recuperar (de uma forma simples) as configurações armazenadas de forma estruturada.
Para criar a classe de fachada, basta herdar da classe System.Configuration.ConfigurationSection e definir propriedades que devolvem as configurações que virão do arquivo de configuração, exemplo:
<!-- O trecho a seguir configura as secões customizadas do arquivo de configurações -->
<configSections>
<section name="ExemploConfig" type="ExemploConfiguracao.Configuration, ExemploConfiguracao"/>
</configSections>
<!-- A Seguir estão as configurações armazenadas no trecho configurado anteriormente -->
<ExemploConfig SaveLog="True" />
Para a configuração acima teríamos a classe abaixo:
Public Class Configuration
Inherits System.Configuration.ConfigurationSection
<System.Configuration.ConfigurationProperty("SaveLog", IsRequired:=True)> _
Public ReadOnly Property SaveLog() As Boolean
Get
Return Convert.ToBoolean(MyBase.Item("SaveLog"))
End Get
End Property
End Class
Neste exemplo, a classe Configuration serve de fachada para a recuperação das configurações. Para acessar essas configurações é só fazer o seguinte:
Dim _Config As Configuration = System.Configuration.ConfigurationManager.GetSection("ExemploConfig")
Dim _SaveLog As Boolean = _Config.SaveLog
É possível também criar coleções de configurações: para isto, é necessário criar uma classe para lidar com a coleção e uma outra classe que definirá os itens dessa coleção, por exemplo, para adicionarmos uma coleção de módulos dentro do nosso exemplo anterior, ficaria assim:
Arquivo XML:
<!-- O trecho a seguir configura as secões customizadas do arquivo de configurações -->
<configSections>
<section name="ExemploConfig" type="ExemploConfiguracao.Configuration, ExemploConfiguracao"/>
</configSections>
<!-- A Seguir estão as configurações armazenadas no trecho configurado anteriormente -->
<ExemploConfig SaveLog="True">
<Modules>
<add ModuleName="Teste1" ExtractQuery="Select * From Tabela" />
<add ModuleName="Teste2" />
</Modules>
</ExemploConfig>
Classe Configuration:
Public Class Configuration
Inherits System.Configuration.ConfigurationSection
<System.Configuration.ConfigurationProperty("SaveLog", IsRequired:=True)> _
Public ReadOnly Property SaveLog() As Boolean
Get
Return Convert.ToBoolean(MyBase.Item("SaveLog"))
End Get
End Property
<System.Configuration.ConfigurationProperty("Modules", IsRequired:=False)> _
Public ReadOnly Property Modules() As ModuleConfigurationCollection
Get
Return MyBase.Item("Modules")
End Get
End Property
End Class
Classe que controlará a coleção:
<System.Configuration.ConfigurationCollection(GetType(ModuleConfiguration), AddItemName:="add", ClearItemsName:="clear")> _
Public Class ModuleConfigurationCollection
Inherits System.Configuration.ConfigurationElementCollection
Protected Overloads Overrides Function CreateNewElement() As System.Configuration.ConfigurationElement
Return New ModuleConfiguration()
End Function
Protected Overrides Function GetElementKey(ByVal element As System.Configuration.ConfigurationElement) As Object
Return DirectCast(element, ModuleConfiguration).ModuleName
End Function
Default Public Overloads ReadOnly Property Item(ByVal Index As Int32) As ModuleConfiguration
Get
Return BaseGet(Index)
End Get
End Property
End Class
Classe que representa os itens da coleção:
Public Class ModuleConfiguration
Inherits System.Configuration.ConfigurationElement
<System.Configuration.ConfigurationProperty("ModuleName", IsRequired:=True, IsKey:=True)> _
Public ReadOnly Property ModuleName() As String
Get
Return Me.Item("ModuleName")
End Get
End Property
<System.Configuration.ConfigurationProperty("ExtractQuery")> _
Public ReadOnly Property ExtractQuery() As String
Get
Return Me.Item("ExtractQuery")
End Get
End Property
End Class
Pesquisando mais afundo você encontrará parâmetros que podem ser configurados nas propriedades da classe de fachada que implementam validação sobre os dados inseridos, além da validação básica que há no exemplo (IsRequired:=True).
Acredito que esta abordagem para configuracões de aplicativos pode trazer benefícios na fase de implantação, pois é possível criar um ConfigSection mais intuitivo para quem irá realizar a configuração do aplicativo (na maioria das vezes quem realiza esta configuração não é o desenvolvedor). Esta abordagem também torna mais simples a tarefa de mover as configurações para um arquivo XML diferente do web.config ou do app.config.
Baixe o exemplo acima completo para o Visual Studio 2008: Download
2 comentários:
Bela iniciativa!
Valeu!!!
Com esse espaço pretendo trocar idéias com o pessoal interessado nestes assuntos e expor minha opinião!
Abrassss!
Postar um comentário