drizzie drizzie - 3 months ago 23
ASP.NET (C#) Question

Where to put View logic in MVP?

So I am implementing MVP in ASP.NET webforms.

I need to be able to change the color of a label based on the status of some data.

My first attempt:

class Presenter
{
...
_view.IsStatusTrue = true;
}

class View
{
bool IsStatusTrue
{
set
{
if(value)
{
lbl.Text = "Status is true :)";
lbl.CssClass = "trueClass";
}
}
}
}


My question: is this logic supposed to be in the Presenter?

class Presenter
{
...
if(status == true)
{
_view.LblCssClass = "trueClass";
_view.StatusText = "Status is true :)";
}
}

Answer

Your post title is self-answering indeed, and it's the view responsibility. I develop a home pet MVP framework project in Java, and the very core of the framework is platform-independent as well as my apps using the framework are. This lets me have many implementations for the target platform/apps views: Swing (something similar to WinForms from the .NET world), GWT (Java to JavaScript infrastructure), JSF (~ASP.NET MVC), Android, JavaFX (~WPF), Lanterna (text-mode user interface) and pure CLI (command-line interface). Think of your presenters as if they all are completely platform-independent. From this point of view, your first example is better than the second one. What it gives:

  • This means that the view does not reveal how it would report the status. This lets the presenter know as less as possible about the view. A simple boolean IsSuccessful{ set; } is really enough to report the status. If you reveal its components, then you violate encapsulation really much.
  • If your presenters are platform-independent, you can unit-test them easily at your platform not starting the target runtime and even not referencing the target runtime libraries, so they are pure. In this case you'd just need to mock your view.
  • You might want to port some your base code to another runtime, not necessarily ASP.NET. Let's say, WinForms. Having your second example introduced it wouldn't work (e.g. trueClass cannot be applied to WinForms, right?). Just consider the following code:
public sealed class CliView
        : AbstractCliView, // just an example, it might containt CLI-related stuff
          IStatusView {

    public boolean IsSuccessful {
        set {
            Console.ForegroundColor = value ? ConsoleColor.Green : ConsoleColor.Red;
            Console.WriteLine(value ? "success" : "FAILURE");
            Console.ResetColor();
        }
    }

}

This is possible just because in the first case you encapsulate how a view is implemented and not reveal the implementation details. What if you would like to support an audio interface someday? :)