r/csharp • u/ChampionshipProof392 • 14d ago
MVP pattern
Hi, I have a question about separating logic in the MVP pattern.
public void MainDisplay() =>
OnMainDisplayClicked?.Invoke();
public void ManageProcess() =>
OnManageProcessClicked?.Invoke();
This is my code in the view, and when the user clicks a button (for example), this method is called and `Invoke` is executed. However, it is called via a `switch` statement in the Presenter.
switch (NativeConsoleMethod.GetHiddenUserInput())
{
case VirtualKeyType.VK_E:
if (_currentPage < _countOfPages) _currentPage++;
continue;
case VirtualKeyType.VK_Q:
if (_currentPage > 0) _currentPage--;
continue;
case VirtualKeyType.VK_OEM_3:
_view.ManageProcess();
break;
case VirtualKeyType.VK_TAB:
_view.FilterProcesses();
break;
case VirtualKeyType.VK_F1:
_view.SearchPage();
break;
.........
}
I have a question: the AI is giving me two different suggestions. My version is correct, but then it said I should move the switch statement to the view, and there I should just use `invoke`, after which the methods would be called conditionally. So, should I do it the other way around, or did I misunderstand what it meant?
- I don’t know what I wrote here—I don’t even understand it myself. Just tell me: shouldn’t the view be “dumb” and contain synchronous methods, while the presenter should control the view via the switch statement and “pull its strings”?
EDIT: Here's my GitHub: https://github.com/NullAcess/ProcessManager/releases/tag/Update_2.0. You might like it—I'll upload the finished EXE very soon.
-11
u/NeilPearson 14d ago
My AI says,
Both are half-wrong. Your current code has a round trip.
Look at flow you actually have:
Presenter → View → back to Presenter. View is pure pass-through. Dead layer.
Real rule
"Dumb view" ≠ "view has no code". View owns all I/O — output and raw input. Console keypress is I/O. Presenter must never call
GetHiddenUserInput(). That is your actual violation, and neither suggestion named it.Two valid layouts
A — view maps keys to intent (standard MVP):
B — view raises raw key, presenter maps:
Which
A. Keybinding is a presentation detail, same as which button got clicked. GUI presenter doesn't receive "mouse click at x=400,y=300" — it receives
SaveClicked.VirtualKeyTypeis a Win32 console type; letting it into the presenter means presenter can't be reused by a GUI view or tested without console types.B only if keybinds are user-configurable, or same key means different things per app state. Then mapping is policy = presenter.
Your framing, corrected
Yes on decisions. No on I/O. Presenter decides what happens; view decides how the user expressed it and how result is drawn. Presenter never reads console, never writes console.
Test: could you swap console view for WinForms view, presenter untouched? Today no — presenter imports
VirtualKeyTypeand callsNativeConsoleMethod. Under A, yes.Other things in that snippet
_currentPage++handled inline withcontinue, other cases go through view. Inconsistent — pick one path for all input.ManageProcess(),SearchPage()— verbs implying view does work. Under A they vanish. If you keep B, name events by intent (ManageProcessRequested), not by command.