|
|
Comments and Discussions
|
|
 |

|
Another topic that I haven't found discussed is passing on authentication information for use for downstream access control.
Any better options than just stuffing the authentication context into the session state?
|
|
|
|

|
I have concerns about your implementation of SessionManager. Any static members of a class will be shared by all simultaneous http requests (i.e. all users).
Since we are supplying a ISessionProvider to the presenter, do we really need the SessionManager? Why not just have it be a property of the Presenter and if it is needed by anything downstream of the Presenter then the Presenter needs to pass it along.
|
|
|
|

|
I have a question. By the way brinliant implementation of the MVP Patter over WEbForms.
My question is regarding accessing HttpContext from the UntiTest Project. One of the key points of this pattern is the testability. I am having an issue though I have built an interface called IStateManager as you have suggested here and it works fine when I am executing code from my view (Web Application), but If I attempt to mock the vew in a unit rest project I get a null refernence exception when I hit any code that is trying to use the state manager. I have tried adding a reference to System.Web to my Unit TEst project but it didn't help. I must be missing something here.
State Manager is Instantiated and used like so.
IStateManager stateManager = StateManagementProvider.GetStateManager<IStateManager>();
Like I said works fine when I run the application in a browser, but I cant write Unit test agenst it at all. Is there something I am missing here?
Thanks,
-Adam N. Thompson
|
|
|
|

|
I personally don't believe unit tests should require references to System.Web. They may sometimes, for convenience, but I don't personally like the idea. If your MVP/MVC implementation truly abstract you away from a web context, you shouldn't have to be tied to System.Web.
That said, here's what I would generally do:
- I would create a Mock version of IStateManager in your unit test using Moq, Rhino Mocks, NMock, etc...
- Allow your StateManagementProvider.GetStateManager method to use some type of IoC Container to resolve types at runtime.
- Calls to GetStateManager should then return HttpContext (or whatever HTTP-specific class you need) at runtime, and your mocked version in your tests.
Cheers
|
|
|
|

|
I figured since I am getting all my instances from a Provider by Interface that I am not tied to the web context. I actually have a config entry specifying that the implementation of state manager is in the View Layer (ASP.NET App). I suppose that the way I have implemented it I could use IoC to inject an implementision of StateManager to the interface that just uses a Dictionary when testing the presenter from the unit test project.
I am unfamilure with these (Moq, Rhino Mocks, NMock), But I think I see your point.
Thank you for your response.
-Adam N. Thompson
|
|
|
|

|
Could you let me know where to find Billys Article.
|
|
|
|

|
I downloaded the code into my c:\downloads folder and click on the solution and get nothing but errors - none of the projects will load:
First Error:
------------
The application for project 'C:\Downloads\Advanced_MVP_src\MVP Sample\mvp' is not installed.
Make sure the application for the project type () is installed.
Second Error:
-------------
The application for project 'C:\Downloads\Advanced_MVP_src\MVP Sample\Sample.Presentation\Sample.Presentation.csproj' is not installed.
Make sure the application for the project type (.csproj) is installed.
Third Error:
------------
The application for project 'C:\Downloads\Advanced_MVP_src\MVP Sample\Sample.WinFormsView\Sample.WinFormsView.csproj' is not installed.
Make sure the application for the project type (.csproj) is installed.
I try to manually add these projects but the IDE says they are already loaded when in fact they are not loaded:
Here is what the IDE looks like in the Solution Explorer:
Solution 'mvp' (0 Projects)
-C:\..\mvp\(unavailable)
-- The Project File cannot be loaded
-Sample.Presentation(unavailable)
-- the project file cannot be loaded
-Sample.WinFormsView(unavailable)
-- the project file cannot be loaded
|
|
|
|

|
I was just wondering if anyone had used this pattern (or any MVP implementation) with a .Net web service. I'm trying to figure out how the View would be implemented in a .asmx page.
Thx!
|
|
|
|

|
protected void SelfRegister(Page page)
{
if (page != null && page is IView)
{
PresenterTypeAttribute attr = Attribute.GetCustomAttribute(page.GetType(), typeof(PresenterTypeAttribute)) as PresenterTypeAttribute;
if (attr != null )
{
PresentationManager.RegisterView(attr.PresenterType, page as IView, _state);
}
}
}
|
|
|
|

