The Thing before MVC series (7): Webactivator of the implementation of the principle of the explanation (reprint)

Source: Internet
Author: User

The thing that happened before MVC series (7): Webactivator's implementation principle
Article content

In the previous article, we analyzed how to dynamically register the implementation of HttpModule, this article to analyze the Webactivator class library implemented by the previous code principle, Webactivator provides 3 kinds of functions, Allow us to execute the specified code separately before HttpApplication initialization, and then shutdown, as in the following example:

[Assembly:WebActivator.PreApplicationStartMethod (typeof"prestart")] [ Assembly:WebActivator.PostApplicationStartMethod (typeof"poststart" )][assembly:webactivator.applicationshutdownmethod (typeof"ShutDown ")]

In addition, there is a bit different from the preapplicationstartmethodattribute of the system, each of the Webactivator features can be used multiple times, such as:

[Assembly:WebActivator.PreApplicationStartMethod (typeof"prestart")] [ Assembly:WebActivator.PreApplicationStartMethod (typeof"prestart") ][assembly:webactivator.preapplicationstartmethod (typeof"prestart" )]

Because it has very few source code, so today we will be a comprehensive analysis of the implementation of Webactivator principle, first download Webactivator the latest 1.5 source code, source address: HTTPS://BITBUCKET.ORG/DAVIDEBBO/WEBACTIVATOR/SRC

Extract the code, we can see the Webactivator project in a total of 6 important CS files, As well as a packages.config file (for tagging this project referencing the Microsoft.Web.Infrastructure.dll class library), let's analyze the source code of each file.

3 a Xxxmethodattribute property:

Based on the above usage, we instruct Webactivator to provide 3 Methodattribute, let's first look at how these 3 files are implemented, the lookup code discovers 3 classes (preapplicationstartmethodattribute/ Postapplicationstartmethodattribute/applicationshutdownmethodattribute) content is the same, are inherited from the Baseactivationmethodattribute class, and then provide the type and method names required by the constructor, 3 attribute classes are supported using multiple times and can only be used for assembly, the code is as follows:

