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 }