Get Accessor for Presenter in ASPX pages

Topics: User Forum
Jan 8, 2007 at 11:44 AM
Is there any reason why the Presenter doesn't have a get accessor in the code-behind of the pages (i.e. views)?

Since in the presenter you can write;

View.DoSomeWork();

... it seems logical to be able to do;

Presenter.BookMyService();

... in the view.

Any thoughts / comments?
Jan 8, 2007 at 1:28 PM
In the ConfirmTransfersView.aspx.cs file you have:

CreateNew
public ConfirmTransfersViewPresenter Presenter
{
get { return _presenter; }
set
{
_presenter = value;
_presenter.View = this;
}
}

and:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_presenter.OnViewInitialized();
}
_presenter.OnViewLoaded();
}

Isn't this what you are talking about?
Jan 9, 2007 at 8:58 AM
Yes that's exactly what I mean. That way any methods on the page can use "Presenter" (i.e. the property) rather than "_presenter". This just feels more like using a published API to me.

But checking code I generated with the current drop of the factory;

<code>

private DefaultViewPresenter _presenter;

protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this._presenter.OnViewInitialized();
}
this._presenter.OnViewLoaded();
}

CreateNew
public DefaultViewPresenter Presenter
{
set
{
this._presenter = value;
this._presenter.View = this;
}
}

</code>

There doesn't appear to be a "get" generated automatically. If the page code behind model was to change in the WCSF, use of the private field could break, but use of the property wouldn't if it was part of the public API (I'm being presumptious here, but I think you can see what I'm getting at).

On the same subject, is there any reason why pages do not inherit from a generic base page? e.g;

public partial class Default : WcsfPage<DefaultPresenter>, IDefaultView

This would enable the inclusion of the presenter property and wire-up code in the base page, cleaning up the code behind a little.
Jan 9, 2007 at 9:49 AM
Following my last comment, I've now posted an example base page class under "Base Page Class" in the developer forum, which seemed more appropriate.

I'm still interested in the get accessor question here though!
Jan 9, 2007 at 10:09 AM
simonice wrote:
<<
On the same subject, is there any reason why pages do not inherit from a generic base page? e.g;

public partial class Default : WcsfPage<DefaultPresenter>, IDefaultView

This would enable the inclusion of the presenter property and wire-up code in the base page, cleaning up the code behind a little
>>

Your idea seems good, but the problem i believe is that the guys want to be able to inject the Presenter.

But if one could write the Definition like this and get the viewproperty of the presenter correct this would have been the best approach.

public class WcsfPage<T, I> : Page
{
private T _presenter;

CreateNew
public virtual T Presenter
{
get
{
return _presenter;
}
set
{
_presenter = value;

// Will This Work?
_presenter.view = (I) this;
}
}
}

And This should be the code

public partial class Default : WcsfPage<IDefaultPresenter, IDefaultView>, IDefaultView
Jan 9, 2007 at 10:22 AM
Looks similar to my solution - have a look at;

http://www.codeplex.com/websf/Project/DisplayThread.aspx?ForumId=1269&ThreadId=3415&ANCHOR#LastPost

I've used the "as" keyword to cast the page class to the View interface's type, as you can't implement it in the generic type obviously. A bit of runtime reflection could verify this if needed, but to be honest I don't see the point (and it probably won't be worth the overhead).

I'm not certain the CreateNew attribute will be inherited correctly though?

Having said that, I've seen this working in a demo solution I've got...
Jan 9, 2007 at 10:37 AM
This solution worked well, but i dont like the SetView solution.

public abstract class WcsfPage<T> : System.Web.UI.Page
{
private T _presenter;

CreateNew
public T Presenter
{
get
{
return _presenter;
}
set
{
_presenter = value;
setView();
// Will This Work?
// _presenter.view = (I)this;
}
}

public abstract void setView();
}


public partial class ElectronicFundsTransfer_NewTransferView : WcsfPage<NewTransferViewPresenter>, INewTransferView
{
public override void SetView()
{
Presenter.View = this;
}
Jan 9, 2007 at 10:46 AM
I know what you're getting at, but as you say, it still seems clunky.

I'd still prefer something like; (Q = view type)

Q castAsView = this as Q;
if (castAsView == null)
throw new PagesMustImplementViewTypeException(String.Format("{0} does not implement {1}", pageName, Q.ToString());
else
this._presenter.View = castAsView;
Jan 9, 2007 at 11:15 AM
Your solution in the your other post works like a charm. I prefer it, i was aiming for this in my first approach, but lacked the skills and control do get it right.
Developer
Jan 10, 2007 at 1:24 PM
Personally, I write public members only if I need to expose things to other objects. Since the presenter will only be used by the view, why to expose it? To me, the public setter seems to be enough (for the dependency injection).

If you want to encapsulate the access to the presenter within your view, you could have a private getter:

CreateNew
public ConfirmTransfersViewPresenter Presenter
{
private get { return _presenter; }
set
{
_presenter = value;
_presenter.View = this;
}
}

You can add this to the Guidance Package by changing the template file WebClientFactory\WebClientFactoryPackage\Templates\T4\View\View.aspx.cs.

Cheers
Mariano Szklanny
http://staff.southworks.net/mariano
Jan 10, 2007 at 2:28 PM
If we are going for a basepage for our solution, the best solution is to flag the getter protected.

CreateNew
public ConfirmTransfersViewPresenter Presenter
{
protected get { return _presenter; }
set
{
_presenter = value;
_presenter.View = this;
}
}

Before ObjectBuilder and injection i prefered to have a getter accessor for all objects in the class, so i could do some checking to ensure the object was created before i accessed it.
Jan 10, 2007 at 9:23 PM
I agree that generally you should only ever expose items that need to be used externally - hence the "public" definition on a getter seems dodgy...

However, a few thoughts led me to this;

a) I don't believe property sets & gets can have different visibility modifiers
b) ObjectBuilder requires a public setter
c) I was mainly angling at the base page theory - hence the item would no longer be a private member
d) I'm concerned this is an area likely to change, so I feel needs defining as a strongly typed interface, if you like - i.e. the access to the Presenter from within the code-behind.

I do take your points though!