I have experienced similar issues when using the model-view-presenter pattern and in my opinion option 2 is the simplest method.
You can do this without the view 'knowing' about the concrete presenter by having all your views implement the following basic interface:
public interface IView
{
object Presenter { set; }
}
Seeing as you are using WinForms you can have a base class that implements the IView
interface and stores the presenter object in the Tag
property.
public abstract class ViewBase : UserControl, IView
{
public object Presenter
{
set { this.Tag = value; }
}
}
Your presenter base class can then be updated to set the IView.Presenter
property and pass itself to the view to ensure the reference is kept alive e.g.
public class Presenter
{
public Presenter(View view)
{
view.Presenter = this;
}
}
Alternatively, your view class could just directly hold a reference to the presenter object like this:
public abstract class ViewBase : UserControl, IView
{
private object _presenter;
public object Presenter
{
set { this._presenter = value; }
}
}
Although your view classes now have a reference to a presenter, they do not know the actual concrete type of the presenter and as long as the field is private, subclasses cannot actually retrieve and use the presenter in any way so this merely becomes an implementation detail of your framework that is used to tie the lifetime of the presenter to the lifetime of it's associated view.