views:

225

answers:

3

I am working with MVP in ASP.NET and wanted see if there is an easier/cleaner way to do this.

I have a presenter with a view. It turns out I can reuse some of the view properties and presenter methods in other views/presenters in the same application area.

Lets say I have a Bar, which is logically a Foo. The base presenter, FooPresenter, has the common logic for Bar and its siblings. The IFoo view has common properties as well.

I want to be able to treat the view as an IFooView in the FooPresenter, and the view as an IBarView in the BarPresenter and have it be the same instance so I get all of the Foo stuff in my view implementation, the aspx page.

Here is what I have:

public interface IFooView {
    // foo stuff
}

public interface IBarView : IFooView {
    // bar stuff
}

public abstract class FooPresenter<T> where T : IFooView {
    public FooPresenter(T view) {
        this.view = view;
    }

    private IFooView view;
    public T View 
    {
        get { return (T)view; }
    }

    public void SomeCommonFooStuff() { }
}

public class BarPresenter : FooPresenter<IBarView> {
    public BarPresenter (IBarView view) 
        : base(view) {

    }

    public void LoadSomeBarStuff() {
        View.Stuff = SomeServiceCall();
    }
}

The interesting part is around accessing the view interface in the child class through the property in the base class that does the cast. Any thoughts about this, or recommendations on how I may be able to make this easier to maintain?

A: 

I've done something similar where in the BarPresenter, I'd have a public IBarView View { get { return (IBarView)this.view; } }. Then you can reference the capital View and get what you need.

Tom
I have done this in the past too, but think it may be cleaner to do the cast in the base class. I would sometimes try to use the member in the child instead of the proeprty but then realize it wasn't cast to the right type.
blu
You can't do the cast to IBarView in the base class because IFooView shouldn't know about subclasses. And if you use the base class view, instead of View (even if by mistake), that still works if you don't need to IBarView properties, but if you do, then it just won't compile.
Tom
The base class knows T which is all it needs, and the above compiles fine. But thanks for your input.
blu
+1  A: 

The only thing I can see that I would change is to remove the private field in FooPresenter and stick with just the property with a public getter and private setter.

There's no need for the private field in this case, just let the generics do the work for you.

Mark Allanson
Agreed, good catch.
blu
A: 

The private field view could just be declared of type T, that way you avoid unnecessary casts

    private T view;
Pete
Indeed, this is the only thing to fix