We are working on a big piece of WinForms legacy code and are in the slow process of refactoring, breaking dependencies down, implementing the MVP pattern and moving logic out of Forms and User Controls into presenters.
We have already added Castle Windsor which creates a ViewFactory that returns a Form/User Control with a Presenter and all of its dependencies attached to it.
One user control is used in pretty much every single screen and we are already refactoring it but have not completed refactoring all the screens that use it, so some of them are using the ViewFactory and some are still calling the control's constructor which of course does not create a presenter.
The way I though we could work around that was to check if the events the control now has are null, if they are it means there is no presenter that has subscribed to them so I create it manually. This works but since there are a few events that can be fired at different times it means that I had to do the following:
private void RaiseEventForPresenter(ref EventHandler action, EventArgs e)
{
if(action == null) CreatePresenter();
action.Invoke(this, e);
}
private void RaiseEventForPresenter(ref CustomDelegate1 action, CustomDelegate1EventArgs e)
{
if(action == null) CreatePresenter();
action.Invoke(this, e);
}
private void RaiseEventForPresenter(ref CustomDelegate2 action, CustomeDelegate2EventArgs e)
{
if(action == null) CreatePresenter();
action.cInvoke(this, e);
}
private void CreatePresenter()
{
new Presenter(this, new Bl(new Dal(new ConnectionManager())));
}
Notice that the delegate needs to be passed as ref in order for it to be successfully invoked after the presenter has been created and it has subscribed to the view's events.
Instead of having a different overloaded method for each kind of event, I would like to do something like so:
private void RaiseEventForPresenter<T1, T2>(ref T1 action, T2 e)
{
if (action == null) CreatePresenter();
action.Invoke(this, e); //Does not compile
}
Of course T1 does not contain a definition for the Invoke method. So far I have tried:
Casting action to an Action:
((Action<object, T2)action).Invoke(this, e);
Redefining T1 to a Delegate:
private void RaiseEventForPresenter<T>(ref Delegate action, T e) ...
Redefining T1 to an Action:
private void RaiseEventForPresenter<T>(ref Action<object, T> action, T e) ...
All of these options give me different compilation errors so my question is, can this be accomplished at all?