Grilled the search process for ASP. NET Core MVC Controller

Source: Internet
Author: User

The layout is not very good, we will see it.

There is an interesting and easy-to-ignore feature in ASP. NET core MVC and ASP. The controller can be written in a non-web assembly, such as a Web assembly: "MyWeb", referencing the assembly "BLL", you can write all the controllers in the "BLL" Inside the assembly. The MVC framework can still look for this controller.

Think about it when the MVC framework starts looking for a process: 1. Locate all assemblies that contain the controller; 2. Reflection finds all controller types; 3. The reflection finds all the action;4. Caches these controllers and actions.

The interesting thing is that the first step is "Find all assemblies containing the controller", at first I think it is to scan the assembly that the current application domain has loaded, and then reflection determines that the controller type does not exist. Single If a program has thousands of assemblies, then reflection is a disaster, MVC is not so slow to start With a curious heart, Oxaloacetic took everyone to take a strip of the official implementation principle (ASP. NET MVC source did not go to see, but the principle is estimated to be similar, this is grilled ASP. NET core MVC).

It is recommended that you first understand the startup process for ASP. NET core MVC: http://www.cnblogs.com/savorboard/p/aspnetcore-mvc-startup.html.

Action matches: http://www.cnblogs.com/savorboard/p/aspnetcore-mvc-routing-action.html

Here's a quote from the Yang Xiaodong blog:

1.ADDMVCCORE,MVC Core Boot code:

         Public StaticImvccorebuilder Addmvccore ( Thisiservicecollection Services) {            if(Services = =NULL)            {                Throw NewArgumentNullException (nameof (services)); }            //Gets the Applicationpartmanager management class, which holds the Applicationpart collection, while the Applicationpart most important subclass Assemblypart logs the assembly information. In addition, populatefeature is used to fill various functions            varPartmanager = Getapplicationpartmanager(services); Services.            Tryaddsingleton (Partmanager);            Configuredefaultfeatureproviders (Partmanager);            Configuredefaultservices (services);            Addmvccoreservices (services); varBuilder =NewMvccorebuilder (services, Partmanager); returnBuilder; }

Applicationpartmanager:

    /// <summary>    ///manages the parts and features of an MVC application. /// </summary>     Public classApplicationpartmanager {/// <summary>        ///Gets the list of<see cref= "Iapplicationfeatureprovider"/>S./// </summary>         PublicIlist<iapplicationfeatureprovider> FeatureProviders {Get; } =NewList<iapplicationfeatureprovider>(); /// <summary>        ///Gets the list of<see cref= "Applicationpart"/>S./// </summary>         PublicIlist<applicationpart> Applicationparts {Get; } =NewList<applicationpart>(); /// <summary>        ///populates the given<paramref name= "feature"/>using the list of/// <see cref= "iapplicationfeatureprovider{tfeature}"/>s configured on the/// <see cref= "Applicationpartmanager"/>. /// </summary>        /// <typeparam name= "Tfeature" >The type of the feature.</typeparam>        /// <param name= "feature" >The feature instance to populate.</param>         Public voidPopulatefeature<tfeature>(tfeature feature) {if(Feature = =NULL)            {                Throw NewArgumentNullException (nameof (feature)); }            foreach(varProviderinchFeatureproviders.oftype<iapplicationfeatureprovider<tfeature>>()) {provider.            Populatefeature (applicationparts, feature); }        }    }
View Code

 Private StaticApplicationpartmanager Getapplicationpartmanager(iservicecollection services) {varManager = Getservicefromcollection<applicationpartmanager>(services); if(Manager = =NULL) {Manager=NewApplicationpartmanager (); varEnvironment = Getservicefromcollection<ihostingenvironment>(services); if(string. IsNullOrEmpty (environment?. ApplicationName)) {returnManager; } //Using the default assembly discovery provider to find the assembly, this class is the core class of the lookup varParts =Defaultassemblypartdiscoveryprovider. Discoverassemblyparts (Environment.                ApplicationName); foreach(varPartinchparts) {
           //Add the found assembly to the collection Manager. Applicationparts.add (part); } } returnManager; }

2.DefaultAssemblyPartDiscoveryProvider:

         Public StaticIenumerable<applicationpart> Discoverassemblyparts (stringentrypointassemblyname) {
//Use the application name to load the application's portal assemblyvarentryassembly = Assembly.Load (NewAssemblyName (Entrypointassemblyname)); varContext = dependencycontext. Load (entryassembly);
///Find the candidate assembly, here is the assembly that "may" contain the controller return getcandidateassemblies(entryassembly, context). Select (p =NewAssemblyPart (p)); }

Defaultassemblypartdiscoveryprovider code I'm not all posted (click to view the full source),

A dependencycontext dependency context is used here, noting that this dependency context is not the context of the dependency injection, which refers to the dependency context of the assembly reference relationship.

The implementation principle seems to be a bit low, that is, recursive calculation and determine whether the Assembly has a reference to the MVC assembly, if there is a reference as a candidate assembly.

Here is a calculation method of the core:

            PrivateDependencyclassificationcomputeclassification(stringdependency) {                if(!_runtimedependencies.containskey (dependency)) {                    //The Library does not has runtime dependency. Since we can ' t infer//anything about it ' s references, we'll assume it does not having a reference to MVC.                    returnDependencyclassification.doesnotreferencemvc; }                varCandidateentry =_runtimedependencies[dependency]; if(Candidateentry.classification! =dependencyclassification.unknown) {returncandidateentry.classification; }                Else                {                    varClassification =Dependencyclassification.doesnotreferencemvc; foreach(varCandidatedependencyinchcandidateEntry.Library.Dependencies) {varDependencyclassification = computeclassification(candidatedependency.name); if(dependencyclassification = = Dependencyclassification.referencesmvc | |dependencyclassification==dependencyclassification.mvcreference) {classification=Dependencyclassification.referencesmvc;  Break; }} candidateentry.classification=classification; returnclassification; }            }

Once you have all the candidate assemblies (that is, the assembly that might contain the controller), call Applicationpartmanager's populatefeature to cache the controller type. As for the action of the back and so on no longer grilled, interested can look at the source code.

From this process can be found dependencycontext this class, and Microsoft.Extensions.DependencyModel this library, then we can use this thing can also play a lot of tricks.

Oh, add one more point, we can load the assembly by plug-in:

         Public void configureservices (iservicecollection services)        {            services. ADDMVC ()                . Addapplicationpart (Assembly.LoadFrom (@ "C:\demo\demo.dll"));        }

So from this point, what do you think? I thought of the. NET core MVC plug-in idea.

Grilled the search process for ASP. NET Core MVC Controller

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.