2009-11-20 6 views
5

'사용자 정의 가능한'asp.net 웹 응용 프로그램 (asp.net mvc 아님)을 빌드해야합니다.의존성 주입 : aspx 페이지에 사용자 컨트롤 삽입하기

나는 사용자 컨테이너를 aspx 페이지에 삽입하기 위해 IoC 컨테이너를 사용하려고 생각하고있었습니다.

아무도 시도하지 않았습니까? (그의 기사 "사용자 제어 라이브러리 만들기 및 사용"참조)

  • 내가 재사용이 가능한 '사용자 컨트롤 라이브러리'를 구축 스콧 오클라호마의 방법을 사용하십시오 여기에 간단히

    내가이 달성 될 수 있다고 생각하는 방법이다 .

  • 해당 라이브러리의 컨트롤 및 페이지에는 사용자 컨트롤을 동적으로 수신 할 수있는 장소가 있어야합니다 (예 : asp PlaceHolder).

  • 내 사용자 지정 웹 응용 프로그램에서 해당 라이브러리 위에 구축 된 특정 사용자 정의 컨트롤을 만듭니다.

  • 나는 '사용자 컨트롤 라이브러리'(예 : PlaceHolders)의 컨트롤/페이지에 삽입 할 수 있도록 IoC 컨테이너에 삽입했습니다.

그게 전부입니다.

이것은 기본적으로 여기에 설명 된대로 Spring.Net에서 수행 할 수 있지만 사용자 컨트롤을 삽입하는 것입니다.

그런 경험이있는 사람이 있습니까? 아니면 어리석은가요? 대안?

아이디어는 해당 라이브러리를 건드리지 않고 내 '사용자 제어 라이브러리'위에 다른 웹 응용 프로그램을 빌드 할 수있는 가능성을 갖는 것입니다.

예를 들면 : 내 라이브러리에 4 개의 텍스트 상자가있는 페이지가 있고 특정 응용 프로그램에 대해 페이지 코드를 변경하지 않고 텍스트 상자 하나를 추가해야합니다. 아이디어는 해당 페이지에 자리 표시자를 놓고이 자리 표시 자에 내 사용자 정의 텍스트 상자를 동적으로 주입하는 것입니다.

답변

1

우리는 유사한 모델을 사용하여 응용 프로그램 모음을 만들었습니다.
우리는 UserControls 및 WebParts를 주입하여 각 페이지를 구성하는 소위 PageBuilder를 보유하고 있습니다.

페이지, UserControls 또는 WebParts의 코드를 변경할 필요가 없도록 모든 것을 구성 할 수 있습니다 (페이지 레이아웃, 페이지 컨트롤, 컨트롤 위치 등). (일부 기능을 추가/변경해야하는 경우 제외).

우리는 심지어 SQL 쿼리 모드, 현재 페이지 등

Basicly를이 같이 작동 같은 다양한 것들에 따라 동작을 변경할 컨트롤 내에서 구성 및 설정을

:

  • 는 레이아웃 테이블을 만듭니다 현재 페이지.
  • 표시 할 UserControls 및 WebParts를 가져옵니다.
  • 각 UserControl 및 WebPart를 올바른 위치에 배치하십시오.
  • 각 UserControl 및 WebPart에 설정을 적용하십시오.

모든 웹 파트는 사용자 지정 게시자/구독자 이벤트 모델을 통해 서로 통신 할 수 있습니다. 나는. WebPart A에서 드롭 다운 선택이 바뀜 => WebPart B는 선택된 항목에 대한 데이터를 보여줍니다.

이 모델을 사용하면 우리가 관여 할 필요없이 고객이 레이아웃과 동작을 디자인 할 수있는 구성 가능한 응용 프로그램을 만들 수 있습니다.

귀하의 모델은 우리 모델의 일부분 인 것처럼 보이며 작업하기 쉽습니다. 개발자와 고객 모두에게 도움이됩니다.

편집 :
Basicly 우리의 프레임 워크는 PageBuilder를 호출하는 몇 마스터 페이지와 기본 페이지로 구성되어 있습니다.
각 마스터 페이지는 페이지, UserControls, WebPart, Lightbox 등 다양한 유형의 개체에 사용됩니다.
각 aspx 페이지에는 UserControls 및 WebParts 용 PlaceHolder가 포함되어 있습니다. 이 PlaceHolder는 PageBuilder에 의해 채워집니다.

우리의 aspx 페이지에있는 UserControl/WebPart PlaceHolder는 원하는 모든 컨트롤로 채울 수 있습니다. 따라서 aspx 페이지를 전혀 변경할 필요가 없습니다. 우리가 텍스트 박스를 원한다면 이것을 설정할 수 있습니다. 사용자 지정 UserControl 또는 WebPart에 대해서도 동일합니다. 이 방법으로 각 사용자 지정 응용 프로그램의 aspx 페이지를 다시 만들 필요는 없지만 구성 만 변경하면됩니다.

우리는 다양한 영문 페이지 100+ 된 UserControls과 WebParts을 가지고 있지만 대부분의 영문 페이지는 비슷한 봐 : 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> 

레이아웃은 모든 컨트롤과 웹 파트를 올바른 위치에로드하고 추가합니다.
(레이아웃에서 컨트롤 및 컨트롤 위치를 모두 구성에서 가져옵니다.)

그런 다음 PageBuilder는 각 컨트롤 및 WebPart에 대한 설정을 적용합니다. 이러한 설정도 구성 할 수 있습니다. 설정은 컨트롤의 높이만큼 단순하거나 "디스플레이 모드"(정적, 페이지 종속적, 그룹 종속적 등)와 같은 더 복잡한 것일 수 있습니다.

더 자세히 설명합니다.

+0

실제로 각 사용자 지정 응용 프로그램에서 새 페이지를 다시 만들고 싶지는 않습니다. "프레임 워크"를 사용하면 텍스트 상자와 같이 수정하지 않고도 aspx 페이지를 풍부하게 만들 수 있습니까? PageBuilder의 역할입니까? 누가 빌더라고 부르죠? 세부 사항을 알려주시겠습니까? – Thierry

4

상황과 완전히 같지 않지만 편집중인 엔티티의 런타임 유형에 따라 편집기 컨트롤을 동적으로 삽입해야합니다. 내 모든 컨트롤은 다음과 같이 공통 인터페이스를 상속했다 :

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

그리고 (이 경우 StructureMap)는 IoC 컨테이너를 사용하여 나는 이것은

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 구성의 어느 지점에서든지이를 변경할 수 있습니다.