@@ -92,51 +92,81 @@ public IEnumerable<INetDaemonAppBase> Instances
9292
9393 var valueType = entry . Value . NodeType ;
9494
95- switch ( valueType )
96- {
97- case YamlNodeType . Sequence :
98- SetPropertyFromYaml ( netDaemonApp , prop , ( YamlSequenceNode ) entry . Value ) ;
99- break ;
100-
101- case YamlNodeType . Scalar :
102- SetPropertyFromYaml ( netDaemonApp , prop , ( YamlScalarNode ) entry . Value ) ;
103- break ;
95+ var instance = InstanceProperty ( netDaemonApp , prop . PropertyType , entry . Value ) ;
10496
105- case YamlNodeType . Mapping :
106- var map = ( YamlMappingNode ) entry . Value ;
107- break ;
108- }
97+ prop . SetValue ( netDaemonApp , instance ) ;
10998 }
11099
111100 return netDaemonApp ;
112101 }
113102
114- public void SetPropertyFromYaml ( INetDaemonAppBase app , PropertyInfo prop , YamlSequenceNode seq )
103+ private object ? InstanceProperty ( Object ? parent , Type instanceType , YamlNode node )
115104 {
116- if ( prop . PropertyType . IsGenericType && prop . PropertyType ? . GetGenericTypeDefinition ( ) == typeof ( IEnumerable < > ) )
105+
106+ if ( node . NodeType == YamlNodeType . Scalar )
117107 {
118- Type listType = prop . PropertyType ? . GetGenericArguments ( ) [ 0 ] ??
119- throw new NullReferenceException ( $ "The property { prop . Name } of Class { app . GetType ( ) . Name } is not compatible with configuration") ;
108+ var scalarNode = ( YamlScalarNode ) node ;
109+ ReplaceSecretIfExists ( scalarNode ) ;
110+ return ( ( YamlScalarNode ) node ) . ToObject ( instanceType ) ;
111+ }
112+ else if ( node . NodeType == YamlNodeType . Sequence )
113+ {
114+ if ( instanceType . IsGenericType && instanceType ? . GetGenericTypeDefinition ( ) == typeof ( IEnumerable < > ) )
115+ {
116+ Type listType = instanceType ? . GetGenericArguments ( ) [ 0 ] ??
117+ throw new NullReferenceException ( $ "The property { instanceType ? . Name } of Class { parent ? . GetType ( ) . Name } is not compatible with configuration") ;
120118
121- IList list = listType . CreateListOfPropertyType ( ) ??
122- throw new NullReferenceException ( "Failed to create listtype, plese check {prop.Name} of Class {app.GetType().Name}" ) ;
119+ IList list = listType . CreateListOfPropertyType ( ) ??
120+ throw new NullReferenceException ( "Failed to create listtype, plese check {prop.Name} of Class {app.GetType().Name}" ) ;
123121
124- foreach ( YamlNode item in seq . Children )
125- {
126- if ( item . NodeType != YamlNodeType . Scalar )
122+ foreach ( YamlNode item in ( ( YamlSequenceNode ) node ) . Children )
127123 {
128- throw new NotSupportedException ( $ "The property { prop . Name } of Class { app . GetType ( ) . Name } is not compatible with configuration") ;
124+
125+ var instance = InstanceProperty ( null , listType , item ) ??
126+ throw new NotSupportedException ( $ "The class { parent ? . GetType ( ) . Name } has wrong type in items") ;
127+
128+ list . Add ( instance ) ;
129129 }
130- var scalarNode = ( YamlScalarNode ) item ;
131- ReplaceSecretIfExists ( scalarNode ) ;
132- var value = ( ( YamlScalarNode ) item ) . ToObject ( listType ) ??
133- throw new NotSupportedException ( $ "The class { app . GetType ( ) . Name } and property { prop . Name } has wrong type in items") ;
134130
135- list . Add ( value ) ;
131+ return list ;
132+ }
133+ }
134+ else if ( node . NodeType == YamlNodeType . Mapping )
135+ {
136+ var instance = Activator . CreateInstance ( instanceType ) ;
137+
138+ foreach ( KeyValuePair < YamlNode , YamlNode > entry in ( ( YamlMappingNode ) node ) . Children )
139+ {
140+ string ? scalarPropertyName = ( ( YamlScalarNode ) entry . Key ) . Value ;
141+ // Just continue to next configuration if null or class declaration
142+ if ( scalarPropertyName == null ) continue ;
143+
144+ var childProp = instanceType . GetYamlProperty ( scalarPropertyName ) ??
145+ throw new MissingMemberException ( $ "{ scalarPropertyName } is missing from the type { instanceType } ") ;
146+
147+ var valueType = entry . Value . NodeType ;
148+ Object ? result = null ;
149+
150+ switch ( valueType )
151+ {
152+ case YamlNodeType . Sequence :
153+ result = InstanceProperty ( instance , childProp . PropertyType , ( YamlSequenceNode ) entry . Value ) ;
154+
155+ break ;
156+
157+ case YamlNodeType . Scalar :
158+ result = InstanceProperty ( instance , childProp . PropertyType , ( YamlScalarNode ) entry . Value ) ;
159+ break ;
160+
161+ case YamlNodeType . Mapping :
162+ var map = ( YamlMappingNode ) entry . Value ;
163+ break ;
164+ }
165+ childProp . SetValue ( instance , result ) ;
136166 }
137- // Bind the list to the property
138- prop . SetValue ( app , list ) ;
167+ return instance ;
139168 }
169+ return null ;
140170 }
141171
142172 private void ReplaceSecretIfExists ( YamlScalarNode scalarNode )
@@ -149,16 +179,6 @@ private void ReplaceSecretIfExists(YamlScalarNode scalarNode)
149179 scalarNode . Value = secretReplacement ?? throw new ApplicationException ( $ "{ scalarNode . Value ! } not found in secrets.yaml") ;
150180 }
151181
152- public void SetPropertyFromYaml ( INetDaemonAppBase app , PropertyInfo prop , YamlScalarNode sc )
153- {
154- ReplaceSecretIfExists ( sc ) ;
155- var scalarValue = sc . ToObject ( prop . PropertyType ) ??
156- throw new NotSupportedException ( $ "The class { app . GetType ( ) . Name } and property { prop . Name } unexpected value { sc . Value } is wrong type") ;
157-
158- // Bind the list to the property
159- prop . SetValue ( app , scalarValue ) ;
160- }
161-
162182 private string ? GetTypeNameFromClassConfig ( YamlMappingNode appNode )
163183 {
164184 KeyValuePair < YamlNode , YamlNode > classChild = appNode . Children . Where ( n =>
0 commit comments