|
Very hard to ready article because the horizontal scrollbar is enabled due to the formatting. Please fix overflow.
|
|
|
|

|
Loved the article and modified my existing MVP code using your ideas as I was also frustrated with some of those common problems. One issue that keeps coming up for me is that the view has to pass the Data Service object to the presenter. Is your solution to simply add a Service object to the presenter as a property? Why does the pattern want the Service passed from the view anyway? I'd LOVE to see your sample code have a Data Service project included. Thanks again for the great post.
b u n g a l a y
|
|
|
|

|
Followup: I realize that the presenter needs to be independent from the service and that's why a IDAOService interface implementation is passed from the view. I just would like to know where you pass this DAO still keeping it independent. THANKS! -Chad
b u n g a l a y
|
|
|
|

|
I'm a little confused about what you're asking. My project doesn't have an IDAOService interface. If it did, I wouldn't be passing it from the view. The view shouldn't even know about a service layer. Were you looking at some other code?
|
|
|
|

|
Sorry for the confusion. I was referring to that part in your article:
"One area I may disagree with Bill is that views should also not know what data layer type (or DAO interface type) to pass to a presenter. I'm of the opinion that the view's shouldn't have a reference to any data layer (i.e. anything upstream of the presenters)."
Bill uses the typical pattern where you pass the DAO Interface type from the view to presenter in the constructor. I just wanted to know what your ideas were on how the presentation gets, and uses the DAO service. I agree that the view shouldn't reference the data layer, but I want the presenter to only know the DAO Interface type, and not have to reference my implementation.
Hope that made a little more sense.
Chad
b u n g a l a y
|
|
|
|

|
Don't believe that it's the view that's passing the DAO, but the overall controller, i.e. the page. A fragment of code from one of my current projects...
protected override void InitializePresenters()
{
IContactDao dao = DaoFactory.ContactDao();
ContactEditPresenter presenter = new ContactEditPresenter(ContactEditView, dao);
ContactEditView.AttachPresenter(presenter);
Presenter = presenter;
}
Don't see an easy way around at least one part of the project knowing how to construct the presenter. The only other approach is some form of IoC container like Winsor etc, and I generally prefer to have code as code not XML unless there's a good reason why.
Paul
|
|
|
|

|
Interesting solution for this problem that was bothering me for a while.
I like the clean separation between the layers, however, I'd like to see this in action in a difficult context, where the presenter would have a more complex interaction with the view.
Good article, thank you for sharing it.
|
|
|
|

|
Thanks! I've been using this patter with a current client by request. As it turns out, their business logic can be rather difficult, especially when deciding which logic goes on the server (a WCF solution), and which logic stays on the client (the presenters). Thus far the architecture has worked extremely well. I'd post some complex code samples if it wouldn't violate the contract.
I can't ask you to take my word for it, but I've found the pattern works well, even for difficult scenarios.
|
|
|
|

|
Hello,
You may take a look at http://www.codeproject.com/cs/design/WebFormsASPdotNET.asp
article which presents the alternative to MVC/MVP approach and also addresses your
concerns about MVP. Any comments will be appreciated.
|
|
|
|

|
Thanks for pointing me to this article. The author has taken a very "Ruby-esque" approach to his page life cycle. If you're not already familiar with how Ruby on Rails works, I'd recommend you check out http://rubyonrails.org/[^]. In short, Rails takes a "convention over configuration" approach. Specifically, Rails use a true MVC pattern that's driven by the request path and query string. In Rails, all incoming requests are handled by a controller. That is to say, the controller is the point of entry for any given request. The view, in this case, is used purely for display.
The question is how does this compare to ASP.NET. By default (that is, without writing HTTP handlers or modules), the code behind an ASP.NET file is the entry point for incoming requests. This convention makes it difficult to implement a true MVC pattern since the view is taking requests, not the controller.
The article you referenced attempts to put the controller at the forefront of the request cycle. It's an interesting approach, but I'm not sure that it provides a tangible advantage to the standard .NET page request life cycle. The MVP pattern really provides a layer of abstraction from the UI that's highly testable.
The main difference here is that the code used in the MVP layer can be easily reused in an WinForms project, Console app, Windows Service, or any other type of "view" you can think of, thanks to the use of simple interfaces. The article you referenced is heavily coupled to the ASP.NET pipeline, and wouldn't work at all outside that context. In other words, MVP strives for reuse while the other article strives to mimic a Rails convention.
Interesting read, though. Thanks!
|
|
|
|

