3

仕事で開発しているいくつかの Web サイト用に、やや高度なカスタム フレームワークに取り組んでおり、そのための小さなプラグイン システムを実装しています。たとえば、Page_Init 関数でプラグインを順番に呼び出した後、さまざまなページ イベント (Load、PreRender など) にフックできるように、何らかの形で ASPX ファイルにプラグインを登録したいと考えています。コードに直接ジャンプして、私が何をしたいかを確認します。

<%@ 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>

それらの<% Plugin %>ディレクティブを参照してください。それらは ASP.NET には存在しませんが、作成したいと考えています。この件に関しては、グーグルで何も見つかりません。カスタムを作成することは可能ですか?

私の考えは、それらがそれらのディレクティブに「登録」されると、それらすべて (ディレクティブがヒットするたびに配列に格納されるか、Page_Init イベントで格納される) をループして、それに応じて動作できるということです。

私が持っていた別のアイデアは、代わりにコードブロックを使用することでした:

<%@ 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>

しかし、関数はすべてのページ イベントの前に (または少なくとも Page_Load の前に) 実行されるのではなく、すべてのページ イベントのに呼び出されるため、基本ページの Page_Load イベントなどで適切に動作するためにプラグインが登録されているかどうかを検出する方法がありません。

どんなアイデアでも本当に感謝しています:)。前もって感謝します!

4

2 に答える 2

3

ASP.NET ページ パーサーは、カスタム ディレクティブをサポートしていません (ただし、Page または MasterPage ディレクティブのカスタム属性はサポートしています)。ただし、サーバー コントロールを使用して、必要なことを行うことはできます。

次のような基本プラグイン クラスがあるとします。

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

たとえば、次のような 2 つのプラグイン クラスがあります。

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; }
}

次に、次のように ASPX Web フォーム (または ASCX) を記述できます。

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

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

etc...

これが機能するためには、次のように、web.config などのどこかでプラグインのプレフィックスを宣言する必要があります。

<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>

コード ビハインド クラスでは、次のようなコードを使用して、Init を含むすべてのイベントでプラグインに自動的にアクセスできます。

public partial class WebForm1 : Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        // get all plugins on the page
        var plugins = Controls.OfType<MyPluginBase>();
    }
}
于 2015-04-25T06:34:55.987 に答える
0

WebFormsをサポートするAutofacなどの依存性注入コンテナーを使用します。

プラグインの登録/解決を行うために、列挙またはメタデータ統合の関係タイプを使用することにおそらく関心があるでしょう。

また、MEF と WebForms を併用することで、ある程度の牽引力が得られるかもしれません。 WebForms と MEF のサンプル

于 2015-04-27T23:05:26.793 に答える