true)]
generic base class Baseactivationmethodattribute:
usingSystem;usingSystem.Reflection;namespacewebactivator{//Base class of all the activation attributes[AttributeUsage (attributetargets.assembly, AllowMultiple =true)]     Public Abstract classBaseactivationmethodattribute:attribute {PrivateType _type; Private string_methodname;  PublicBaseactivationmethodattribute (Type type,stringmethodName) {_type=type; _methodname=MethodName; }         PublicType type {Get{return_type;} }         Public stringMethodName {Get{return_methodname;} }         Public intOrder {Get;Set; }  Public voidInvokeMethod () {//Get the methodMethodInfo method =Type.getmethod (MethodName, bindingflags.static| BindingFlags.NonPublic |bindingflags.public); if(Method = =NULL)            {                Throw NewArgumentException (String.Format ("The type {0} doesn ' t has a static method named {1}", Type, MethodName)); }            //Invoke ItMethod. Invoke (NULL,NULL); }    }}

Through the code, we can first see that, in addition to the type and MethodName, there is an order attribute, which is used to mark the order of execution when the same attribute is used more than once. A InvokeMethod method is then provided to execute the MethodName static method in the class that passes in the current type class.

Assembly extension method Assemblyextensions:
usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Reflection;namespacewebactivator{Static classassemblyextensions {//Return All the attributes of a given type from an assembly         Public StaticIenumerable<t> getactivationattributes<t> ( ThisAssembly Assembly)whereT:baseactivationmethodattribute {returnAssembly. GetCustomAttributes (typeof(T), Inherit:false). Oftype<t>(); }    }}

The extension method is primarily used to get all attribute of the specified type under an assembly assembly (and does not include inherited classes), that is, to query the attributes of the 3 attributes above (because each one allows multiple declarations).

Main Management class Activationmanager:

This class is mainly divided into the following parts:

1 private static function assemblies, Getassemblyfiles is primarily to obtain all DLL assemblies under the current application for other methods to traverse the corresponding feature declarations from this Assembly collection.
//to load all acquired assembliesPrivate StaticIenumerable<assembly>assemblies{Get    {        if(_assemblies = =NULL)        {            //Cache the list of relevant assemblies, since we need it for both Pre and Post_assemblies =NewList<assembly>(); foreach(varAssemblyFileinchGetassemblyfiles ()) {                Try                {                    //Ignore Assemblies We can ' t load. They could be native, etc ..._assemblies.                ADD (Assembly.LoadFrom (assemblyfile)); }                Catch                {                }            }        }        return_assemblies; }}//get assembly file path collectionPrivate Staticienumerable<string>Getassemblyfiles () {//When running under ASP. NET, find assemblies in the Bin folder. //Outside of ASP, use whatever folder Webactivator itself are in    stringDirectory =hostingenvironment.ishosted?HttpRuntime.BinDirectory:Path.GetDirectoryName (typeof(Activationmanager).    Assembly.location); returnDirectory.GetFiles (Directory,"*.dll");}
2 Gets the compiled assembly of all Appcode folders under code.
//Return all the App_Code assembliesPrivate StaticIenumerable<assembly>appcodeassemblies{Get    {        //Return An empty list if We;re not hosted or there aren ' t any        if(! hostingenvironment.ishosted | | !_hasinited | | Buildmanager.codeassemblies = =NULL)        {            returnEnumerable.empty<assembly>(); }        returnBuildmanager.codeassemblies.oftype<assembly>(); }}
3 Perform the methods specified in the 3 features
 Public Static voidRunprestartmethods () {runactivationmethods<PreApplicationStartMethodAttribute>();} Public Static voidRunpoststartmethods () {runactivationmethods<PostApplicationStartMethodAttribute>();} Public Static voidRunshutdownmethods () {runactivationmethods<ApplicationShutdownMethodAttribute>();}//Call the relevant activation method from all assembliesPrivate Static voidRunactivationmethods<t> ()wheret:baseactivationmethodattribute{foreach(varAssemblyinchAssemblies.concat (appcodeassemblies)) {        foreach(Baseactivationmethodattribute ActivationattribinchAssembly. Getactivationattributes<t> (). (Att =Att.        Order) {Activationattrib.invokemethod (); }    }}

As can be seen from the code, the 3 attribute execution method calls are the same generic method Runactivationmethods<t>, in this method, mainly from all the assemblies, through the generic method to query the characteristics of all tags (ordered by order), and executes the method specified in each attribute declaration. In addition, from Assemblies.concat (appcodeassemblies), all assemblies are also included in the code-compiled assembly of the App_Code directory.

4 Custom HttpModule
classstartmethodcallingmodule:ihttpmodule{Private Static Object_lock =New Object(); Private Static int_initializedmodulecount;  Public voidInit (HttpApplication context) {Lock(_lock) {//Keep track of the number of modules initialized and//Make sure we have call the post start methods once per app domain            if(_initializedmodulecount++ = =0) {runpoststartmethods (); }        }    }     Public voidDispose () {Lock(_lock) {//Call the shutdown methods If the last module is disposed            if(--_initializedmodulecount = =0) {runshutdownmethods (); }        }    }}

This module is primarily used to execute the method of the Poststart type at init time, and executes the shutdown type method at Dispose, and executes only once.

5. The most important method of entry
 Public Static voidRun () {if(!_hasinited)        {runprestartmethods (); //Register Our module to handle any Post Start methods. But outside of ASP. Just run them now        if(hostingenvironment.ishosted) {Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtili Ty. Registermodule (typeof(Startmethodcallingmodule)); }        Else{runpoststartmethods (); } _hasinited=true; }}

The Run method looks easy to understand, first executes the method of the Prestart type, and then determines whether the hostingenvironment host succeeds, and if successful, dynamically registers our custom HttpModule above, In order for the module to execute Poststart type method and shutdown type method at HttpApplication initialization and Dispose, if no host succeeds, then only the method of Poststart type is executed.

Note: As can be seen from the code implementation, in the Prestart type method, the HttpContext object cannot be used for input and output because the object is not created successfully at this time.

6. Who called the Portal Method run ()

This will not have to say more, it must be used. Net4.0 comes with the Preapplicationstartmethodattribute feature, the code is as follows:

[Assembly:preapplicationstartmethod (typeof"Run")]

You can leave this code outside of the namespace of any class file in the Webactivator project, but for the sake of unification, it is usually placed in the AssemblyInfo class file under the properties directory, which is what Webactivator does.

Summary, well, this is webactivator all the source code, the implementation is actually very simple, right? Once the project has a similar demand, use this class library boldly, and NINJECT.MVC is also based on this kind of library.

Resources:

Http://blogs.msdn.com/b/davidebb/archive/2010/10/11/light-up-your-nupacks-with-startup-code-and-webactivator.aspx

Https://bitbucket.org/davidebbo/webactivator/src

Synchronization and recommendations

This article has been synchronized to the directory index: Thelittle Thing before MVC series

MVC before the point of the series of articles, including the original, translation, reprint and other types of articles, if it is useful to you, please recommend supporting a, to the power of the uncle writing.

Original link This article by Bean John Blog Backup expert remote One click release

What happened before MVC series (7): The implementation principle of Webactivator (reprint)

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.