Brannon
unread,Feb 23, 2012, 1:59:36 PM2/23/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Autofac
Here is code for my first attempt at adding command line parsing
support. It seems to work pretty well. Run the code with -sp 23 or --
someProp asldjlsdjf to see how it works.
Possible Todo:
1. Support a parameter to output the usage.
2. Support required parameters.
3. Support generating an XML schema and a parameter to load parameters
from XML.
4. Warn about unused command line parameters
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using Autofac;
using Autofac.Core;
namespace TestAutofac
{
class Program
{
static void Main()
{
var builder = new ContainerBuilder();
var ret = builder.RegisterType<MyService>();
var cp = new ConfigurablePropertyParameter("SomeProp", "I'm a
command-line settable property");
ret.WithProperty(cp);
try
{
var container = builder.Build();
var service = container.Resolve<MyService>();
Console.WriteLine("Prop = " + service.SomeProp);
}
catch (DependencyResolutionException ex)
{
Console.WriteLine("Unable to successfully parse the parameter: " +
ex.InnerException.Source);
Console.WriteLine(ConfigurablePropertyParameter.GenerateCommandLineUsage());
}
if (Debugger.IsAttached)
Console.ReadKey();
}
}
class MyService
{
public int SomeProp { get; set; }
}
class ConfigurablePropertyParameter: Parameter
{
public static string GenerateCommandLineUsage()
{
var sb = new StringBuilder("Supported Parameters: ");
lock(_descriptions)
{
foreach (var desc in _descriptions.OrderBy(d => d.Key))
{
sb.AppendLine();
var sn = GenerateShortName(desc.Key);
var ln = GenerateLongName(desc.Key);
sb.Append("\t");
sb.Append(sn);
sb.Append("/");
sb.Append(ln);
sb.Append(" <value>\t");
sb.Append(desc.Value);
}
}
return sb.ToString();
}
protected static readonly Dictionary<string, string> _descriptions =
new Dictionary<string, string>();
protected static readonly HashSet<string> _shortNames = new
HashSet<string>();
public readonly string PropertyName;
public ConfigurablePropertyParameter(string propertyName, string
propertyDescription)
{
PropertyName = propertyName;
var sn = GenerateShortName(propertyName);
lock(_shortNames)
{
if (!_shortNames.Add(sn))
throw new ArgumentException("This short propertyName has already
been registerd: " + sn, "propertyName");
}
lock (_descriptions)
{
if(_descriptions.ContainsKey(propertyName)) throw new
ArgumentException("This propertyName has already been registerd: " +
propertyName, "propertyName");
_descriptions.Add(propertyName, propertyDescription);
}
}
private static string GenerateLongName(string longName)
{
return "--" + char.ToLower(longName[0]) + longName.Substring(1);
}
private static string GenerateShortName(string longName)
{
var matches = longName.Where(char.IsUpper);
return "-" + string.Join("", matches).ToLower();
}
public override bool CanSupplyValue(ParameterInfo pi,
IComponentContext context, out Func<object> valueProvider)
{
return FoundInCommandLine(pi, out valueProvider);
}
private bool FoundInCommandLine(ParameterInfo pi, out Func<object>
valueProvider)
{
var args = Environment.GetCommandLineArgs();
var idx = Array.IndexOf(args, GenerateShortName(PropertyName));
if(idx < 0)
{
idx = Array.IndexOf(args, GenerateLongName(PropertyName));
}
if(idx < 0)
{
valueProvider = null;
return false;
}
valueProvider = () =>
{
try
{
return Convert.ChangeType(args[idx + 1], pi.ParameterType);
}
catch(Exception ex)
{
ex.Source = GenerateShortName(PropertyName) + "/" +
GenerateLongName(PropertyName);
throw;
}
};
return true;
}
}
}