views:

221

answers:

1

I have a page that is setup like this

public partial class _Default : ViewBasePage<EmployeePresenter, IEmployeeView>,
                                 IEmployeeView
{
...
}

Inside my base page

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

    public TPresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = GetView(); // <- Works
            //_presenter.View = (TView)this; <- Doesn't work
        }
    }

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

What I need to do is actually cast (TView)_Default, using my GetView() method does indeed end with that result. Inside the base page I can't do

_presenter.View = (TView)this;

Because this is actually ViewBasePage<TPresenter,TView> so it can't directly cast to just TView.

So my actual question is there any alternative ways to achieve my result in a way that feels less hacky, if this is the primary option is there really anything I need to be concerned about by treating my page in this manner?

Edit:

The exact part I'm trying to write away is

private static TView GetView()
{
    return (TView) HttpContext.Current.Handler;
}

as I feel like this is fairly gross hack to be able to reference back to the page in this context.

+1  A: 

I don't see how (TView)this is expected to work. this is referring to the class which happens to be a Page. You can't convert a Page to an IView.

Your current implementation doesn't look at all hacky.

Am I missing something?

EDIT: now that I understand your situation a little better; what about having ViewBasePage inherit from IView (And removing it from your _Default page)?

EDIT Furthermore, if you then want the _Default page to have to implement the functions defined in the Interface, you can have the ViewBasePage class implement the interface's functions abstractly.

public class _Default : ViewBasePage<Presenter<IView>, IView>
{
    #region Overrides of classB
    public override void test()
    {
        //perform the test steps.
    }
    #endregion
}
public abstract class ViewBasePage<TPresenter, TView> :
    Page, IView
    where TPresenter : Presenter<TView>
    where TView : IView
{
    protected TPresenter _presenter;

    public TPresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = (TView)((IView)this); //<- Now it does work
        }
    }
    #region Implementation of IView
    public abstract void test();
    #endregion
}
public interface IView
{
    void test();
}
public abstract class Presenter<TView> where TView : IView
{
    public TView View { get; set; }
    public virtual void OnViewInitialized(){}
    public virtual void OnViewLoaded(){}
}
Chris
The page implements IView so say in Page_Load{ IView view = (IView)THIS; } works fine at the page level, it's at the base page that THIS refers to the BasePage not the page where it implements IView. The hacky part is using the HttpContext
Chris Marisic
This would only be allowed to work if you could guarantee that the inheriting class also inherited IView. To gaurantee that the inheriting class does inherit IView would be to have ViewBasePage also inherit from IView.
Chris
I'm trying to write away the HttpContext call
Chris Marisic
Alright, I forgot to remove that from my example, give it a look now.
Chris
Did you try building this? That still gets a casting error. C# doesn't seem to understand that TView inside ViewBasePage is the same as TView inside Presenter<TView> even with the where constraints.
Chris Marisic
And i can't do : Page, TView since it says it wants an interface name for that
Chris Marisic
Ah, you tried the top example before I changed the TView to IView. Once you make that change it works. Yes I did compile this. I just didn't copy in the correct version.
Chris
I just copied it and pasted it into a new cs file and it's still the same result.
Chris Marisic
Oops, you're right; I forgot a step in the casting. I fixed the example with this code: _presenter.View = (TView)((IView)this);
Chris
Working now, thanks for all your effort!
Chris Marisic