Estoy tratando de implementar una sección de configuración personalizada en un proyecto y sigo corriendo con excepciones que no entiendo. Espero que alguien pueda completar los espacios en blanco aquí.
Tengo App.config
que se ve así:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ServicesSection" type="RT.Core.Config.ServicesConfigurationSectionHandler, RT.Core"/>
</configSections>
<ServicesSection type="RT.Core.Config.ServicesSection, RT.Core">
<Services>
<AddService Port="6996" ReportType="File" />
<AddService Port="7001" ReportType="Other" />
</Services>
</ServicesSection>
</configuration>
Tengo un ServiceConfig
elemento definido así:
public class ServiceConfig : ConfigurationElement
{
public ServiceConfig() {}
public ServiceConfig(int port, string reportType)
{
Port = port;
ReportType = reportType;
}
[ConfigurationProperty("Port", DefaultValue = 0, IsRequired = true, IsKey = true)]
public int Port
{
get { return (int) this["Port"]; }
set { this["Port"] = value; }
}
[ConfigurationProperty("ReportType", DefaultValue = "File", IsRequired = true, IsKey = false)]
public string ReportType
{
get { return (string) this["ReportType"]; }
set { this["ReportType"] = value; }
}
}
Y tengo un ServiceCollection
definido así:
public class ServiceCollection : ConfigurationElementCollection
{
public ServiceCollection()
{
Console.WriteLine("ServiceCollection Constructor");
}
public ServiceConfig this[int index]
{
get { return (ServiceConfig)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(ServiceConfig serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new ServiceConfig();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServiceConfig) element).Port;
}
public void Remove(ServiceConfig serviceConfig)
{
BaseRemove(serviceConfig.Port);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
}
La parte que me falta es qué hacer con el controlador. Originalmente, intenté implementar un IConfigurationSectionHandler
pero encontré dos cosas:
- no funcionó
- Está en desuso.
Ahora estoy completamente perdido sobre qué hacer para poder leer mis datos desde la configuración. Cualquier ayuda por favor!
c#
configuration
app-config
configuration-files
Chris Holmes
fuente
fuente
Respuestas:
La respuesta anterior es correcta, pero también te daré todo el código.
Su app.config debería verse así:
Tu
ServiceConfig
yServiceCollection
clases permanecen sin cambios.Necesitas una nueva clase:
Y eso debería hacer el truco. Para consumirlo puedes usar:
fuente
[Add|Remove|Clear]ItemName
propiedades en elConfigurationCollection
atributo no son realmente necesarias en este caso, porque "agregar" / "borrar" / "eliminar" ya son los nombres predeterminados de los elementos XML.Si está buscando una sección de configuración personalizada como la siguiente
entonces puedes usar mi implementación de la sección de configuración para comenzar a agregar una
System.Configuration
referencia de ensamblaje a tu proyectoMire cada uno de los elementos anidados que utilicé, el primero es Credenciales con dos atributos, así que agreguemos primero
Elemento de credenciales
Agente primario y Agente secundario
Ambos tienen los mismos atributos y parecen una Dirección a un conjunto de servidores para una conmutación por error primaria y, por lo que solo necesita crear una clase de elemento para ambos, como los siguientes
Explicaré cómo usar dos elementos diferentes con una clase más adelante en esta publicación, omita el SiteId ya que no hay diferencia en él. Solo tiene que crear una clase igual que la anterior con una sola propiedad. veamos cómo implementar la colección Lanes
se divide en dos partes, primero debe crear una clase de implementación de elemento y luego crear una clase de elemento de colección
LaneConfigElement
puede notar que un atributo de
LanElement
es una Enumeración y si intenta usar cualquier otro valor en la configuración que no esté definido en la aplicación Enumeración arrojará unSystem.Configuration.ConfigurationErrorsException
inicio. Ok, pasemos a la definición de colecciónpuedes notar que he configurado el
AddItemName = "Lane"
puedes elegir lo que quieras para el elemento de entrada de tu colección, prefiero usar "agregar" el predeterminado pero lo cambié solo por el bien de esta publicación.Ahora todos nuestros elementos anidados se han implementado, ahora debemos agregar todos los de una clase que tiene que implementar
System.Configuration.ConfigurationSection
CustomApplicationConfigSection
Ahora puede ver que tenemos dos propiedades con nombre
PrimaryAgent
ySecondaryAgent
ambas tienen el mismo tipo. Ahora puede comprender fácilmente por qué solo teníamos una clase de implementación para estos dos elementos.Antes de poder utilizar esta sección de configuración recién inventada en su app.config (o web.config) solo necesita decirle a la aplicación que ha inventado su propia sección de configuración y darle un poco de respeto, para ello debe agregar las siguientes líneas en app.config (puede ser justo después del inicio de la etiqueta raíz).
NOTA: MyAssemblyName debe estar sin .dll, por ejemplo, si el nombre del archivo de ensamblado es myDll.dll, use myDll en lugar de myDll.dll
para recuperar esta configuración, use la siguiente línea de código en cualquier lugar de su aplicación
Espero que la publicación anterior lo ayude a comenzar con un tipo un poco complicado de secciones de configuración personalizadas.
Happy Coding :)
**** Editar **** Para habilitar LINQ en
LaneConfigCollection
tienes que implementarIEnumerable<LaneConfigElement>
Y agregue la siguiente implementación de
GetEnumerator
para las personas que todavía están confundidas acerca de cómo funciona realmente el rendimiento, lea este bonito artículo
Dos puntos clave tomados del artículo anterior son
fuente
Este es un código genérico para la colección de configuración:
Después de que lo haya hecho
GenericConfigurationElementCollection
, puede usarlo simplemente en la sección de configuración (este es un ejemplo de mi Dispatcher):El elemento de configuración es config aquí:
El archivo de configuración se vería así:
Espero que ayude!
fuente
Una alternativa más fácil para aquellos que prefieren no escribir toda esa plantilla de configuración manualmente ...
1) Instalar Nerdle.AutoConfig desde NuGet
2) Defina su tipo de ServiceConfig (ya sea una clase concreta o simplemente una interfaz, ya sea)
3) Necesitará un tipo para guardar la colección, por ejemplo
4) Agregue la sección de configuración de esta manera (observe el nombre de camelCase)
5) Mapa con AutoConfig
fuente
Intente heredar de ConfigurationSection . Esta publicación de blog de Phil Haack tiene un ejemplo.
Confirmado, según la documentación de IConfigurationSectionHandler :
fuente