private ConstructorInfoCache FindConstructorRecursive(Type type) { ConstructorInfo constructorInfo = null; ConstructorInfo[] allConstructors = type.GetConstructors(BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (allConstructors.Length > 0) { // Choose the first... constructorInfo = allConstructors[0]; // Iterate on the others for [Constructor]... foreach (ConstructorInfo info in allConstructors) { if (info.GetCustomAttributes(typeof(ConstructorAttribute), true).Length <= 0) { continue; } constructorInfo = info; break; } } if (constructorInfo == null) { return(null); } var constructorInfoCache = new ConstructorInfoCache(constructorInfo, GetParameterInfoCache(constructorInfo.GetParameters())); return(constructorInfoCache); }
private object CreateInstance(Type type) { if (!_cachedDefaultConstructor.ContainsKey(type)) { // Find first constructor without parameters... ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ConstructorInfo constructor = null; foreach (ConstructorInfo info in constructors) { if (info.GetParameters().Length == 0) { constructor = info; break; } } if (constructor != null) { ConstructorInfoCache constructorInfoCache = new ConstructorInfoCache(constructor, GetParameterInfoCache(constructor.GetParameters())); _cachedDefaultConstructor.Add(type, constructorInfoCache); } else { _cachedDefaultConstructor.Add(type, null); } } if (_cachedDefaultConstructor[type] != null) { return(_cachedDefaultConstructor[type].ConstructorInfo.Invoke(null)); } return(Activator.CreateInstance(type)); }
private object ExecuteConstructor(IContainer container, IInjectContext parentContext, ConstructorInfoCache constructor, Type type, params object[] addDependencies) { ParameterInfoCache[] parameters = constructor.Parameters; if (parameters == null || parameters.Length == 0) { return(constructor.ConstructorInfo.Invoke(null)); } // Resolve parameters object[] paramObjects = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfoCache parameter = parameters[i]; ParameterInfo parameterInfo = parameter.ParameterInfo; // Can we resolve this? if (container.HasBindingFor(parameterInfo.ParameterType)) { bool isCircularDependency = false; foreach (Type resolvingType in _currentlyResolvingTypes) { if (parameterInfo.ParameterType.IsAssignableFrom(resolvingType)) { isCircularDependency = true; } } // Prevent recursive / circular dependency... if (isCircularDependency) { LogHandler?.Invoke("Injector: Circular dependency detected in Type {0} parameter index: {1}", type, i); paramObjects[i] = null; } else { InjectContext injectContext = new InjectContext(container, constructor.DeclaringType, parentContext); object paramInstance = container.ResolveWithCategory(parameterInfo.ParameterType, parameters[i].InjectAttribute?.Category, injectContext); paramObjects[i] = paramInstance; } } else { bool hasAdditionalDependency = false; // Check additional dependencies... foreach (object dependency in addDependencies) { if (parameterInfo.ParameterType.IsInstanceOfType(dependency)) { hasAdditionalDependency = true; paramObjects[i] = dependency; break; } } if (!hasAdditionalDependency) { LogHandler?.Invoke("Injector: {0} - Type is not bound in the container, assigning as null {1}, parameter index: {2}", type, parameterInfo.ParameterType, i); paramObjects[i] = null; } } } // Invoke constructor... object instance = constructor.ConstructorInfo.Invoke(paramObjects); return(instance); }