void SetConstructor() { var ctor = Type.TryGetConstructors().OrderBy(x => x.GetParameters().Length).FirstOrDefault(); if (ctor == null) { #if NET472 || NETCOREAPP2_1 if (Type.GetTypeInfo().IsValueType) { fastCtor = EmitHelper.CreateParameterlessConstructorHandler(Type); } #endif return; } var ps = ctor.GetParameters(); var cargs = new object[ps.Length]; for (int i = 0; i < ps.Length; i++) { var p = ps[i]; if (!p.HasDefaultValue) { return; } cargs[i] = p.DefaultValue; } emtpy_constructor = new FastMethod(ctor); empty_params = cargs; }
public static object Create(ITypeTree <ServiceDefinition> services, ITypeTree <object> scope, Type type, params object[] parameters) { if (type.IsValueType) { return(Activator.CreateInstance(type)); } if (scope == null) { scope = new TypeTree <object>(); } bool first = createSession == null; if (first) { createSession = new List <ICreateCallback>(); } try { // private constructor are private for a reason, don't use them! var ctor = FindConstructors(services, scope, type).FirstOrDefault(x => x.IsPublic); if (ctor == null) { throw new InvalidOperationException($"Type {type.FullName} can't be Activated, no constructor can be called at this time."); } var pis = ctor.GetParameters(); var cargs = new object[pis.Length]; for (int i = 0; i < pis.Length; i++) { var p = pis[i]; var impa = p.GetCustomAttribute <ImportAttribute>(); var t = (impa != null ? impa.ImportedType : null) ?? p.ParameterType; var descendant = MergeKeys(services, scope, t).Where(x => x != type).FirstOrDefault(); var val = parameters != null?parameters.FirstOrDefault(x => t.IsInstanceOfType(x)) : null; if (val != null) { cargs[i] = val; } else if (descendant != null) { cargs[i] = SolveExact(services, scope, descendant); } else if (p.HasDefaultValue) { cargs[i] = p.DefaultValue; } else if (CanBeInstantiated(t)) { cargs[i] = Resolve(services, scope, t).FirstOrDefault(); } } var fc = FastMethod.GetMethod(ctor); var result = fc.Invoke(null, cargs); if (scope != null) { scope[type] = result; } if (result is ICreateCallback) { createSession.Add((ICreateCallback)result); } ResolveProperties(services, scope, result); return(result); } finally { if (first) { for (int i = 0; i < createSession.Count; i++) { ((ICreateCallback)createSession[i]).OnCreated(); } createSession = null; } } }