Service Oriented e i tanti file di configurazione
Posted by imperugo in Windows Communication Foundation on Monday 10 November 2008 at 5:00 PM
Una delle cose scomode che si ha in un'applicazione service oriented è il deploy e i numerosi file di configurazione. Se penso alla nostra attuale struttura parliamo di circa 20 servizi e di altrettanti file di configurazione.
Molto spesso questi file di configurazione hanno parti in comune tra loro, tipo custom section, behaviors, ecc e ogni qual volta devi cambiare una di queste parti sei costretto a dover modificare decine di file di configurazione.
Per ovviare il problema mi sono venute in mente due soluzione (se ne avete altre sono ben accette :D):
- Mettere le configurazioni in comune su file di configurazione esterni;
- Creare un file di configurazione comune a tutti i servizi.
Diciamo che mi è piaciuta più la seconda opzione, minor numero di file da gestire e maggior difficoltà nel realizzare la cosa :D (per la serie le cose semplici non ci piacciono).
Detto ciò ne è uscita la seguente classe:
using System;
using System.Configuration;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Web.Hosting;
public class MyServiceHost : ServiceHost
{
private string configPath;
/// <summary>
/// Initializes a new instance of the <see cref="MyServiceHost"> class.
/// </see>
/// </summary>
/// <param name="serviceType" />Type of the service.
/// <param name="baseAddresses" />The base addresses.
public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MyServiceHost"> class.
/// </see>
/// <param name="singletonInstance" />The instance of the hosted service.
/// <param name="baseAddresses" />An <see cref="T:System.Array"> of type <see cref="T:System.Uri"> that contains the base addresses for the hosted service.
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="singletonInstance"> is null.</paramref>
public MyServiceHost(object singletonInstance, params Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
private string ConfigPath
{
get
{
if (configPath == null)
{
// Hostato in IIS
configPath = HostingEnvironment.ApplicationPhysicalPath;
if (String.IsNullOrEmpty(configPath))
//Non hostato da IIS
configPath = Directory.GetCurrentDirectory();
}
return configPath;
}
}
/// <summary>
/// Loads the service description information from the configuration file and applies it to the runtime being constructed.
/// </summary>
/// <exception cref="T:System.InvalidOperationException">The description of the service hosted is null.</exception>
protected override void ApplyConfiguration()
{
// generate the name of the custom configFile, from the service name:
string configFilename = Path.Combine(ConfigPath,
String.Format("{0}.config", Description.Name));
if (!string.IsNullOrEmpty(configFilename) && File.Exists(configFilename))
base.ApplyConfiguration();
else
LoadConfigFromCustomLocation(@"C:\Temp\Services.config");
}
/// <summary>
/// Load the config file from custom location.
/// </summary>
/// <param name="configFilename" />The config filename.
private void LoadConfigFromCustomLocation(string configFilename)
{
var filemap = new ExeConfigurationFileMap {ExeConfigFilename = configFilename};
Configuration config =
ConfigurationManager.OpenMappedExeConfiguration
(filemap,
ConfigurationUserLevel.None);
ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);
if (serviceModel == null)
throw new ConfigurationErrorsException("There are a problem with the configuration file.");
bool loaded = false;
foreach (ServiceElement se in serviceModel.Services.Services)
{
if (!loaded)
if (se.Name == Description.ConfigurationName)
{
LoadConfigurationSection(se);
loaded = true;
}
}
if (!loaded)
throw new ArgumentException("ServiceElements not found in the configuration file.");
}
}
Il modo di utilizzarlo rimane lo stesso:
ServiceHost service = new MtvServiceHost(typeof(EmailService)); service.Open();
Nel file Services.config possiamo configurare tutti i servizi di cui abbiamo bisogno, ma tutto il resto del file di configurazione è comune a tutti.
Cambiamo un custom behavior comune a tutti, lo facciamo in un unico posto in un unico file!
Per ora sembra funzionare :D
The comments for this post are closed.
- There is no TrackBack for this post.
Archive