|
Hello,
Im really sorry that you read only the first few lines. I pointed you to my own article. My article was inspired by Ruby on Rails framework only in the sense
that multi-tier architecture is posssible. Anything else is my own ideas without
copying or mimicing Rails. I decoupled three tiers
by using interfaces. Please read more than only few lines
before you write such a judgement.
Firstly, If you read more you have noticed that there is a http handler used which
takes care of url rewriting, creating and calling controller/presenter methods.
Secondly, everything that you wrote about my article is flat wrong because you people
want to read only headline and pass a judgement. Effort first then judgment.
Thirdly, http module is an entry point not controller/presenter
Fourthly,the whole appoach is an interface based.
PLEASE PLEASE read, make an effort
arturbl
|
|
|
|

|
I read you're whole article, top to bottom. My points still stand, and, for the record, were not critical at all. There are no judgements, just simple observations. My point is that you use a controller-first architecture like Rails.
Frankly, you need to calm down a bit - you asked me to read the article and give observations. I did, and I stand by based on the current content of the article. Further, my points on how your architecture isn't portable to a non-asp platform still stands in terms of a HTTP handler being the controller broker. It's not being critical, it's just a fact.
Seriously, don't ask for opinions if you don't want to take them.
|
|
|
|

|
Thank you for reading the whole article and your remarks. I must say that you are very quick.
If you incorporate url mapping/rewriting in your http module then at some point you need to call some methods. In my case methods of the controller/presenter are called
on run-time based on a given url content. I do not know how you would have url mapping without calling controller/presenter methods. Clearly you need something between http module and aspx page.
The whole idea of using interfaces where controller talks to model, view and controller talk to each other is because of portability.
Take out http module out and try to write win forms app and you will see that my approach is fully portable. Controller knows almost nothing about view and talks to model through interface methods. None of the three tiers has any knowledge about http module. Controller is not as powerful as in Rails. Its methods are called by view through interface methods. If you write console or win forms app you should not modify the structure of model or controller. Just get rid of http module and aspx page. I hope that clarifies things.
Yes, in case of win forms app or console one you need controller-breaker. You simply
intstantiate controllers class somewhere in a code. But by no means you change model or controller structure. When you switch between web/win forms/console apps you may add or remove some code but never in controller or model (you remove controllers properties in case of none-asp app,but you never change constrolers structure). This is what I mean by portability
I stand by the fact that my approach is as portable to non-asp environment as interface based approach is.
-- modified at 16:01 Wednesday 5th September, 2007
|
|
|
|

|
I'm still not clear... your controllers are loaded by the HTTP module. If you take out the module and move to a WinForms or Console app, what's going to load the controller? My point is that you have a convention, the module, to do that work. That module depends fully on ASP.NET. Obviously, you're not going to have an HTTP module in a WinForms app. To that end, there is still a dependency, despite the abstraction further down the pipeline.
You stated, "Yes, in case of win forms app or console one you need controller-breaker. You simply intstantiate controllers class somewhere in a code.But by no means you change model or controller structure."
What you're saying is that you have to write new code to do what your HTTP module does if you change UI paradigms. The MVP pattern in Bill's and my articles don't require that infrastructure. They're 100% technology agnostic, and, short of creating new views (wich all of our projects would require), there's no changes necessary, and no additional code.
My point is that you have a really cool concept, but it's simply not comparing apples to apples when you compare your idea or Rails to this type of MVP implementation.
Great ideas, though. I still enjoyed your article.
|
|
|
|

|
Doesn't mapping views to presenters lose type savety?
I like the idea of having less code,
but I rather have my code checked compile time then run-time.
In your example it's possible to map any presenter to any other view
and only find out at run-time that the mapping is wrong.
Any ideas on making it type save?
|
|
|
|

|
Check out the latest source code. I've updated it to get rid of the type mapper all together (though I just noticed the article's text is still out of date.
Right now the mapping is attribute-based, which helps provide some abstraction, but no real type safety. I does, however, guarantee the type of presenter that will act on the view. I'm in the process of constructing a more elegant solution using generics so the types can be checked at compile time.
|
|
|
|

