I just published an article about kudystudio. Web. Activating the day before yesterday. I made another change today and provided the source code to you.
Kudystudio. Web. Activating provides two attributes: activationattribute and activationmethodattriating, which can be flexibly registered in your program at any time.One or moreProcessing events triggered before/after appilcation_start () and before appilcation_end.Kudystudio document directory
Download source code kudystudio.web.activating.rar (. net4.0)
The trigger function goals are defined as follows:
/// <summary> /// Specifies the targets to use for invoking activation methods. /// </summary> [Serializable] public enum ActivationMethodTarget { /// <summary> /// Provides expanded support for ASP.NET application pre-start. /// </summary> PreApplicationStart = 0x0, /// <summary> /// Provides expanded support for ASP.NET application post-start. /// </summary> PostApplicationStart, /// <summary> /// Provides expanded support for before ASP.NET application shutdown. /// </summary> PreApplicationEnd }
First introduce activationmethodattribute. This attribute allows youStatic MethodTo register with the AssemblyOne or moreTrigger the function and specify the triggerFunction goalsAndExecution sequenceIt is defined as follows:
/// <summary> /// Provides expanded support for application activation. /// </summary> [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true)] public sealed class ActivationMethodAttribute : OrderableAttribute { #region Constructors /// <summary> /// Initializes a new instance of the ActivationMethodAttribute class. /// </summary> /// <param name="type">An object that describes the type of the activation method.</param> /// <param name="methodName">An empty parameter signature that has no return value.</param> public ActivationMethodAttribute(Type type, string methodName) :this(type, methodName, ActivationMethodTarget.PreApplicationStart) { } /// <summary> /// Initializes a new instance of the ActivationMethodAttribute class. /// </summary> /// <param name="type">An object that describes the type of the activation method.</param> /// <param name="methodName">An empty parameter signature that has no return value.</param> /// <param name="methodTarget">The method target for the associated activation method</param> public ActivationMethodAttribute(Type type, string methodName, ActivationMethodTarget methodTarget) { type.ThrowsIfNull("type"); methodName.ThrowsIfNullOrEmpty("methodName"); if (!Enum.IsDefined(typeof(ActivationMethodTarget), methodTarget)) { throw new ArgumentException("The methodTarget is undefined."); } this.Type = type; this.MethodName = methodName; this.MethodTarget = methodTarget; } #endregion #region Properties /// <summary> /// Gets the type that is returned by the associated activation method. /// </summary> public Type Type { get; private set; } /// <summary> /// Gets the associated activation method. /// </summary> public string MethodName { get; private set; } /// <summary> /// Gets or sets the method target for the associated activation method. /// </summary> public ActivationMethodTarget MethodTarget { get; set; } #endregion }
With the activationmethodattri attribute, the basic requirements can be met, but the activationattribute attribute can make your code organization clearer? Because you do not need to input a function name when registering a trigger function, and each program component can establish its own implementation class (one or more interfaces in ipreapplicationstart, ipostapplicationstart, and ipreapplicationend) it is not mixed with registration transactions of other program components. The activationattribute attribute allows youInterface implementationTo register with the AssemblyOne or moreTrigger the function and specifyExecution sequenceIs defined as follows:
/// <summary> /// Provides expanded support for application activation(s). /// </summary> [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true)] public sealed class ActivationAttribute : OrderableAttribute { #region Constructors /// <summary> /// Initializes a new instance of the ActivationAttribute class. /// </summary> /// <param name="type"> /// An object that implements any activation interface (<see cref="IPreApplicationStart"/>, /// <see cref="IPostApplicationStart"/>, <see cref="IPreApplicationEnd"/>). /// </param> public ActivationAttribute(Type type) { type.ThrowsIfNull("type"); this.Type = type; } #endregion #region Properties /// <summary> /// Gets the type that implements any activation interface. /// </summary> public Type Type { get; private set; } #endregion }
The key implementation is the invokeactivationmethods method of the activationmanager class. The Code is as follows:
private static void InvokeActivationMethods(ActivationMethodTarget target) { List<OrderableAttribute> allAttributes = new List<OrderableAttribute>(); // get all attributes foreach (Assembly assembly in AppAssemblies.Concat(GetCodeAssemblies(target))) { allAttributes.AddRange(GetAttributes<ActivationMethodAttribute>(assembly).Cast<OrderableAttribute>()); allAttributes.AddRange(GetAttributes<ActivationAttribute>(assembly).Cast<OrderableAttribute>()); } // handle all ordered attributes foreach (OrderableAttribute attribute in allAttributes.OrderBy(attr => attr.Order)) { // invokes static method activations ActivationMethodAttribute methodAttribute = attribute as ActivationMethodAttribute; if (methodAttribute != null && methodAttribute.MethodTarget == target) { MethodInfo method = methodAttribute.Type.GetMethod(methodAttribute.MethodName, StaticMethodBindingFlags); if (method != null) { method.Invoke(null, null); continue; // continue next target } // method not found throw new ApplicationException(string.Format("The type {0} doesn't have a static method named {1}.", methodAttribute.Type, methodAttribute.MethodName)); } // try next case: // invokes activations of activation classes that implements any activation interface ActivationAttribute classAttribute = attribute as ActivationAttribute; if (classAttribute != null) { Type type = classAttribute.Type; object activation = null; if (IsValidActivationType(type)) { try { activation = Activator.CreateInstance(type); } catch(Exception ex) { throw new ApplicationException(string.Format("Fail to create instance of type {0}.", methodAttribute.Type), ex); } } else { // invalid activation class throw new ApplicationException(string.Format("The type {0} is not a valid activation class.", type.FullName)); } if (activation != null) { if (target == ActivationMethodTarget.PreApplicationStart && (activation is IPreApplicationStart)) { (activation as IPreApplicationStart).PreApplicationStart(); } else if (target == ActivationMethodTarget.PostApplicationStart && (activation is IPostApplicationStart)) { (activation as IPostApplicationStart).PostApplicationStart(); } else if (target == ActivationMethodTarget.PreApplicationEnd && (activation is IPreApplicationEnd)) { (activation as IPreApplicationEnd).PreApplicationEnd(); } } } } }
In. Net 4.0, a new preapplicationstartmethodattribute class provides only one pre-trigger support. How can I implement pre-trigger and pre-trigger ?. Net4.0 provides a class named dynamicmoduleutility (located in Microsoft. Web. Infrastructure. dll assembly), which has only one method, registermodule (type moduletype), which can be used to dynamically add an httpmodule. The author of webactivator cleverly uses dynamic registration of httpmodule. Trigger postapplicationstart at the initialization of the first httpmodule that processes the trigger event, and trigger preapplicationend at the destruction of the last httpmodule. The core principle is as follows, which is simple as kudystudio. web. the source code in activating is not optimized, because each event is triggered only once in the application cycle, and there is no need to deliberately speed up code loading. In addition, the trigger sequence in webactivator1.5 is only valid for each independent assembly (I don't know if the author intentionally did it), kudystudio. web. the trigger sequence of activating is effective in all the assembly of the entire application (effective refers to the sorting range). If you are interested, please download the source code analysis.
Download kudystudio.web.activating.rar (. net4.0)
Attach the test instance description here. In the activatingweb website project, activatingtest. CS writes the implementation and registration of the trigger function. Global. asax is used for auxiliary testing. The result of running the website is as follows:
All the trigger scripts are executed according to the specified sequence. After web.configis enabled, click Save. The activatingtest.txt content in the website root directory is as follows:
You can see that the preapplicationend trigger function is also executed in order.
The article is over now. If this article is helpful to you, please click "suggestion" to provide support. Thank you. Make sure to indicate the source when reprinting.