示例#1
0
        private static void ReplaceWithGenericTypeModel(Type requestedType, ref InjectionModel existingModel)
        {
            var typeArgs    = requestedType.GetGenericArguments();
            var genericType = existingModel.Type.MakeGenericType(typeArgs);

            var(_, deliveryMode, instance, speckName, configuration) = existingModel;
            existingModel = new InjectionModel(genericType, deliveryMode, instance, speckName, configuration);
        }
示例#2
0
        internal static object InstantiateSpeck(Type requestedType, InjectionModel existingModel, Func <Type, bool> hasSpeck, Func <Type, string, object> getSpeck, Func <ParameterInfo, bool> hasConfiguration, string configurationName)
        {
            object    instantiatedSpeck = null;
            Exception innerException    = null;

            var isGenericTypeRequired = (requestedType != existingModel.Type) && (requestedType.IsGenericType && existingModel.Type.IsGenericType);

            if (isGenericTypeRequired)
            {
                ReplaceWithGenericTypeModel(requestedType, ref existingModel);
            }

            var constructors = existingModel
                               .Type
                               .GetConstructors()
                               .OrderByDescending(x => x.GetParameters().Count());

            foreach (var constructor in constructors)
            {
                var instantiatedParameters = constructor
                                             .GetParameters()
                                             .Where(p => hasSpeck(p.ParameterType) || hasConfiguration(p))
                                             .Select(p => getSpeck(p.ParameterType, p.GetCustomAttribute <SpeckyConfigurationAttribute>()?.ConfigurationName ?? configurationName))
                                             .ToArray();

                try
                {
                    instantiatedSpeck = Activator.CreateInstance(existingModel.Type, instantiatedParameters);
                    break;
                }
                catch (Exception exception)
                {
                    innerException = new Exception(exception.Message, innerException);
                }
            }

            return(instantiatedSpeck
                   ?? throw new Exception($"Could not instantiate {existingModel.Type.Name}", innerException));
        }