Extending common interfaces for view/presenter

Topics: Prism v2 - Silverlight 2
Apr 17, 2009 at 9:39 PM
I seem to have gotten myself into a bit of a bind and was looking for some direction on the approach to take.

Basically I have a master view /w several content regions each represented by a view/presenter.  I have a single controller for the masterView that I use to manage everything.

Anyhow I have created a standard interface for a view / presenter.  In my view I have some standard events that I need/want.  My interface for the view is passed to the constructor of my presenter and I can subscribe to the events I want.  I have a set of standard events that I need to manage for all the different views in a single master view /w a controller.

Everything works great and I can delegate the events as needed up the chain.

My problem is that a couple of my views need some additional events and properties.  So I created another layer of view/presenter.

so I had IView1 & IPresenter1

IPresenter1 has a property
IView1 View {get;set}

and then I do
public presenter(IView1 view)
{
    View = view;
    View.Event1 += ...
    View.Event2 += ...
}

Now I have a more complicated view that I need an additional event so I created another set

IView2 : IView1
    event EvemttHandler <...> Event3

I also created a new presenter IPresenter2 : IPresenter1

I started to put in
new IView2 View {get;set}

so as to 'hide' the prior implemenation ... that didn't work.  When I actually create my real view from IView2 I have to implement both View Properties which I can't do.

I then decided that in my Presenter2 I would just cast my IView to an IView2 and subscribe to the events.  This seems to work and seems okay in my mind but is it asking for trouble down the road?  Sort of seems a bit like I almost tried to merge inheritence /w two interfaces.

public Presenter2(IView2 view)
{
    View = view;

    View.Event1 += ...
    View.Event2 += ...
    (View as IView2).Event3 += ...
}

This particular view happens to have a list on it so I need to handle the change in list items where the other views don't have that.

 

Really my question boils down to the best way to 'extend' an interface that is used in more than one place.  The other option would be to add a generic 'listItemChanged' event to my IView1 interface and not use it anywhere else.  That seemed a little annoying since I had to implement it in each object but I'm not that opposed to it.

 


Thanks

jack

Apr 17, 2009 at 11:19 PM

Hi Jack,

 

The way you are hiding a member inherited from a base class is correct and there should not be a problem since the member from IView2 is the one that will be called by Visual Studio. Plus, adding the generic 'listItemChanged' in IView1 is not such a good approach, because as you say, some Views will unnecessarily implement a member.

 

If I understand correctly in IPresenter1 and Presenter1 you have something like:

interface IPresenter1

{

IView1 View { get; set; }

//More code here

}

-----------------------------------------------

public Presenter1(IView1 view)

{

View = view;

//More code here       

}

 

And in IPresenter2:

    interface IPresenter2 : IPresenter1

    {

            new IView2 View { get; set; }

    }

    public Presenter1(IView2 view)

    {

        View = view;

//More code here       

    }

 

The approach I would take would be creating another interface, let’s say IPresenterBase. This interface would take all members from  IPresenter1,  except for the IView1 View. IPresenter2 should implement IBasePresenter, and add its own members like the 'listItemChanged' and IView2 View. Doing this avoids having to hide the View member.

 

The current approach you are taking is also viable. Having a method in your presenters in charge of getting IView1 casted to IView2 if you wanted to remain with it  could be another approach.

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman
Apr 18, 2009 at 12:01 AM

Damian,

Thank you for your reply - You were very close to what I was doing.

My IPresenter1 and IView1 are equivalent to the IPresenterBase (almost same name) / IViewBase.

I am unable to compile Presenter2 : IPresenter2 when I have new IView2 View in IPresenter2

interface IPresenter1

{

IView1 View { get; set; }

//More code here

}

interface IPresenter2 : IPresenter1

{

new IView2 View { get; set; }

//More code here

}

object Presenter2 : IPresenter2

                {

public IView2 View { get; set; }

...

}

The Presenter2 won't compile as it says I haven't implements IPresenter1.

'Presenter2' does not implement interface member 'IPresenter1.View'. 'Presenter2.View' cannot implement 'IPresenter.View' because it does not have the matching return type of 'IView1'.            

That threw me before I posted.  However I think that I might have put IView1 View into my base interface too early.  Each child view of my master view will have its own IViewXXX so I don't gain anything.  I can still make each IViewXXX implement IViewBase, I just don't need to implement it in the base presenter.  I think I was looking for a 'placeholder' to ensure I always implemented a View property in each Presenter.

Thanks

jack

From: dschenkelman [mailto:notifications@codeplex.com]
Sent: April-17-09 4:20 PM
To: jaddington@alexandergracie.com
Subject: Re: Extending common interfaces for view/presenter [CompositeWPF:53676]

