2009-11-20 18 views
5

私はasp.net mvcではなく、「カスタマイズ可能な」asp.net Webアプリケーションをビルドする必要があります。依存性注入:aspxページにユーザーコントロールを注入する

私は、ユーザーコントロールをaspxページに挿入するためにIoCコンテナを使用することを考えていました。

誰でもこれを試しましたか?ここで簡単に説明すると

は、私はこれを達成することができますどのように考えるかです:

  • 私は、再利用可能な「ユーザーコントロールライブラリ」を構築するためのスコット・ガスリーのメソッドを使用します(彼の記事「ユーザーコントロールライブラリの作成と使用」を参照してください) 。

  • このライブラリ内のコントロールとページには、ユーザーコントロールを動的に受け取る場所(たとえば、asp PlaceHolder)が必要です。

  • 私のカスタムWebアプリケーションでは、そのライブラリの上に構築され、特定のユーザーコントロールを作成します。

  • 私はそれらをIoCコンテナに入れて、「ユーザーコントロールライブラリ」のコントロール/ページ(PlaceHoldersなど)に挿入できるようにしました。

これだけです。

これは、基本的には、http://blogger.forgottenskies.com/?p=70で説明したようにSpring.Netで行うことができますが、ユーザーコントロールを挿入することです。

誰かにこのようなことに関する経験がありますか?それとも、馬鹿に聞こえる?代替案?

アイデアは、そのライブラリに触れずに、私の 'ユーザーコントロールライブラリ'の上に別のWebアプリケーションを構築する可能性を持つことです。

たとえば、私のライブラリには4つのテキストボックスを持つページがあり、特定のアプリケーションに対しては、ページのコードを変更せずにテキストボックスを1つ追加する必要があります。アイデアは、そのページにプレースホルダーを置き、このプレースホルダーに私のカスタムテキストボックスを動的に注入することです。

答えて

1

類似のモデルを使用して一連のアプリケーションを構築しました。
私たちはUserControlsとWebPartsを注入して各ページを構築するいわゆるPageBuilderを持っています。

すべての設定(ページレイアウト、ページコントロール、コントロールの位置など)は、ページ、UserControlsまたはWebPartsのコードを変更する必要はありません。 (一部の機能を追加/変更する必要がない限り)。

私たちも、それはこのように機能など、SQLクエリ、モード、現在のページのような様々な事柄に応じて動作を変更するコントロール内の構成と設定、

Basiclyを持っている:レイアウトテーブルを作成します

  • 現在のページの
  • 表示するUserControlsおよびWebPartを取得します。
  • 各UserControlとWebPartを正しい位置に配置します。
  • 各UserControlとWebPartに設定を適用します。

すべてのWebPartsは、カスタムパブリッシャ/サブスクライバイベントモデルによって互いに通信できます。私。 WebPart Aでは、ドロップダウン選択が変更されます。> WebPart Bは、選択した項目のデータを表示します。

このモデルを使用すると、私たちが関与する必要なくレイアウトや動作を設計できる高度に構成可能なアプリケーションを構築できます。

あなたのモデルは私たちのモデルのサブセットであると思われます。私が言うことができるのは、使い方が簡単だということです。開発者の視点と顧客の両方から。

編集:
Basicly私たちのフレームワークは、いくつかのマスターページとPageBuilderを呼び出し、ベースページで構成されています。
各マスターページは、ページ、UserControls、WebPart、Lightboxなどのオブジェクトのさまざまな種類に使用されます。
各aspxページには、UserControlsおよびWebParts用のPlaceHolderが含まれています。このPlaceHolderは、PageBuilderによって作成されます。

私たちのaspxページのUserControl/WebPart PlaceHolderには、必要なコントロールを入力することができます。したがって、aspxページを変更する必要は全くありません。テキストボックスが必要な場合は、これを設定できます。カスタムUserControlまたはWebPartにも同じことが起こります。このようにして、カスタムアプリケーションごとにaspxページを再作成する必要はありませんが、設定を変更するだけで済みます。

