문제

나는 자신의 모델보기 발표자 패턴 (웹 클라이언트 소프트웨어 공장의 정맥) 사본을 구현하여 수많은 문제가있는 WCSF의 ObjectBuilder에 연결되는 대신 내 자신의 DI 프레임 워크를 활용할 수 있습니다. 나는 그것을 할 수있는 몇 가지 방법을 생각해 냈지만 그들 중 누구도 특히 나를 행복하게하지 않습니다. 다른 사람이 다른 아이디어를 가지고 있는지 알고 싶었습니다.

해결책 #1A

httpmodule을 사용하여 컨텍스트를 가로 채기 위해 객체 actortory.buildup (httpcontext.current.handler)를 호출하려면 컨텍스트를 가로 채기

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }
}

해결책 #1B

httpmodule을 사용하는 대신 페이지로드에서 빌드 업 호출

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        ObjectFactory.BuildUp(this);
    }
}

해결책 #1C

부동산을 통해 발표자를 액세스하면 필요한 경우 getter가 빌드 업을 할 수 있습니다.

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    public EmployeePresenter Presenter
    {
        get
        {
            if (_presenter == null)
            {
                ObjectFactory.BuildUp(this);
            }

            return _presenter;
        }
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }
}

해결책 #2

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        get
        {
            if (_presenter == null)
            {
                _presenter = ObjectFactory.GetInstance<EmployeePresenter>();
                _presenter.View = this;
            }

            return _presenter;
        }
    }
}

해결책 #2B

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        get
        {
            if (_presenter == null)
            {
                Presenter = ObjectFactory.GetInstance<EmployeePresenter>();
            }

            return _presenter;
        }
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }
}

편집하다: 추가 용액 1c, 2b

도움이 되었습니까?

해결책

솔루션 #1B를 사용하고 a 레이어 슈퍼 타입 모든 페이지의 경우 발표자 초기화를 조금 더 건조시키기 위해. 이와 같이:

페이지 코드 :

public partial class _Default : AbstractPage, IEmployeeView
{
    private EmployeePresenter presenter;

    private EmployeePresenter Presenter
    {
        set
        {
            presenter = value;
            presenter.View = this;
        }
    }
    protected override void Do_Load(object sender, EventArgs args)
    {
        //do "on load" stuff 
    }

}

추상 페이지 코드 :

public abstract class AbstractPage : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ObjectFactory.BuildUp(this);
        this.Do_Load(sender,e); 
        //template method, to enable subclasses to mimic "Page_load" event

    }
    //Default Implementation (do nothing)
    protected virtual void Do_Load(object sender, EventArgs e){}
}

이 솔루션을 사용하면 한 클래스에서만 발표자 초기화 (ObjectFactory에 의해 생성)가 있습니다. 나중에 수정 해야하는 경우 쉽게 수행 할 수 있습니다.

편집하다:

do_load해야합니다 요약 또는 가상 ?

템플릿 메소드 원래이 방법은 서브 클래스가이를 구현하도록 강제하여 수퍼 클래스 계약을 준수하기 위해 추상적이어야한다고 말합니다. ( "독점"< "게임"의 Wikipedia 예제 참조).

반면 에이 특정한 경우, 우리는 사용자 클래스가 우리의 방법을 재정의하도록 강요하고 싶지 않지만 그렇게 할 기회를줍니다. 당신이 그것을 추상적으로 선언한다면, 많은 클래스는 그 방법을 비워 두는 방법을 재정의해야합니다 (이것은 분명히 코드 냄새입니다). 따라서 우리는 현명한 기본값을 제공하고 (아무것도하지 않음) 방법을 가상으로 만듭니다.

다른 팁

나는 나 자신의 MVP 프레임 워크를 만들었습니다. 가장 좋은 방법은 기본 페이지 클래스와 함께 제네릭을 사용하는 것입니다. 일반 클래스 정의에서 발표자 유형을 지정하면 각 제안에 필요한 대부분의 코드를 놓칠 수 있습니다.

그러나 그렇게하는 것에 대해 내가 좋아하지 않는 것들이 있습니다. 클래스 정의는 다소 복잡해 보일 수 있으며 초보자를 읽기 쉽지 않습니다. 또한 기본 페이지에서 이벤트 모델을 사용하는 좋은 방법을 완전히 해결하지 못했습니다.

죄송합니다. 여기에 코드가 없지만 원하는 경우 게시 할 수 있습니다. 또한 www.codeplex.com/aspnetmvp에 게시 된 이전 버전의 코드가 있습니다.

나는 다음과 같이 기본 페이지 클래스를 사용하고 있습니다.

protected override void OnInit(EventArgs e)
    {
        StructureMap.ObjectFactory.BuildUp(this);
        base.OnInit(e);
    }

기본 클래스 접근 방식은 사용자 컨트롤에서도 작동합니다. 혼자서 모듈에서 저를 유지했습니다 (두 가지 방법을 설정하고 싶지 않았습니다). 페이지의 경우입니다

public partial class Employee : View, IEmployeeView
{
    public ViewPresenter Presenter { get; set; }
    private void Page_Load(object sender, EventArgs e){}
}

생성자를 통해보기를 주입합니다. StructureMap 구성의 원형 참조 문제를 피하려면이 헬퍼 방법을 사용하십시오.

static T GetView<T>()
{
    return (T) HttpContext.Current.Handler;
}

StructureMap 구성에서 발표자와 뷰 주입 모두에 대한 컨벤션을 사용하십시오.

매우 귀중한 의견에 감사드립니다. 귀하의 답변은 각각 내 최종 솔루션에서 함께 결합 할 수있는 귀중한 아이디어를 주었고 이것이 제가 생각해 낸 것입니다.

public abstract class ViewBasePage<TPresenter, TView> :
    Page where TPresenter : Presenter<TView>
{
    protected TPresenter _presenter;

    public TPresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = GetView();
        }
    }

    /// <summary>
    /// Gets the view. This will get the page during the ASP.NET
    /// life cycle where the physical page inherits the view
    /// </summary>
    /// <returns></returns>    
    private static TView GetView()
    {
        return (TView) HttpContext.Current.Handler;
    }

    protected override void OnPreInit(EventArgs e)
    {
        ObjectFactory.BuildUp(this);
        base.OnPreInit(e);
    }
}

그리고 내 원래 페이지로 상속 :

public partial class _Default : 
    ViewBasePage<EmployeePresenter, IEmployeeView>, IEmployeeView
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            _presenter.OnViewInitialized();
        }

        _presenter.OnViewLoaded();
        Page.DataBind();
    }

    #region Implementation of IEmployeeView

    ...

    #endregion
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top