From: dschenkelman

Hi Jack,

The way you are hiding a member inherited from a base class is correct and there should not be a problem since the member from IView2 is the one that will be called by Visual Studio. Plus, adding the generic 'listItemChanged' in IView1 is not such a good approach, because as you say, some Views will unnecessarily implement a member.

If I understand correctly in IPresenter1 and Presenter1 you have something like:

interface IPresenter1

{

IView1 View { get; set; }

//More code here

}

-----------------------------------------------

public Presenter1(IView1 view)

{

View = view;

//More code here

}

And in IPresenter2:

interface IPresenter2 : IPresenter1 {

new IView2 View { get; set; }

}

public Presenter1(IView2 view)

{

View = view;

//More code here

}

The approach I would take would be creating another interface, let’s say IPresenterBase. This interface would take all members from IPresenter1, except for the IView1 View. IPresenter2 should implement IBasePresenter, and add its own members like the 'listItemChanged' and IView2 View. Doing this avoids having to hide the View member.

The current approach you are taking is also viable. Having a method in your presenters in charge of getting IView1 casted to IView2 if you wanted to remain with it could be another approach.

Please let me know if this helps.

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Read the full discussion online.

To add a post to this discussion, reply to this email (CompositeWPF@discussions.codeplex.com)

To start a new discussion for this project, email CompositeWPF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Apr 18, 2009 at 12:14 AM

Actually that didn't work - I need the View in the IPresenterBase Interface because in my Controller for the whole set of Views I'm using it to generically process all my Presenters as I enable them and get the data, etc.

From: jaddington [mailto:notifications@codeplex.com]
Sent: April-17-09 5:01 PM
To: jaddington@alexandergracie.com
Subject: Re: Extending common interfaces for view/presenter [CompositeWPF:53676]

From: jaddington

Damian,

Thank you for your reply - You were very close to what I was doing.

My IPresenter1 and IView1 are equivalent to the IPresenterBase (almost same name) / IViewBase.

I am unable to compile Presenter2 : IPresenter2 when I have new IView2 View in IPresenter2

interface IPresenter1

{

IView1 View { get; set; }

//More code here

}

interface IPresenter2 : IPresenter1

{

new IView2 View { get; set; }

//More code here

}

object Presenter2 : IPresenter2

{

public IView2 View { get; set; }

...

}

The Presenter2 won't compile as it says I haven't implements IPresenter1.

'Presenter2' does not implement interface member 'IPresenter1.View'. 'Presenter2.View' cannot implement 'IPresenter.View' because it does not have the matching return type of 'IView1'.

That threw me before I posted. However I think that I might have put IView1 View into my base interface too early. Each child view of my master view will have its own IViewXXX so I don't gain anything. I can still make each IViewXXX implement IViewBase, I just don't need to implement it in the base presenter. I think I was looking for a 'placeholder' to ensure I always implemented a View property in each Presenter.

Thanks

jack

From: dschenkelman [mailto:notifications@codeplex.com]
Sent: April-17-09 4:20 PM
To: jaddington@alexandergracie.com
Subject: Re: Extending common interfaces for view/presenter [CompositeWPF:53676]

From: dschenkelman

Hi Jack,

The way you are hiding a member inherited from a base class is correct and there should not be a problem since the member from IView2 is the one that will be called by Visual Studio. Plus, adding the generic 'listItemChanged' in IView1 is not such a good approach, because as you say, some Views will unnecessarily implement a member.

If I understand correctly in IPresenter1 and Presenter1 you have something like:

interface IPresenter1

{

IView1 View { get; set; }

//More code here

}

-----------------------------------------------

public Presenter1(IView1 view)

{

View = view;

//More code here

}

And in IPresenter2:

interface IPresenter2 : IPresenter1 {

new IView2 View { get; set; }

}

public Presenter1(IView2 view)

{

View = view;

//More code here

}

The approach I would take would be creating another interface, let’s say IPresenterBase. This interface would take all members from IPresenter1, except for the IView1 View. IPresenter2 should implement IBasePresenter, and add its own members like the 'listItemChanged' and IView2 View. Doing this avoids having to hide the View member.

The current approach you are taking is also viable. Having a method in your presenters in charge of getting IView1 casted to IView2 if you wanted to remain with it could be another approach.

Please let me know if this helps.

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Read the full discussion online.

To add a post to this discussion, reply to this email (CompositeWPF@discussions.codeplex.com)

To start a new discussion for this project, email CompositeWPF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Read the full discussion online.

To add a post to this discussion, reply to this email (CompositeWPF@discussions.codeplex.com)

To start a new discussion for this project, email CompositeWPF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com