{ explore .net }

To content | To menu | To search

Wednesday 4 November 2009

WCSF and VS2010

Guidance Automation isn't supported yet in Visual Studio 2010 beta 2 and this sucks (my apologies for using this word).

In a project we're currently working on we're using Entity Framework and the Web Client Software Factory and I would really like to use the new EF features in VS2010 beta 2 (it does have a go-live license) but also keep using WCSF and without GAX/GAT support this aint gonna happen.

But as always in IT there might be a workaround, I'll be extracting the project templates of WCSF (have a look in the install directory to find them) and adding them to the project templates of Visual Studio.

I'll keep you informed of my success or failure.

Tuesday 4 August 2009

Web Client Software Factory (WCSF) - reusing views PART 2

Here is my solution for the problem explained in the previous post.

So the problem was, how can you reuse views (aspx pages) in different controllers (processes, pageflows, ... whatever you want to call them)?

I'm still using the standard Model-View-Presenter-Controller pattern used by WCSF but I'm abstracting the controller part from the presenter and I'll be passing the view (through it's interface) to the controller.

ICanHandleView<TView>
For every view the controller can handle the controller will implement an interface ICanHandleView<TView>. This generic interface has two methods, HandleView(TView view) and FillView(TView view). FillView will be mostly called when the page is loaded to fill the view with state information and HandleView will be called when an action occurred (e.g. a button click). In the implementation of HandleView you take the data from the view, store it in the controller and then decide to which page you will redirect the user. So basically the Presenter is just there to translate actions of the UI into calls to the controller.

BasePresenter
When you add a page with WCSF it will also generate a presenter that inherits from Presenter<T> where T is the interface of your view. I've created a class BasePresenter that inherits from Presenter<T>. BasePresenter has a property Controller that returns a ICanHandle(TView), behind the scenes this property uses a static class ControllerFactory that creates a new controller or correlates the current request to an existing controller. So, when WCSF created your presenter you just change the Presenter<T> it inherits from with BasePresenter<T>.

ControllerFactory
This little workhorse is responsible to do the correlation between a request and a new or existing controller. Actually ControllerFactory is just a static class that will instantiate the real factory, in my case WebControllerFactory. This was done to abstract the asp.net infrastructure from the rest of the system as the WebControllerFactory will use the HttpContext to do the correlation.

I hope I can make this all a bit clearer with the following class diagram:

(click to enlarge)

Correlation
The correlation strategy of my WebControllerFactory is the following:

(click to enlarge)

red dots: flow when the first page of the process is first requested
green dots: flow when the first page of the process is postbacked
blue dots: flow of all the following pages in the process

The reason I use the hidden field is to avoid that on a postback, of the first page of the process, a new controller would be created.

Some technical details:
When a controller is redirecting to the next page it should add the "flowid" parameter to the url. To get to the page object of a request, to add or read the hidden field value, I use HttpContext.Current.CurrentHandler, this is a IHttpHandler that can be cassed to a System.Web.UI.Page. To instantiate the correct controller factory and controllers I used Unity, the details of this I leave as an exercise to you the reader.

All of this might seem a bit complicated but once this is implemented it's really easy to use:
- generate your pages and presenters with WCSF
- write the code of your controller, unfortunately you still have to do this yourself
- configure unity
- change the base class of the presenter to BasePresenter<...>
and it's ready!

If something is not clear or if you would have a better way to do this please let me know.

Monday 27 July 2009

Web Client Software Factory (WCSF) - reusing views

This is a compilation of my comments on the blog of Simon Ince concerning reusing views in the WCSF framwork. If there are more comments posted I will also update this article. Please feel free to share your ideas as well.

First of all, if you don't know WCSF check out the articles on Simon's blog, you can find my comments on part 2 of his series.

comment 1 (me)

First of all thanks for the great articles about WCSF!

But I do have a question:

How do you achieve reusing a view (.aspx page) in a different page flow (process)?

It seems to me that this is impossible in WCSF. The view receives the presenter from the system and the presenter receives the controller but I don't see any possibility to decide which controller to use. I have the impression everything is hooked up in the wrong order to achieve reusing a view in an other page flow. In WCSF a user browses to a page and so it's actually the view that decides which process (page flow) is started. Would the ASP.net MVC framework be better suited for this?

Steven Hillaert

comment 2 (Simon)

@ Steven,

that's a good question. I think it applies equally to the MVC framework as the WCSF - remember the Controller in MVC is not an "Application Controller". Instead the MVC is similar to MVP, so in fact the question is how do we decide which Application Controller (or any page flow implementation) to use from within the Presenter (in MVP) or Controller (in MVC)? I find it curious that not many people have discussed using an Application Controller in MVC yet.

Anyway, the issue you're referring to is that in the WCSF most people inject a controller into the presenter using a [CreateNew] attribute... but you needn't do it that way if you don't want to. You could instead inject a ControllerFactory of some form, and use that to create a Controller based on further metadata available to the Presenter (perhaps some session data, or a querystring argument). You could also use a Service Locator approach instead of injection to achieve the same thing.

The other way that view reuse can be achieved is to create a User Control with an MVP trio... although how you compose these can be a complex subject so give it a try and see if it fits your approach.

Does that help?

Make sure you check out Blaine's post & survey here and feedback if this needs further guidance;

http://blogs.msdn.com/blaine/archive/2009/07/20/patterns-and-practices-wants-you-to-take-the-web-guidance-survey.aspx

Simon

comment 3 (me)

@ Simon,

Concerning WCSF:
During the weekend I came to the same conclusions as you on how to implement this in WCSF. I think the the querystring is the most flexible and practical, the only problem I see with this is that the page could be "injected" into a different process (pageflow) quite easily, some security will be needed here. An other issue is that the controller will have to implement an interface for every step (view) of the process because the presenter might used several controllers that don't necessarily have the same interface.

Concerning MVC:
I had a quick look at it (reading) and I would think that reusing a view is a lot easier here. The controller in MVC is a front controller, the user actually "surfs" to the controller and not directly to a view. So you can make the user surf directly to a process and then the process (controller) decides which view to load.

Thanks for your help Simon, I will definitely take the survey and give feedback concerning this topic.  

Steven

UPDATE
My implementation of a possible solution.