Ejemplo n.º 1
0
            static object GetDependency(CommandService commandService, ConstructorInfo ctor, IServiceProvider provider, Type serviceType)
            {
                if (serviceType == typeof(IServiceProvider) || serviceType == provider.GetType())
                {
                    return(provider);
                }

                if (serviceType == typeof(CommandService) || serviceType == commandService.GetType())
                {
                    return(commandService);
                }

                var service = provider.GetService(serviceType);

                if (service == null)
                {
                    throw new InvalidOperationException($"Failed to instantiate {ctor.DeclaringType}, dependency of type {serviceType} was not found.");
                }

                return(service);
            }
Ejemplo n.º 2
0
        public static Func <IServiceProvider, T> CreateProviderConstructor <T>(CommandService commandService, Type type)
        {
            var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

            if (constructors.Length == 0)
            {
                throw new InvalidOperationException($"{type} has no public non-static constructors.");
            }

            if (constructors.Length > 1)
            {
                throw new InvalidOperationException($"{type} has multiple public constructors.");
            }

            object GetDependency(ConstructorInfo ctor, IServiceProvider provider, Type serviceType)
            {
                if (serviceType == typeof(IServiceProvider) || serviceType == provider.GetType())
                {
                    return(provider);
                }

                if (serviceType == typeof(CommandService) || serviceType == typeof(ICommandService) || serviceType == commandService.GetType())
                {
                    return(commandService);
                }

                var service = provider.GetService(serviceType);

                if (service != null)
                {
                    return(service);
                }

                throw new InvalidOperationException($"Failed to instantiate {ctor.DeclaringType}, dependency of type {serviceType} was not found.");
            }

            var constructor        = constructors[0];
            var parameters         = constructor.GetParameters();
            var arguments          = new object[parameters.Length];
            var propertiesToInject = new List <PropertyInfo>();

            do
            {
                var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                for (var i = 0; i < properties.Length; i++)
                {
                    var property = properties[i];
                    if (property.SetMethod != null && !property.SetMethod.IsStatic && property.SetMethod.IsPublic &&
                        property.GetCustomAttribute <DoNotInjectAttribute>() == null)
                    {
                        propertiesToInject.Add(property);
                    }
                }

                type = type.BaseType.GetTypeInfo();
            }while (type != typeof(object));

            return((provider) =>
            {
                for (var i = 0; i < parameters.Length; i++)
                {
                    arguments[i] = GetDependency(constructor, provider, parameters[i].ParameterType);
                }

                T instance;
                try
                {
                    instance = (T)constructor.Invoke(arguments);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"Failed to instantiate {constructor.DeclaringType}. See the inner exception for more details.", ex);
                }

                for (var i = 0; i < propertiesToInject.Count; i++)
                {
                    var property = propertiesToInject[i];
                    property.SetValue(instance, GetDependency(constructor, provider, property.PropertyType));
                }

                return instance;
            });
        }