|
If it can be done, generics seems like the way to go.
But it just feels like a fundamental problem.
|
|
|
|

|
I agree. I haven't found a good solution yet other than the attributes on the views (see the latest source code).
|
|
|
|

|
Part of my master thesis is about MVP, I came across Your article and I have to say that it will helps me a lot and also that If you figure it out yourself, You are genius,
thank You very much again
regards
Krzysztof Szepietowski
|
|
|
|

|
I'm flattered that my article will help with your thesis. In case you're interested, I've refactored the project a bit to further decouple the views in favor of using events. I'll post the updated code and this thread when I get the source updatd. Hope it helps!
|
|
|
|

|
I know we can do the same thing with System.Web.Caching.Cache but is there a better way to do it with Cache so this wouldn't be necessary? Or would this be the best type of approach for Cache as well?
Thanks!
JMW
|
|
|
|

|
You can do it however you need, using an approach like the session state in the demo gives you freedom for multiple types UI platforms. You wouldn't want to use ASP.NET's session state for a WinForms app. You also wouldn't want to use ASP's caching in a WinForms context. I'd stick with some type of provider model or interface so the underlying implementation can be abstracted.
|
|
|
|

|
Looking at your example I found the SessionManager...
But still don't understand why the SessionManager is neccessary. With ISessionProvider alone you would not need to reference System.Web in the presentation project, would you?
|
|
|
|

|
The original idea for the SessionManager was to help with making multiple calls to more than one presenter at the same time. I had originally started with a Singleton pattern so all instances of presenter implementations could share the same session object. The sample code hasn't built that idea out as much as it has put a good place holder for the sake of ease.
|
|
|
|

|
Since the original posting of this article I've stopped using the "Execute" paradigm all together. Every last line of code related to it was deleted from my own personal project, so for those of you who continue to have great suggestions, no need to dwell on the old stuff.
What new ideas does everyone have?
|
|
|
|

|
Maybe you could edit the article itself by replacing the Execute parts with what you use right now!
And of course a thanks for your contribution and the time to respond and change your opinion.
|
|
|
|

|
I absolutely will update the article when I have the sample prject in a state that's worth re-posting. I'm also happy to take more ideas/snippets/etc... into account before I edit the article, so post away!
|
|
|
|

|
I'm rather new at .Net so I may be overlooking something obvious.
Couldn't the view interface define delegates for every one of the events it needs to respond to?
The view implementation would have calls to the delegates in the various events it needs the presenter to respond to.
When the presenter inits the view, it assigns its own member methods to the views' delegates.
When the presenter gets a call to one of the methods it assigned as delegates, it turns around and asks the view for the data it needs and does whatever processing it needs to do.
I hope I'm explaining this correctly. (And that I'm not embarassing myself too badly. )
I'd be thankful for any insight you could provide me since I'm thinking of using this for a rather large project.
Thanks.
|
|
|
|

|
Thanks for the suggestion! You're right; an event structure could easily be defined in the interfaces and used to invoke the presenters. It may simply be easier to call a method exposed by a presenter so parameter passing is easier, but what you outlined is well within the realm of possibility.
|
|
|
|

