1 module glued.application.di.resolveCall; 2 3 import std.meta; 4 import std.traits: moduleName, fullyQualifiedName, isCallable, Parameters, ReturnType; 5 import std.array: join; 6 import std.functional; 7 8 import glued.logging; 9 import glued.annotations; 10 11 import glued.application.di.annotations; 12 13 import dejector; 14 15 auto resolveCall(alias Def, F...)(Dejector injector, F foo) 16 if (isCallable!(F)) 17 { 18 alias R = ReturnType!F; 19 alias P = Parameters!F; 20 auto toCall = cast(R delegate(P)) toDelegate(foo); 21 22 static string generateImports(){ 23 string result; 24 static foreach (p; P){ 25 result ~= "import "~moduleName!p~";\n"; 26 } 27 return result; 28 } 29 30 31 static string generateResolvedExpression(){ 32 //extension point when we introduce environment (key/val config) 33 string result = "toCall("; 34 string[] params; 35 static foreach (i, p; P){ 36 static if (hasOneAnnotation!(parameter!(Def, i), Autowire)) 37 { 38 params ~= "injector.get!("~fullyQualifiedName!(getAnnotation!(parameter!(Def, i), Autowire).Query)~")"; 39 } 40 else 41 { 42 params ~= "injector.get!("~fullyQualifiedName!p~")"; 43 } 44 } 45 result ~= params.join(", "); 46 result ~= ")"; 47 return result; 48 } 49 50 mixin CreateLogger; 51 static if (is(R == void)){ 52 mixin(Logger.logged!(generateImports()~generateResolvedExpression()~";")); 53 } else { 54 mixin(Logger.logged.value!(generateImports()~"return "~generateResolvedExpression()~";")); 55 } 56 }