导航

08-002 Hosting 之 StartupManager : IStartupManager

Posted on 2015-04-07 10:40  DotNet1010  阅读(134)  评论(0)    收藏  举报

在写MVC的时候,一个很重要的类是 Startup 类。

这个类是谁来执行的呢? 这个就与 StartupManager 相关。

 先看一下接口的代码:

   public interface IStartupManager
    {
        Action<IApplicationBuilder> LoadStartup(
            string applicationName,
            string environmentName);
    }

 这个主要是通过配置文件中配置的 应用程序名称  和 环境名称 来加载Startup类。

其中 applicationName        = config.Get("app")

       environmentName     = config.Get("ASPNET_ENV")?? "Development";   可以不配置 默认是 ”Development"

看一下实现类中唯一的构造函数:

	public StartupManager(IEnumerable<IStartupLoaderProvider> providers)
        {
            _providers = providers;
        }

 关于IStartupLoaderProvider 当前只有一个实现类:

    public class StartupLoaderProvider : IStartupLoaderProvider
    {
        private readonly IServiceProvider _services;

        public StartupLoaderProvider(IServiceProvider services)
        {
            _services = services;
        }

        public int Order { get { return -100; } }

        public IStartupLoader CreateStartupLoader(IStartupLoader next)
        {
            return new StartupLoader(_services, next);
        }
    }

 看一下接口方法实现的代码:

	public Action<IApplicationBuilder> LoadStartup(
            string applicationName,
            string environmentName)
        {
            // build ordered chain of application loaders
            var chain = _providers
                .OrderBy(provider => provider.Order)
                .Aggregate(NullStartupLoader.Instance, (next, provider) => provider.CreateStartupLoader(next));
			/*
			  看一下 Aggregate 的源代码:
            public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed
                    , Func<TAccumulate, TSource, TAccumulate> func) {
               TAccumulate result = seed;
               foreach (TSource element in source) result = func(result, element);
               return result;
            }
			    chain=NullStartupLoader.Instance; //这里是返回null.
				foreach(var pro in providers)
				{
				   chain=pro.CreateStartupLoader(chain);
			    }
	        */


			// invoke chain to acquire application entrypoint and diagnostic messages
	   var diagnosticMessages = new List<string>();
            var application = chain.LoadStartup(applicationName, environmentName, diagnosticMessages);

            if (application == null)
            {
                throw new Exception(diagnosticMessages.Aggregate("TODO: web application entrypoint not found message", (a, b) => a + "\r\n" + b));
            }

            return application;
        }

 LoadStartup 具体的代码 放在下一遍了解一下。