|
Thanks for the validation! It really helped improve my confidence in my current design.
Thank you for the great article (just realized I hadn't mentionned that before).
|
|
|
|

|
Using the abstract execute method seems cumbersome and unwieldy.
May I suggest the use of Events instead?
For example, you could define the Login event in your view interface.
Then, in your loginButton_Click subroutine, just raiseevent Login.
In your presenter class, use
Public Sub Login() Handles view.Login
dim userName as string = view.UserName
dim password as string = view.Password
...
end sub
|
|
|
|

|
True, you could use events to respond to the UI, but that raises a number of problems with MVP theory. First off, when the presenter responds to the UI’s events you rapidly approach an MVC pattern. Next is the issue of references. Take a datagrid’s ItemDataBound event for example. In order for the presenter to subscribe to that event, the presenter would be forced to have a reference to System.Web, something you absolutely should not do to follow the MVP pattern.
Another problem with this approach is that you’ve more tightly coupled the presenter to a particular type of view. As I’m sure you know, the delegate signatures for many controls do not mesh between ASP and WinForms (or other sources). You’d be forced to write an entire set of classes so any type of view could pass the same, consistent, expected data types to the presenter. That brings us right back to square one – the views are now engaged in non-view logic.
I totally agree about calling the Execute method; since writing this article I’ve come to dislike every aspect of that idea. A good point was made in a previous post regarding how the self-documenting nature of the presentation layer is lost using a generic Execute method. I still haven’t found a good answer to the problem of coupling and abstraction between the layers. Like I said, I like the idea of events, but there are too many immediate limitations to fit that into this MVP sample. Until I find a good alternative, I’m resigned to the fact that the true advantage of MVP is that it’s like partial classes across assemblies to aide in testability.
|
|
|
|

|
I may not have been clear in presenting my ideas.
To subscribe to an ItemDataBound, don't let the presenter subscribe to it directly.
Let the View subscribe to it, then let the View expose a different event.
For example,
In the usercontrol code-behind,
Public Event ItemSelected(ByVal PositionLabelIndex As Integer) '==> expose this event to the presenter
Private Sub gvBomNarrations_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles gvBomNarrations.SelectedIndexChanged
RaiseEvent ItemSelected(CInt(gvBomNarrations.SelectedValue))
End Sub
In the View,
Public Interface IViewBomNarrations
Event ItemSelected(byval value as integer)
End Interface
In the presenter,
Public Class BomNarrationsPresenter
Private WithEvents _view As IViewBomNarrations
Private Sub _view_ItemSelected(byval value as integer) Handles _view.ItemSelected
...
End Sub
ENd Class
|
|
|
|

|
I understand your point, but what I'm saying is that your example describes how MVC (Model-View-Controller) works. All you've done is take the ASP.NET event structure and have the view dumb it down for the presenter's sake. Now your view has to be smart enough to know how to translate UI data types into .NET primitives, and potentially even business objects, expected by the presenters. Further, your example forces the view to know the correct order in which events should be fired (remember, views are not always ASP.NET pages) to keep the presenter's workflow correct. One of the major ideas for MVP is for the view to be as simple as possible. The presenter should simply use properties and methods to retrieve the data it needs rather than trying to respond to events that will likely be inconsistent between various views. Events can be used, where appropriate, but not by adding complexity to the views.
Good ideas, though. Thanks!
|
|
|
|
|

|
I just happened to read thru the whole MVP discussion chain, though a lot late, I thought I would share my view as well. Having events as a way of communicaton between the view and the presenter, does give us the flexibility of making the View totally unaware of the Presenter. My question is why should the View know about the Presenter? The following code would allow us to test the code easily with any ILoginView implementation.
public LoginPresenter(IView view,Model model)
{
((ILoginView)view).OnValidateUser += this.ValidateUser;
}
|
|
|
|

|
How about using "convention" to match the CommandName of an event, e.g. button click, to the action taht you want to call on the present. That way you can use reflection to call the action without having to have a generic execute method, e.g.
protected void loginButton_Click( object sender, EventArgs e )
{
Type presenterType = base._presenter.GetType();
BindingFlags flags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance;
MethodInfo action = presenterType.GetMethod(((Button)sender).CommandName, flags);
action.Invoke(target,null);
}
Obviously you can refactor the reflection code out into a helper, it is just here for illustration.
Therefore you can have a CommandName = "Login" on the submit button and a public void Login() on the presenter.
Great article by the way
|
|
|
|

|
What is the use of methods add,contains and clear in websession provider? how can I access them,since presenter is only using ISessionProvider to put session values..
thks
|
|
|
|

|
I don't understand your question. Can you be more clear?
Notion ONE - Excellence through Service.
|
|
|
|

|
I re-read your post, and I think I understand your question. The point is that I intended to implement the interface to support those methods, and left it as generic as possible for this article. I started by creating a functional wrapper for ASP's session object, and didn't implement the interface until later. I wouldn't do that for a real application, but in the case of this sample I took a backwards approach. You're right, the presenters can't take advantage of methods not exposed by the interface, and as such they're not useful outside of ASP.NET.
Notion ONE - Excellence through Service.
|
|
|
|

|
i am doing a real project..and have used your idea of session management..thks..brilliant idea..
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Addressing the common issues related to the MVP pattern using ASP.NET and WinForms clients.
| Type | Article |
| Licence | CPOL |
| First Posted | 14 Jul 2006 |
| Views | 121,863 |
| Downloads | 338 |
| Bookmarked | 100 times |
|
|