views:

606

answers:

4

Although my question might seem abstract I hope it's not. Suppose I develop an application, an ASP.NET MVC site and later I am tasked to build an Winforms client for this application how much and how can I reuse from the existing application?

I defined the models, I defined controllers and views. They all work well.

Now the boss comes asking for a Winforms client and I am hoping I can reuse the models and the controllers (provided I put them in different assemblies) and not reuse just the views (ASPX views).

Can this be done? How?

A: 

You can check the User Interface Process Application Block for .NET. I don't think it will work with ASP.NET MVC though.

zvikara
It won't even work with ASP.NET 2.0. It is very old.
RichardOD
+9  A: 

I have done this previously, not with asp.net MVC but with pure asp.net web forms. I used a home-grown MVP (Model-View-Presenter) pattern, and the absolute most important thing to allow the Presenter (== Controller in your case) to be used in a WinForms app was to not reference anything to do with system.web

So the first thing you need to do is introduce interface(s) to wrap any request, response, web etc stuff, and have every Presenter accept these interfaces via Dependency Injection (or make them available to the Presenters by some other technique), then if the Presenter uses those rather than the actual system.web stuff.

Example:

Imagine you want to transfer control from Page A to Page B (which in your winforms app you might want to close form A then open form B).

Interface:

public interface IRuntimeContext
{
  void TransferTo(string destination);
}

web implementation:

public class AspNetRuntimeContext
{
  public void TransferTo(string destination)
  {
    Response.Redirect(destination);
  }
}

winforms implementation:

public class WinformsRuntimeContext
{
  public void TransferTo(string destination)
  {
    var r = GetFormByName(destination);
    r.Show();
  }
}

Now the Presenter (Controller in your case):

public class SomePresenter
{
  private readonly runtimeContext;
  public SomePresenter(IRuntimeContext runtimeContext)
  {
    this.runtimeContext = runtimeContext;
  }

  public void SomeAction()
  {
    // do some work

    // then transfer control to another page/form
    runtimeContext.TransferTo("somewhereElse");
  }
}

I haven't looked at the asp.net MVC implementation in detail but I hope this gives you some indication that it will probably be a lot of work to enable the scenario you are after.

You may instead want to consider accepting that you will have to re-code the View and Controller for the different platforms, and instead concentrate on keeping your controllers extremely thin and putting the bulk of your code in a service layer that can be shared.

Good Luck!

zadam
I wish I could vote you up twice, this is a great answer!
unforgiven3
+1  A: 

Write your code as abstract as possible. @zadam says very well : abstract redirection so you can reimplement it in another solutions.

+2  A: 

Have a look at the Northwind starter kit (don't be put off by the Northwind bit)- that has various GUIs attached to a layered architecture including both MVC and Winforms.

It does exactly what you want to achieve.

RichardOD