public object CreateInstance(ObjectImpl impl) { List <ObjectImpl> types = ResolveCtorTypes(impl); object[] parms = ResolveCtorParams(types); return(impl.oType.GetConstructor(types.Select(p => p.iType).ToArray()).Invoke(parms)); }
public List <ObjectImpl> ResolveCtorTypes(ObjectImpl impl) { List <ObjectImpl> types = new List <ObjectImpl>(); List <ConstructorInfo> ctors = new List <ConstructorInfo>(); // fetch and sort constructors ascendingly by number of parameters. foreach (ConstructorInfo ctor in impl.oType.GetConstructors()) { ctors.Add(ctor); } ctors.Sort((a, b) => { return(a.GetParameters().Count().CompareTo(b.GetParameters().Count())); }); // try to resolve the ctor with the maximum number of parameters. // the first one wins bool ctorResolved = false; for (int i = ctors.Count() - 1, j = 0; i >= j; i--) { bool paramResolved = true; ConstructorInfo ctor = ctors[i]; ParameterInfo[] parms = ctor.GetParameters(); foreach (ParameterInfo parm in parms) { Type parmType = parm.ParameterType; if (parmType == typeof(IContext)) { types.Add(new ObjectImpl() { iType = typeof(IContext), oType = context.GetType() }); continue; } // try to resolve param // scan services KeyValuePair <string, ObjectImpl> implSvc = context.Services.FirstOrDefault(p => p.Value.iType == parmType); paramResolved = !string.IsNullOrEmpty(implSvc.Key); if (paramResolved) { types.Add(implSvc.Value); continue; } // scan modules KeyValuePair <string, ObjectImpl> implMod = context.Modules.FirstOrDefault(p => p.Value.iType == parmType); paramResolved = !string.IsNullOrEmpty(implMod.Key); if (paramResolved) { types.Add(implMod.Value); continue; } // scan views KeyValuePair <string, ObjectImpl> implView = context.Views.FirstOrDefault(p => p.Value.iType == parmType); paramResolved = !string.IsNullOrEmpty(implView.Key); if (paramResolved) { types.Add(implView.Value); continue; } // cant resolve this parameter? break and go to next ctor if (!paramResolved) { break; } } // piss of as soon as it resolves one of the ctors if (paramResolved) { ctorResolved = true; break; } // if not resolved go to next ctor } if (ctorResolved) { return(types); } else { return(new List <ObjectImpl>()); } }