1
1
using Newtonsoft . Json ;
2
2
using System ;
3
+ using System . Collections ;
3
4
using System . Collections . Generic ;
4
5
using System . Linq ;
5
6
using System . Linq . Dynamic . Core ;
6
7
using System . Linq . Expressions ;
7
8
using System . Reflection ;
8
9
using System . Text ;
10
+ using Newtonsoft . Json . Linq ;
9
11
using WorkflowCore . Interface ;
10
12
using WorkflowCore . Models ;
11
13
using WorkflowCore . Primitives ;
@@ -24,10 +26,10 @@ public DefinitionLoader(IWorkflowRegistry registry)
24
26
_registry = registry ;
25
27
}
26
28
27
- public WorkflowDefinition LoadDefinition ( string json )
29
+ public WorkflowDefinition LoadDefinition ( string source , Func < string , DefinitionSourceV1 > deserializer )
28
30
{
29
- var source = JsonConvert . DeserializeObject < DefinitionSourceV1 > ( json ) ;
30
- var def = Convert ( source ) ;
31
+ var sourceObj = deserializer ( source ) ;
32
+ var def = Convert ( sourceObj ) ;
31
33
_registry . RegisterWorkflow ( def ) ;
32
34
return def ;
33
35
}
@@ -171,13 +173,24 @@ private void AttachInputs(StepSourceV1 source, Type dataType, Type stepType, Wor
171
173
{
172
174
var dataParameter = Expression . Parameter ( dataType , "data" ) ;
173
175
var contextParameter = Expression . Parameter ( typeof ( IStepExecutionContext ) , "context" ) ;
174
- var sourceExpr = DynamicExpressionParser . ParseLambda ( new [ ] { dataParameter , contextParameter } , typeof ( object ) , input . Value ) ;
176
+ var environmentVarsParameter = Expression . Parameter ( typeof ( IDictionary ) , "environment" ) ;
177
+ var stepProperty = stepType . GetProperty ( input . Key ) ;
175
178
176
- var stepParameter = Expression . Parameter ( stepType , "step" ) ;
177
- var targetProperty = Expression . Property ( stepParameter , input . Key ) ;
178
- var targetExpr = Expression . Lambda ( targetProperty , stepParameter ) ;
179
+ if ( input . Value is string )
180
+ {
181
+ var acn = BuildScalarInputAction ( input , dataParameter , contextParameter , environmentVarsParameter , stepProperty ) ;
182
+ step . Inputs . Add ( new ActionParameter < IStepBody , object > ( acn ) ) ;
183
+ continue ;
184
+ }
179
185
180
- step . Inputs . Add ( new MemberMapParameter ( sourceExpr , targetExpr ) ) ;
186
+ if ( ( input . Value is IDictionary < string , object > ) || ( input . Value is IDictionary < object , object > ) )
187
+ {
188
+ var acn = BuildObjectInputAction ( input , dataParameter , contextParameter , environmentVarsParameter , stepProperty ) ;
189
+ step . Inputs . Add ( new ActionParameter < IStepBody , object > ( acn ) ) ;
190
+ continue ;
191
+ }
192
+
193
+ throw new ArgumentException ( $ "Unknown type for input { input . Key } on { source . Id } ") ;
181
194
}
182
195
}
183
196
@@ -221,5 +234,52 @@ private Type FindType(string name)
221
234
return Type . GetType ( name , true , true ) ;
222
235
}
223
236
237
+ private static Action < IStepBody , object , IStepExecutionContext > BuildScalarInputAction ( KeyValuePair < string , object > input , ParameterExpression dataParameter , ParameterExpression contextParameter , ParameterExpression environmentVarsParameter , PropertyInfo stepProperty )
238
+ {
239
+ var expr = System . Convert . ToString ( input . Value ) ;
240
+ var sourceExpr = DynamicExpressionParser . ParseLambda ( new [ ] { dataParameter , contextParameter , environmentVarsParameter } , typeof ( object ) , expr ) ;
241
+
242
+ void acn ( IStepBody pStep , object pData , IStepExecutionContext pContext )
243
+ {
244
+ object resolvedValue = sourceExpr . Compile ( ) . DynamicInvoke ( pData , pContext , Environment . GetEnvironmentVariables ( ) ) ;
245
+ if ( stepProperty . PropertyType . IsEnum )
246
+ stepProperty . SetValue ( pStep , Enum . Parse ( stepProperty . PropertyType , ( string ) resolvedValue , true ) ) ;
247
+ else
248
+ stepProperty . SetValue ( pStep , System . Convert . ChangeType ( resolvedValue , stepProperty . PropertyType ) ) ;
249
+ }
250
+ return acn ;
251
+ }
252
+
253
+ private static Action < IStepBody , object , IStepExecutionContext > BuildObjectInputAction ( KeyValuePair < string , object > input , ParameterExpression dataParameter , ParameterExpression contextParameter , ParameterExpression environmentVarsParameter , PropertyInfo stepProperty )
254
+ {
255
+ void acn ( IStepBody pStep , object pData , IStepExecutionContext pContext )
256
+ {
257
+ var stack = new Stack < JObject > ( ) ;
258
+ var destObj = JObject . FromObject ( input . Value ) ;
259
+ stack . Push ( destObj ) ;
260
+
261
+ while ( stack . Count > 0 )
262
+ {
263
+ var subobj = stack . Pop ( ) ;
264
+ foreach ( var prop in subobj . Properties ( ) . ToList ( ) )
265
+ {
266
+ if ( prop . Name . StartsWith ( "@" ) )
267
+ {
268
+ var sourceExpr = DynamicExpressionParser . ParseLambda ( new [ ] { dataParameter , contextParameter , environmentVarsParameter } , typeof ( object ) , prop . Value . ToString ( ) ) ;
269
+ object resolvedValue = sourceExpr . Compile ( ) . DynamicInvoke ( pData , pContext , Environment . GetEnvironmentVariables ( ) ) ;
270
+ subobj . Remove ( prop . Name ) ;
271
+ subobj . Add ( prop . Name . TrimStart ( '@' ) , JToken . FromObject ( resolvedValue ) ) ;
272
+ }
273
+ }
274
+
275
+ foreach ( var child in subobj . Children < JObject > ( ) )
276
+ stack . Push ( child ) ;
277
+ }
278
+
279
+ stepProperty . SetValue ( pStep , destObj ) ;
280
+ }
281
+ return acn ;
282
+ }
283
+
224
284
}
225
285
}
0 commit comments