04. parse the StartUp source code of Asp. Net Core 2.0, asp. netstartup

Source: Internet
Author: User
Tags webhost

04. parse the StartUp source code of Asp. Net Core 2.0, asp. netstartup
04. parse Asp. in the previous article, we set up our own Web application step by step. We created a new StartUp class with only one Configure method and did not inherit from any interfaces, that is to say, Asp. the Net Core 2.0 Framework does not use interfaces to define how to customize the StartUp class for developers. How is this class used by the framework? Download the open source code of Asp. Net Core 2.0 first! I. Review the code for accessing the StartUp class of the framework.

Using Microsoft. aspNetCore. hosting; namespace MyWeb {class Program {static void Main (string [] args) {var host = new WebHostBuilder (). useKestrel () // specify the WebServer as Kestrel. useStartup <StartUpB> () // configure WebHost. build (); host. run (); // start WebHost }}}

The key code for framework access is the WebHostBuilder. UseStartup method. Let's take a look at the framework source code:

public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)        {            var startupAssemblyName = startupType.GetTypeInfo().Assembly.GetName().Name;            return hostBuilder                .UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName)                .ConfigureServices(services =>                {                    if (typeof(IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo()))                    {                        services.AddSingleton(typeof(IStartup), startupType);                    }                    else                    {                        services.AddSingleton(typeof(IStartup), sp =>                        {                            var hostingEnvironment = sp.GetRequiredService<IHostingEnvironment>();                            return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, hostingEnvironment.EnvironmentName));                        });                    }                });        }

First, this is the extension class of the IWebHostBuilder interface. Here there are two branches

1. If StartUp starts fromIStartupAnd add them to the plug-in service framework as a singleton.

2. If it is not fromIStartupInherit, thenPackagingIsIStartupAnd then add it to the plug-in service framework as a singleton.

The Source Code confirms that the ConventionBasedStartup class inheritsIStartup.

public class ConventionBasedStartup : IStartup    {        private readonly StartupMethods _methods;        public ConventionBasedStartup(StartupMethods methods)        {            _methods = methods;        }                public void Configure(IApplicationBuilder app)        {            try            {                _methods.ConfigureDelegate(app);            }            catch (Exception ex)            {                if (ex is TargetInvocationException)                {                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();                }                throw;            }        }        public IServiceProvider ConfigureServices(IServiceCollection services)        {            try            {                return _methods.ConfigureServicesDelegate(services);            }            catch (Exception ex)            {                if (ex is TargetInvocationException)                {                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();                }                throw;            }        }    }
View Code

 Ii. How does the Framework Package our StartUp class?

From the source code, we can see that the key code isStartupLoader. LoadMethodsLet's look at the framework source code (some code is omitted)

public static StartupMethods LoadMethods(IServiceProvider hostingServiceProvider, Type startupType, string environmentName)        {            var configureMethod = FindConfigureDelegate(startupType, environmentName);            var servicesMethod = FindConfigureServicesDelegate(startupType, environmentName);            object instance = null;            if (!configureMethod.MethodInfo.IsStatic || (servicesMethod != null && !servicesMethod.MethodInfo.IsStatic))            {                instance = ActivatorUtilities.GetServiceOrCreateInstance(hostingServiceProvider, startupType);            }            Func<IServiceCollection, IServiceProvider> configureServices = services =>            {                             return services.BuildServiceProvider();            };            return new StartupMethods(instance, configureMethod.Build(instance), configureServices);        }

We guessFindConfigureDelegateMethod connected to our StartUp, the source code confirmed that the Framework obtained ourStartUp. ConfigureMethod: It was originally matched using the method name string class ^_^

private static ConfigureBuilder FindConfigureDelegate(Type startupType, string environmentName)        {            var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true);            return new ConfigureBuilder(configureMethod);        }

 3. Let our StartUp inherit fromIStartup

From the above analysis, we can see that the framework can be connected to two types of StartUp,

  • One is inherited fromIStartupClass
  • The other is includeConfigureMethod class

In this case, ourStartUpCan I directly inherit fromIStartupWhat about it? The experiment proves that the Code is as follows:

Using System; using Microsoft. aspNetCore. hosting; using Microsoft. aspNetCore. builder; using Microsoft. aspNetCore. http; using Microsoft. extensions. dependencyInjection; namespace MyWeb {class StartUpI: IStartup {public void Configure (IApplicationBuilder app) {app. run (c => {var req = c. request. path. toString (). trimStart ('/'); var res = string. empty; switch (req) {case "1": res = "one"; break; case "2": res = "two"; break; default: res = "none"; break;} var mtd = string. empty; switch (c. request. method) {case "GET": mtd = "Request Method: get"; break; case "POST": mtd = "Request Method: post"; break; default: mtd = "Request Method: none"; break;} return c. response. writeAsync (res) ;});} public IServiceProvider ConfigureServices (IServiceCollection services) {return services. buildServiceProvider ();}}}
View Code

We pass this class to the framework.

Using Microsoft. aspNetCore. hosting; namespace MyWeb {class Program {static void Main (string [] args) {var host = new WebHostBuilder (). useKestrel () // specify the WebServer as Kestrel. useStartup <StartUpI> () // configure WebHost. build (); host. run (); // start WebHost }}}

Then run the program and the result is as expected: OK!

 4. The framework implements a base class integrated from IStartup

By searching the reference relationship of IStartup, we can find that the framework implementsAbstractionBase ClassStartupBase:

public abstract class StartupBase : IStartup    {        public abstract void Configure(IApplicationBuilder app);        IServiceProvider IStartup.ConfigureServices(IServiceCollection services)        {            ConfigureServices(services);            return CreateServiceProvider(services);        }        public virtual void ConfigureServices(IServiceCollection services)        {        }        public virtual IServiceProvider CreateServiceProvider(IServiceCollection services)        {            return services.BuildServiceProvider();        }    }

As we can see, you only need to implementConfigureThisAbstract MethodThe StartUp customization can be completed to reduce the development workload. we can implement a subclass:

Using Microsoft. aspNetCore. hosting; using Microsoft. aspNetCore. builder; using Microsoft. aspNetCore. http; namespace MyWeb {class StartUpB: StartupBase {public override void Configure (IApplicationBuilder app) {app. run (c => {var req = c. request. path. toString (). trimStart ('/'); var res = string. empty; switch (req) {case "1": res = "one"; break; case "2": res = "two"; break; default: res = "none"; break;} var mtd = string. empty; switch (c. request. method) {case "GET": mtd = "Request Method: get"; break; case "POST": mtd = "Request Method: post"; break; default: mtd = "Request Method: none"; break;} return c. response. writeAsync (res );});}}}
View Code

We pass this class to the framework.

Using Microsoft. aspNetCore. hosting; namespace MyWeb {class Program {static void Main (string [] args) {var host = new WebHostBuilder (). useKestrel () // specify the WebServer as Kestrel. useStartup <StartUpB> () // configure WebHost. build (); host. run (); // start WebHost }}}

Then run the program and the result is as expected: OK!

 V. Performance Analysis

Now we have figured out how ASP. Net Core2.0 can access the StartUp class in three ways:

1. Define a class by yourself, which must containConfigureMethod

2. inherited fromIStartup, Implement all methods

3. inherited fromStartupBaseAbstract class, which only needs to be implementedConfigureMethod

I think the third method is more efficient, for two reasons:

1. You only need to implement one method with the least code

2. Reflection is not required and the efficiency is higher.

I don't know. The first method is used by default when Microsoft creates an ASP. Net Core2.0 project. From which perspective ???

 

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.