예제 #1
0
        public Action <IApplicationBuilder> LoadStartup(
            string applicationName,
            string environmentName,
            IList <string> diagnosticMessages)
        {
            if (String.IsNullOrEmpty(applicationName))
            {
                return(_next.LoadStartup(applicationName, environmentName, diagnosticMessages));
            }

            var assembly = Assembly.Load(new AssemblyName(applicationName));

            if (assembly == null)
            {
                throw new Exception(String.Format("TODO: assembly {0} failed to load message", applicationName));
            }

            var startupName1 = "Startup" + environmentName;
            var startupName2 = "Startup";

            // Check the most likely places first
            var type =
                assembly.GetType(startupName1) ??
                assembly.GetType(applicationName + "." + startupName1) ??
                assembly.GetType(startupName2) ??
                assembly.GetType(applicationName + "." + startupName2);

            if (type == null)
            {
                // Full scan
                var definedTypes = assembly.DefinedTypes.ToList();

                var startupType1 = definedTypes.Where(info => info.Name.Equals(startupName1, StringComparison.Ordinal));
                var startupType2 = definedTypes.Where(info => info.Name.Equals(startupName2, StringComparison.Ordinal));

                var typeInfo = startupType1.Concat(startupType2).FirstOrDefault();
                if (typeInfo != null)
                {
                    type = typeInfo.AsType();
                }
            }

            if (type == null)
            {
                throw new Exception(String.Format("TODO: {0} or {1} class not found in assembly {2}",
                                                  startupName1,
                                                  startupName2,
                                                  applicationName));
            }

            var configureMethod = FindMethod(type, "Configure{0}", environmentName, typeof(void), required: true);
            var servicesMethod  = FindMethod(type, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false)
                                  ?? FindMethod(type, "Configure{0}Services", environmentName, typeof(void), required: false);

            object instance = null;

            if (!configureMethod.IsStatic || (servicesMethod != null && !servicesMethod.IsStatic))
            {
                instance = ActivatorUtilities.GetServiceOrCreateInstance(_services, type);
            }
            return(builder =>
            {
                if (servicesMethod != null)
                {
                    var services = HostingServices.Create(builder.ApplicationServices);
                    // TODO: remove this once IHttpContextAccessor service is added
                    services.AddContextAccessor();
                    if (servicesMethod.ReturnType == typeof(IServiceProvider))
                    {
                        // IServiceProvider ConfigureServices(IServiceCollection)
                        builder.ApplicationServices = (Invoke(servicesMethod, instance, builder, services) as IServiceProvider)
                                                      ?? builder.ApplicationServices;
                    }
                    else
                    {
                        // void ConfigureServices(IServiceCollection)
                        Invoke(servicesMethod, instance, builder, services);
                        if (builder != null)
                        {
                            builder.ApplicationServices = services.BuildServiceProvider();
                        }
                    }
                }
                Invoke(configureMethod, instance, builder);
            });
        }
예제 #2
0
        public Action<IBuilder> LoadStartup(
            string applicationName,
            string environmentName,
            IList<string> diagnosticMessages)
        {
            if (String.IsNullOrEmpty(applicationName))
            {
                return _next.LoadStartup(applicationName, environmentName, diagnosticMessages);
            }

            var assembly = Assembly.Load(new AssemblyName(applicationName));
            if (assembly == null)
            {
                throw new Exception(String.Format("TODO: assembly {0} failed to load message", applicationName));
            }

            var startupName1 = "Startup" + environmentName;
            var startupName2 = "Startup";

            // Check the most likely places first
            var type =
                assembly.GetType(startupName1) ??
                assembly.GetType(applicationName + "." + startupName1) ??
                assembly.GetType(startupName2) ??
                assembly.GetType(applicationName + "." + startupName2);

            if (type == null)
            {
                // Full scan
                var definedTypes = assembly.DefinedTypes.ToList();

                var startupType1 = definedTypes.Where(info => info.Name.Equals(startupName1, StringComparison.Ordinal));
                var startupType2 = definedTypes.Where(info => info.Name.Equals(startupName2, StringComparison.Ordinal));

                var typeInfo = startupType1.Concat(startupType2).FirstOrDefault();
                if (typeInfo != null)
                {
                    type = typeInfo.AsType();
                }
            }

            if (type == null)
            {
                throw new Exception(String.Format("TODO: {0} or {1} class not found in assembly {2}", 
                    startupName1,
                    startupName2,
                    applicationName));
            }

            var configureMethod1 = "Configure" + environmentName;
            var configureMethod2 = "Configure";
            var methodInfo = type.GetTypeInfo().GetDeclaredMethod(configureMethod1);
            if (methodInfo == null)
            {
                methodInfo = type.GetTypeInfo().GetDeclaredMethod(configureMethod2);
            }
            if (methodInfo == null)
            {
                throw new Exception(string.Format("TODO: {0} or {1} method not found",
                    configureMethod1,
                    configureMethod2));
            }

            if (methodInfo.ReturnType != typeof(void))
            {
                throw new Exception(string.Format("TODO: {0} method isn't void-returning.",
                    methodInfo.Name));
            }

            object instance = null;
            if (!methodInfo.IsStatic)
            {
                instance = ActivatorUtilities.GetServiceOrCreateInstance(_services, type);
            }

            return builder =>
            {
                var parameterInfos = methodInfo.GetParameters();
                var parameters = new object[parameterInfos.Length];
                for (var index = 0; index != parameterInfos.Length; ++index)
                {
                    var parameterInfo = parameterInfos[index];
                    if (parameterInfo.ParameterType == typeof(IBuilder))
                    {
                        parameters[index] = builder;
                    }
                    else
                    {
                        try
                        {
                            parameters[index] = _services.GetService(parameterInfo.ParameterType);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(string.Format(
                                "TODO: Unable to resolve service for startup method {0} {1}",
                                parameterInfo.Name,
                                parameterInfo.ParameterType.FullName));
                        }
                    }
                }
                methodInfo.Invoke(instance, parameters);
            };
        }