Skip to content

Commit 8cb230d

Browse files
committed
Add support for generic IDictionary<string,obj> query inputs
1 parent e2ff051 commit 8cb230d

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/FSharp.Data.GraphQL.Server/Values.fs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,30 @@ let rec internal compileByType
105105

106106
| InputObject objDef ->
107107
let objtype = objDef.Type
108-
let ctor = ReflectionHelper.matchConstructor objtype (objDef.Fields |> Array.map (fun x -> x.Name))
108+
let (constructor : obj[] -> obj), (parameterInfos : Reflection.ParameterInfo[]) =
109+
if typeof<IDictionary<string,obj>>.IsAssignableFrom(objtype) then
110+
let parameterInfos = [|
111+
for f in objDef.Fields ->
112+
{ new Reflection.ParameterInfo() with
113+
member _.Name = f.Name
114+
member _.ParameterType = f.TypeDef.Type
115+
member _.Attributes = Reflection.ParameterAttributes.Optional
116+
}
117+
|]
118+
let constructor (args:obj[]) =
119+
let o = Activator.CreateInstance(objtype)
120+
let dict = o :?> IDictionary<string, obj>
121+
for fld,arg in Seq.zip objDef.Fields args do
122+
dict.Add(fld.Name, arg)
123+
box o
124+
constructor, parameterInfos
125+
else
126+
let ctor = ReflectionHelper.matchConstructor objtype (objDef.Fields |> Array.map (fun x -> x.Name))
127+
ctor.Invoke, ctor.GetParameters()
128+
109129

110130
let struct (mapper, nullableMismatchParameters, missingParameters) =
111-
ctor.GetParameters ()
131+
parameterInfos
112132
|> Array.fold
113133
(fun struct (all : ResizeArray<_>, areNullable : HashSet<_>, missing : HashSet<_>) param ->
114134
match
@@ -188,7 +208,7 @@ let rec internal compileByType
188208

189209
let! args = argResults |> splitSeqErrorsList
190210

191-
let instance = ctor.Invoke args
211+
let instance = constructor args
192212
do!
193213
objDef.Validator instance
194214
|> ValidationResult.mapErrors (fun err ->
@@ -201,7 +221,6 @@ let rec internal compileByType
201221
| true, found ->
202222
match found with
203223
| :? IReadOnlyDictionary<string, obj> as objectFields ->
204-
205224
let argResults =
206225
mapper
207226
|> Seq.map (fun struct (field, param) -> result {
@@ -217,7 +236,7 @@ let rec internal compileByType
217236

218237
let! args = argResults |> splitSeqErrorsList
219238

220-
let instance = ctor.Invoke args
239+
let instance = constructor args
221240
do!
222241
objDef.Validator instance
223242
|> ValidationResult.mapErrors (fun err ->

0 commit comments

Comments
 (0)