Leggere i parametri da linea di comando

Dopo i vari post di polemica varia... eccomi qui con un post tecnico. Segue come ho deciso di affrontare il _problema_ del passaggio dei parametri da riga di comando. Essendo che sono abbastanza soddisfatto della pensata (nonostante non sia nulla di eccezionale) ho deciso di persisterla nel mio blog. L'_archiettura_ è composta da una classe di utilità "ProgramArgumentsUtil" che è generica e ho incluso nella mia libreria di Utilità; da una classe specializzata per il contesto del programma "ProgramArguments" che ha il compito di convertire i parametri da stringa a dati tipizzati; e infine la classe "Program" che contiene il main del programma che usa la classe "ProgramArguments".

 /// <summary>
 /// Classe di utilità per la lettura dei parametri da linea di comando.
 /// Ogni parametro si intende nel formato: "{nomeparametro}:{valoreparametro}".
 /// I parametri non delimitati dai ":" verranno inseriti per intero come chiave con 
 /// valore Boolean.TrueString.
 /// </summary>
public class ProgramArgumentsUtil
{  
 #region Fields
 private static StringDictionary arguments;
 #endregion
 #region Constructors
 static ProgramArgumentsUtil()
 {
  arguments = new StringDictionary();
  string[] commandLineArguments = Environment.GetCommandLineArgs();
  for(int i = 1; i < commandLineArguments.Length; i++)
  {
   string[] splits = commandLineArguments[i].Split(new char[]{':'}, 2); 
   if(splits.Length == 2)
   {
    arguments[splits[0].ToUpper()] = splits[1];
   }
   else
   {
    arguments[splits[0].ToUpper()] = Boolean.TrueString;
   }
  }
 }
 #endregion
 #region Methods
 /// <summary>
 /// Indica se contiene un argomento.
 /// True se l'argomento è stato specificato.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public static bool Contains(string key)
 {
  return arguments.ContainsKey(key);
 }
 /// <summary>
 /// Recupera argomento per nome, se l'argomento non è 
 /// specificato torna il valore specificato da default value
 /// </summary>
 /// <param name="key"></param>
 /// <param name="defaultValue"></param>
 /// <returns></returns>
 public static string GetArgument(string key, string defaultValue)
 {   
  string item = arguments[key.ToUpper()];
  if(item == null)
  {
   item = defaultValue;
  }
  return item;
 }
 /// <summary>
 /// Ritorna la stringa con un quadro riassuntivo dei parametri.
 /// </summary>
 /// <returns></returns>
 public static new string ToString()
 {
  StringBuilder sb = new StringBuilder();
  foreach(string paramName in arguments.Keys)
  {
   sb.AppendFormat("{0}\t{1}", paramName, arguments[paramName]);
   sb.Append(Environment.NewLine);
  }
  return sb.ToString();
 }
 #endregion
} 
 
 /// <summary>
 /// Classe di utilità per la lettura degli argomenti da linea di comando.
 /// </summary>
public class ProgramArguments
{
  
 #region Const
 const string FILE_INPUT = "in";
 const string FORMATO_FILE = "f";
 const string MODE = "m";
 const string SOLO_VALIDAZIONE = "v";
 #endregion
  
 #region FromCommandLineArguments
 /// <summary>
 /// Lettura e conversione file + eventaule validazione dei dati.
 /// </summary>
 public static ProgramArguments FromCommandLineArguments()
 {   
  ProgramArguments programArguments = new ProgramArguments();
  programArguments.fileName = ProgramArgumentsUtil.GetArgument(FILE_INPUT, string.Empty);
  programArguments.formatoFile = ProgramArgumentsUtil.GetArgument(FORMATO_FILE, string.Empty).ToUpper();
  programArguments.soloValidazione =  ProgramArgumentsUtil.GetArgument(MODE, SOLO_VALIDAZIONE).Equals(SOLO_VALIDAZIONE);     
  return programArguments;
    
 }
 #endregion
 #region Fields
 private string formatoFile = string.Empty;
 private string filename = string.Empty;
 private bool soloValidazione = false;
 #endregion
 #region Constructors
 private ProgramArguments()
 {
 }
 #endregion
 #region Properties
 public string FormatoFile
 {
  get{return formatoFile;}
 }
 public string Filename
 {
  get{return fileName;}
 }
 public bool SoloValidazione
 {
  get{return soloValidazione;}
 }
 #endregion
  
 #region Methods
 [Conditional("DEBUG")]
 public void DumpOnTrace()
 {
  Trace.WriteLine(ProgramArgumentsUtil.ToString());
 }
 #endregion
}

class Program
{
 /// <summary>
 /// esempio: ASDataImp f:xls in:"C:\Data\Import Dati\ECMA.xls" m:v/i
 /// </summary>
 [STAThread]
 static void Main(string[] args)
 {
  try
  {
          
   ProgramArguments arguments = ProgramArguments.FromCommandLineArguments();
   arguments.DumpOnTrace();
    
   switch(arguments.FormatoFile)
   {
    case FileFormats.XLS:
     LettoreFoglioExcel excel = new LettoreFoglioExcel(arguments.Filename);
     if(arguments.SoloValidazione)
     {
      excel.Valida();
     }
     else
     {
      excel.Importa();
     }
     break;
    default:
     throw new ArgumentException("Formato non valido", "formato");
   }
      
  }
  catch(Exception e)
  {
   Environment.ExitCode = 1;
   Console.WriteLine(e.ToString());
  }
  AttendiConfermaUtente();
 }
 [Conditional("DEBUG")]
 private static void AttendiConfermaUtente()
 {
  Console.ReadLine();
 }
}

Nel mondo IT nessuno che vuole - ma soprattutto capisce - la qualità!

Volevo rispondere/commentare/dire la mia su una riflessione di Riccardo Golia riguardo a "la progettazione del software",  (ripresa anche da (Luka) in "Progettare software, la realtà italiana e della community .NET") ...la sua riflessione nasce dalla chat MVP di ieri sera... e mi spiace che ho dovuto staccare prima della discussione perchè sarebbe stato interessante partecipare, ma ahimè avevo un bel pò di strada per rientrare a casa :o

Dopo una serie di giustissime osservazioni lancia questa domanda: Ma siamo sicuri che la "colpa" sia solo di chi ci commissiona i progetti?
Credo personalmente che la colpa non sia loro... solitamente chi commissiona software non ha le idee chiare su qllo ke vuole... ma è normale, lui non è tecnico!

La verità sacrosanta è che "Purtroppo in Italia non sono molti i clienti che sono disposti a spendere per la qualità!". La mia idea che il mondo IT sia anche ricco di accrobati e direttori di circo... disposti a vendere qualsiasi cosa e andare anche sotto costo pur di accaparrarsi una piccola fetta mercato... peccato che dopo ci si ritrovi ad avere giorni e giorni di manutenzioni per bug (che molti riescono anke a farsi pagare!). Che poi una volta mi fecero notare che al cliente finale se un programma/sito funziona e fa il suo dovere è suffiiciente... fondamentelmente è un casino capire la bontà qualitattiva per un non-tecnico... bah... credo sia meglio ke mi fermo qui ke se no viene fuori un encicolopedia e non un post :-p

«ottobre»
domlunmarmergiovensab
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456