@@ -249,7 +249,12 @@ public enum SettingsFlags
249249 Default = ShortNames | NoSlashes
250250 }
251251
252- public interface ICommandLineComponentFactory
252+ /// <summary>
253+ /// An IComponentFactory that is used in the command line.
254+ ///
255+ /// This allows components to be created by name, signature type, and a settings string.
256+ /// </summary>
257+ public interface ICommandLineComponentFactory : IComponentFactory
253258 {
254259 Type SignatureType { get ; }
255260 string Name { get ; }
@@ -1649,10 +1654,10 @@ public bool Finish(CmdParser owner, ArgValue val, object destination)
16491654
16501655 var values = val . Values ;
16511656 bool error = false ;
1652-
1653- void BuildSubComponent ( SubComponent com )
1657+ if ( IsSingleSubComponent )
16541658 {
16551659 bool haveKind = false ;
1660+ var com = SubComponent . Create ( ItemType ) ;
16561661 for ( int i = 0 ; i < Utils . Size ( values ) ; )
16571662 {
16581663 string str = ( string ) values [ i ] . Value ;
@@ -1673,25 +1678,41 @@ void BuildSubComponent(SubComponent com)
16731678
16741679 if ( Utils . Size ( values ) > 0 )
16751680 com . Settings = values . Select ( x => ( string ) x . Value ) . ToArray ( ) ;
1676- }
16771681
1678- if ( IsSingleSubComponent )
1679- {
1680- var com = SubComponent . Create ( ItemType ) ;
1681- BuildSubComponent ( com ) ;
16821682 Field . SetValue ( destination , com ) ;
16831683 }
16841684 else if ( IsSingleComponentFactory )
16851685 {
1686- var com = new SubComponent ( ) ;
1687- BuildSubComponent ( com ) ;
1686+ bool haveName = false ;
1687+ string name = null ;
1688+ string [ ] settings = null ;
1689+ for ( int i = 0 ; i < Utils . Size ( values ) ; )
1690+ {
1691+ string str = ( string ) values [ i ] . Value ;
1692+ if ( str . StartsWith ( "{" ) )
1693+ {
1694+ i ++ ;
1695+ continue ;
1696+ }
1697+ if ( haveName )
1698+ {
1699+ owner . Report ( "Duplicate component kind for argument {0}" , LongName ) ;
1700+ error = true ;
1701+ }
1702+ name = str ;
1703+ haveName = true ;
1704+ values . RemoveAt ( i ) ;
1705+ }
1706+
1707+ if ( Utils . Size ( values ) > 0 )
1708+ settings = values . Select ( x => ( string ) x . Value ) . ToArray ( ) ;
16881709
16891710 Contracts . Check ( _signatureType != null , "ComponentFactory Arguments need a SignatureType set." ) ;
16901711 var factory = ComponentFactoryFactory . CreateComponentFactory (
16911712 ItemType ,
16921713 _signatureType ,
1693- com . Kind ,
1694- com . Settings ) ;
1714+ name ,
1715+ settings ) ;
16951716 Field . SetValue ( destination , factory ) ;
16961717 }
16971718 else if ( IsMultiSubComponent )
@@ -1819,24 +1840,27 @@ void BuildSubComponent(SubComponent com)
18191840 return error ;
18201841 }
18211842
1843+ /// <summary>
1844+ /// A factory class for creating IComponentFactory instances.
1845+ /// </summary>
18221846 private static class ComponentFactoryFactory
18231847 {
18241848 public static IComponentFactory CreateComponentFactory (
1825- Type fieldType ,
1849+ Type factoryType ,
18261850 Type signatureType ,
18271851 string name ,
18281852 string [ ] settings )
18291853 {
1830- Contracts . Check ( fieldType != null &&
1831- typeof ( IComponentFactory ) . IsAssignableFrom ( fieldType ) &&
1832- fieldType . IsGenericType ) ;
1854+ Contracts . Check ( factoryType != null &&
1855+ typeof ( IComponentFactory ) . IsAssignableFrom ( factoryType ) &&
1856+ factoryType . IsGenericType ) ;
18331857
18341858 Type componentFactoryType ;
1835- if ( fieldType . GenericTypeArguments . Length == 1 )
1859+ if ( factoryType . GenericTypeArguments . Length == 1 )
18361860 {
18371861 componentFactoryType = typeof ( ComponentFactory < > ) ;
18381862 }
1839- else if ( fieldType . GenericTypeArguments . Length == 2 )
1863+ else if ( factoryType . GenericTypeArguments . Length == 2 )
18401864 {
18411865 componentFactoryType = typeof ( ComponentFactory < , > ) ;
18421866 }
@@ -1846,7 +1870,7 @@ public static IComponentFactory CreateComponentFactory(
18461870 }
18471871
18481872 return ( IComponentFactory ) Activator . CreateInstance (
1849- componentFactoryType . MakeGenericType ( fieldType . GenericTypeArguments ) ,
1873+ componentFactoryType . MakeGenericType ( factoryType . GenericTypeArguments ) ,
18501874 signatureType ,
18511875 name ,
18521876 settings ) ;
@@ -1856,7 +1880,7 @@ private abstract class ComponentFactory : ICommandLineComponentFactory
18561880 {
18571881 public Type SignatureType { get ; }
18581882 public string Name { get ; }
1859- protected string [ ] Settings { get ; }
1883+ private string [ ] Settings { get ; }
18601884
18611885 protected ComponentFactory ( Type signatureType , string name , string [ ] settings )
18621886 {
@@ -1899,7 +1923,8 @@ public TComponent CreateComponent(IHostEnvironment env)
18991923 SignatureType ,
19001924 out TComponent result ,
19011925 Name ,
1902- CombineSettings ( Settings ) ) ) ;
1926+ GetSettingsString ( ) ) ,
1927+ $ "Unknown loadable class: '{ Name } ' SignatureType: '{ SignatureType } '") ;
19031928
19041929 return result ;
19051930 }
@@ -1919,8 +1944,9 @@ public TComponent CreateComponent(IHostEnvironment env, TArg1 argument1)
19191944 SignatureType ,
19201945 out TComponent result ,
19211946 Name ,
1922- CombineSettings ( Settings ) ,
1923- argument1 ) ) ;
1947+ GetSettingsString ( ) ,
1948+ argument1 ) ,
1949+ $ "Unknown loadable class: '{ Name } ' SignatureType: '{ SignatureType } '") ;
19241950
19251951 return result ;
19261952 }
0 commit comments