は、我々は様々なASPXページの100+のUserControlとWebパーツを持っていますが、ほとんどのaspxページは、に似て:PageBuilderが作成

Partial Class MyPageClass Inherits BasePage 
    Protected Sub Page_Init(ByVal sender As Object, ByVal e as System.EventArgs) Handles Me.Init 
    'The following method is in the BasePage and is part of the PageBuilder. 
    LoadControls() 
    End Sub 
End Class 

:私たちのようなものを持っている分離コードで

<%@ Page MasterPageFile="main.master" ... %> 
<asp:Content runat="server" ContentPlaceHolderID="Main" ID="MainSection"> 
    <asp:PlaceHolder runat="server ID="UserControlPlaceHolder"></asp:PlaceHolder> 
</asp:Content> 

レイアウトは、すべてのコントロールとWebPartを正しい位置にロードして追加します。
(コントロールと位置を制御するレイアウトはすべてコンフィギュレーションから取得されます)

次に、PageBuilderは各コントロールとWebPartの設定を適用します。これらの設定も構成可能です。設定は、コントロールの高さなどの単純なものや、「表示モード」(静的、ページ依存、グループ依存など)のような複雑なものにすることができます。

これについて詳しく説明します。

+0

私は、実際には各カスタムアプリケーションで新しいページを再作成したくありません。あなたの "フレームワーク"は、aspxページを変更することなくテキストボックスなどで充実させることができますか? PageBuilderの役割ですか?ビルダーとは誰ですか?詳細を教えてください。 – Thierry

4

状況はまったく同じではありませんが、編集中のエンティティのランタイムタイプに応じてエディタコントロールを動的に挿入する必要がありました。私はすべてのコントロールは、このような共通のインタフェースを継承していた:IoCコンテナ(この場合のStructureMap)を使用して、次に

public interface IEditor 
{ 
    bool CanHandle(EntityBase entity); 
    void Display(EntityBase entity); 
    void Save(EntityBase entity); 
} 

public partial class AddressEditor : UserControl, IEditor 
{ 
    public bool CanHandle(EntityBase entity) 
    { 
     return (entity is Address); 
    } 

    public void Display(EntityBase entity) 
    { 
     var address = (Address)entity; 
     addressLine1Textbox.Text = address.Line1; 
     // etc... 
    } 

    public void Save(EntityBase entity) 
    { 
     var address = (Address)entity; 
     address.Line1 = addressLine1Textbox.Text; 
     // etc... 
    } 
} 

私は

var editorControl = ObjectFactory.GetAllInstancesOf<IEditor>().First(x => x.CanHandle(myEntity)); 

これがあるようなもので、正しいユーザーコントロールを得ることができますただし、面倒な場合は、このようなインスタンスを作成するとページにユーザーコントロールを追加できません。 .ascxファイルの場所を知る必要があります。ようにしますが、それは各制御が戻りエディタインタフェースを介して、それを公開することができます:

public string AscxFile { get { return "~/UserControls/AddressEditor.ascx"; } } // Implements IEditor.AscxFile 

を次に呼び出しページでは、LoadControlを使用します。

var actualControl = LoadControl(editorControl.AscxFile); 
editorPlaceholder.Controls.Add(actualControl); 
editorControl.Display(myEntity); 

私はコンポジットコントロールを使用して好適な、彼らはもう少し努力が必要作成したがた.ascxファイルを心配する必要は、私はちょうどページに直接追加することはできません:あなたはPage.OnInit段階でコントロールを追加していることを確認してください

var editorControl = ObjectFactory.GetAllInstancesOf<IEditor>().First(x => x.CanHandle(myEntity)); 
editorPlaceholder.Controls.Add((Control)editorControl); 
editorControl.Display(myEntity); 

ので、それはViewStateに参加することができ、ポストバックの間に記憶されることはないので、毎回それを行う必要があります。

最後に、IoCツールを使用して配線を行い、StructureMapを使用してIEditorのすべてのインスタンスを自動的に読み込みますが、アプリケーションコードまたはxml設定の任意の時点でこれを変更できます。