Create custom ASP.NET directive (not MVC)?

I am working on a somewhat advanced custom framework for some of the websites I develop at work and I am implementing a small plugin system for it. I want to somehow register the plugins in the ASPX file so that I can then connect to the various page events (Load, PreRender, etc.) after calling them sequentially in my Page_Init function, for example. I'll go straight to the code so you can see what I want to do:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Plugin TypeName="MyFramework.Plugin.Core" Arg1="arg1" Arg2="arg2" %>
<%@ Plugin TypeName="MyFramework.Plugin.MainMenu" Arg1="arg1" Arg2="arg2" %>
<%@ Plugin TypeName="MyFramework.Plugin.IE6Hacks" Arg1="arg1" Arg2="arg2" %>
<%@ Plugin TypeName="MyFramework.Plugin.Footer2015" Arg1="arg1" Arg2="arg2" %>
<%@ Plugin TypeName="MyFramework.Plugin.SortableGridViews" Arg1="arg1" Arg2="arg2" %>

<!DOCTYPE html>
<html>
<head runat="server">
    <title>blah</title>
</head>
<body>      
    <form id="form1" runat="server"> Blah... </form>
</body>
</html>

      

See these directives <% Plugin %>

? they don't exist in ASP.NET, but I want to create them. I can't find anything on Google regarding this stuff. Is it possible to create a custom one?

My idea is that once they are "registered" with these directives, I can skip all of them (stored in an array every time the directive is hit, or in the Page_Init event) and act accordingly.

Another idea I used was to use blocks of code instead:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<% RegisterPlugin("MyFramework.Plugin.Core"); %>
<% RegisterPlugin("MyFramework.Plugin.MainMenu"); %>
<% RegisterPlugin("MyFramework.Plugin.IE6Hacks"); %>
<% RegisterPlugin("MyFramework.Plugin.Footer2015"); %>
<% RegisterPlugin("MyFramework.Plugin.SortableGridViews"); %>

<!DOCTYPE html>
<html>
<head runat="server">
    <title>blah</title>
</head>
<body>      
    <form id="form1" runat="server"> Blah... </form>
</body>
</html>

      

BUT functions are called after all page events instead of firing them before them (or at least before Page_Load), leaving me unrecognizable if I have plugins registered to act accordingly on my main Page_Load page events and such.

Any ideas are really appreciated :). Thanks in advance!

+3


source to share


2 answers


The ASP.NET page parser does not support custom directives (although it does support custom attributes in the Pages directive or MasterPage). But you can still do what you want using server controls.

Suppose you have a base plugin class like:

// we derive from control, so all plugins are automatically
// added to the Page.Controls collection
public class MyPluginBase : Control
{
}

      

And, for example, two plugin classes like this:

public class MyPlugin : MyPluginBase
{
    public string MyFirstProperty { get; set; }
    public int MySecondProperty { get; set; }
}

public class MyOtherPlugin : MyPluginBase
{
    public string MyFirstProperty { get; set; }
    public int MySecondProperty { get; set; }
}

      

Then you can write an ASPX (or ASCX) webform like:



<%@ Page ... standard attributes ... %>

<plugins:MyPlugin runat="server" MyFirstProperty="blah" MySecondProperty="1"></plugins:MyPlugin>
<plugins:MyOtherPlugin runat="server" MyFirstProperty="blahblah" MySecondProperty="2"></plugins:MyOtherPlugin>

etc...

      

Note: for this you will need to declare the plugin prefix somewhere, for example in your web.config file, for example:

<configuration>
  <system.web>
    <pages>
      <controls>
        <!-- all assemblies & namespaces that contain plugins classes -->
        <add assembly="WebApplication1" namespace="WebApplication1.Code" tagPrefix="plugins" />
        <add assembly="MyOtherPlugins" namespace="MyOtherPlugins.Plugins" tagPrefix="plugins" />
      </controls>
    </pages>
  </system.web>
</configuration>

      

And in the code behind the class, you will have automatic access to plugins in all events, including Init, with this code:

public partial class WebForm1 : Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        // get all plugins on the page
        var plugins = Controls.OfType<MyPluginBase>();
    }
}

      

+3


source


Use a dependency injection container like Autofac which supports WebForms .

You will probably be interested in using Enumeration or Metadata Integerrogation to do the registration / resolution of the plugin.



You can also find some grip using MEF with WebForms. Examples of WebForms and MEF

0


source







All Articles