>where does filters come in?
The same way as I resolve Handlers, eg:
windsorContainer.ResolveAll<IRunBeforeAllHandlersFor<TWebCall>>(new { 
EngineContext = engineContext,  ControllerContext = context});
windsorContainer.ResolveAll<IRunAfterAllHandlersFor<TWebCall>>(new { 
EngineContext = engineContext,  ControllerContext = context});
We can even have validation done this way, eg:
windsorContainer.ResolveAll<IHandleValidationFor<TWebCall>>);


>how do you bind incoming parameters?
The derived classes from WebCall are populated with the incoming params.
Eg.
public class ProductViewWebCall : WebCall{
    public string ProductId { get; get; }
}
or
public class UserCreateWebCall : WebCall{
    public string Name { get; get; }
    public string Password { get; get; }
}

>how do you enforce ordering
You don't need because if you do then you are mixing "concerns"
That said, yes I do agree that sometimes you may want to run a handler first, 
specially if we have an authorisation handler.
I'm thinking about implementing the ordering the same way NServiceBus does it 
(see http://www.nservicebus.com/Documentation.aspx):
     public void SpecifyOrder(Order 
order)
     {
          order.Specify(First<H1>.Then<H2>().AndThen<H3>().AndThen<H4>() //etc);
     }


Please remember this is just a hobby at the moment and I know that there is 
still a lot to think about, also if I go down this path and get it working, I 
would create a new project and not call it MR because this is a huge change for 
Monorail users, that said this would definitely give us the edge over the 
difference between the MS implementation of MVC and our own :)


Cheers
John



________________________________
From: Ken Egozi <[email protected]>
To: [email protected]
Sent: Mon, 22 March, 2010 5:10:51 PM
Subject: Re: MonoRail roadmap/todos


the idea is cool, and I'm also facing the same composability issues
however, It does raise questions (where does filters come in? how do you bind 
incoming parameters? how do you enforce ordering (say you want part B to run 
after part A since you *know* that it uses a subset of data that Part A uses, 
and assuming a request-level-cache is in place, you'll be able to spare an 
out-of-process call that way)

I'm thinking about tackling that problem differently:
- have the request map to a controller action (using existing routing rules), 
(and of running the auth-filter pre action and the "set layout params" after 
action, etc.)
- in the controller, ask the container to resolve all handlers, and supply them 
with the current context (as IDictionaries) and ask them to run
    -  Async controllers are one more benefit I can use here by not 
re-inventing the process mechanism
- use the DictionaryAdapterFactory to access query+form parameters in the 
handlers, and to set property-bag values

that way I do not need to bend monorail into anything, and I gain a "monorail 
free" way of composing stuff, which can be useful if I expose some 
functionality through other means (WCF, direct API calls, whatever)


On Mon, Mar 22, 2010 at 7:29 AM, John Simons <[email protected]> wrote:

>Actually WebCall and Handles are interfaces, sorry for the confusion.
>>(I'm not too keen on the use of 'I' for interfaces any more, that can
>>be a different discussion)
>
>>public interface WebCall{}
>
>public interface Handles<T> where T: WebCall
>>{
>>   void Handle(T command);
>>}
>
>Cheers
>>John
>
>
>>On Mar 22, 4:13 pm, Alex Henderson <[email protected]> wrote:
>>> I'm not sure that inheritance of commands (which are bound to form
>>> parameters etc.) is a good mechanism for determining handlers for a request,
>>> this limits your ability to compose things easily (you run up against the
>>> limitations of single inheritance etc.).
>>>
>>> Also would this be the mechanism used in place of things like filters - so
>>> effectively a handler of the base command class "WebCall" would behave like
>>> a BeforeAction filter (kinda).   If so, isn't ordering of handlers then
>>> going to become an issue to implementing things like security,
>>> authentication etc. filters.
>>>
>>> Interesting discussion though.
>>>
>>> Cheers,
>>>
>>>  - Alex
>>>
>> On Mon, Mar 22, 2010 at 2:45 PM, John Simons 
>> <[email protected]>wrote:
>
>>
>>> > Sorry I did a very simplistic example.
>>> > So here is something a bit more complex, and with a few more smarts.
>>>
>>> > Lets say that as part of displaying /Products/List we also display on
>>> > the same screen a shopping cart + product specials + recommended
>>> > products, actually lets say that we do this for any url that is part
>>> > of the Products "area" (/Products/*).
>>>
>>> > The way we do this using the Controller/Action is something like this:
>>> > public void List(){
>>> >  PropertyBag["cart"] = GetCart();
>>> >  PropertyBag["recommended"] = Recommended();
>>> >  PropertyBag["specials"] = Specials();
>>> >  PropertyBag["productsList"] = GetProductsList();
>>> > }
>>>
>>> > public void Search(){
>>> >  PropertyBag["cart"] = GetCart();
>>> >  PropertyBag["recommended"] = Recommended();
>>> >  PropertyBag["specials"] = Specials();
>>> > }
>>>
>>> > public void ComingSoon(){
>>> >  PropertyBag["cart"] = GetCart();
>>> >  PropertyBag["recommended"] = Recommended();
>>> >  PropertyBag["specials"] = Specials();
>>> >  PropertyBag["comingSoon"] = ComingSoon();
>>> > }
>>>
>>> > And yes I know you can do a bit of refactoring here or use Filters,
>>> > but the point is that an action method has a lot of responsibilities
>>> > with this model.
>>> > Also, remember that your controllers tend to not just have one single
>>> > action method but many (this can make the Controllers quite large
>>> > classes!).
>>>
>>> > The way I would do this using Handles is (Note: I'm using inheritance
>>> > to work out what handles to execute):
>>>
>>> >       public class ProductsListWebCall : ProductsWebCall{
>>>
>>> >       }
>>>
>>> >       public class ProductsWebCall : WebCall {
>>>
>>> >       }
>>>
>>> >        public class ProductsListHandler :
>>> > Handles<ProductsListWebCall>
>>> >        {
>>> >                public IEngineContext EngineContext { get; set; }
>>> >                public IControllerContext ControllerContext { get;
>>> > set; }
>>>
>>> >                public void Handle(ProductsListWebCall webCall)
>>> >                {
>>> >                         ControllerContext.PropertyBag["productsList"]
>>> > = GetProductsList();
>>> >                }
>>> >        }
>>>
>>> >        public class ProductsSpecialsHandler :
>>> > Handles<ProductsWebCall>
>>> >         {
>>> >                public IEngineContext EngineContext { get; set; }
>>> >                public IControllerContext ControllerContext { get;
>>> > set; }
>>>
>>> >                 public void Handle(ProductsWebCall webCall)
>>> >                {
>>> >                        ControllerContext.PropertyBag["specials"] =
>>> > Specials();
>>> >                }
>>> >        }
>>>
>>> >        public class ProductsRecommendedHandler :
>>> > Handles<ProductsWebCall>
>>> >         {
>>> >                public IEngineContext EngineContext { get; set; }
>>> >                public IControllerContext ControllerContext { get;
>>> > set; }
>>>
>>> >                 public void Handle(ProductsWebCallwebCall)
>>> >                {
>>> >                        ControllerContext.PropertyBag["recommended"]
>>> > =Recommended();
>>> >                }
>>> >        }
>>>
>>> >        public class CartHandler : Handles<WebCall>
>>> >         {
>>> >                public IEngineContext EngineContext { get; set; }
>>> >                public IControllerContext ControllerContext { get;
>>> > set; }
>>>
>>> >                 public void Handle(WebCall webCall)
>>> >                {
>>> >                        ControllerContext.PropertyBag["cart"] =
>>> > GetCart();
>>> >                }
>>> >        }
>>>
>>> > The advantage I get from using this model is hopefully total
>>> > separation of concerns on my handlers.
>>>
>>> > I will write a post about this, with sample code that I hope will
>>> > clarify a lot of the unanswered question in this thread.
>>>
>>> > Cheers
>>> > John
>>>
>>> > On Mar 22, 12:16 pm, Henry Conceição <[email protected]>
>>> > wrote:
>>> > > For me, it appears to be just a rename. What we used to call
>>> > > controller, is now called handler.  With the downside that now I'm
>>> > > obligated to implement an extra class honoring the web call contract.
>>> > > But perhaps I didn't get the big picture...
>>>
>>> > > Cheers,
>>> > > Henry Conceição
>>>
>>> > > On Sun, Mar 21, 2010 at 9:38 PM, John Simons 
>>> > > <[email protected]>
>>> > wrote:
>>> > > > Jan,
>>> > > > My line of thought at the moment is why have a controller at all?
>>> > > > See Chad Myers post on it:
>>> > > >http://www.lostechies.com/blogs/chad_myers/archive/2009/06/18/going-c.
>>> > ..
>>>
>>> > > > I have been hacking MR to bend it the way I want, so far I'm able to
>>> > > > convert a request into a command (using convention over configuration)
>>> > > > and execute that command with a simple interface.
>>> > > > Eg.
>>> > > > Assume a request comes in for /Products/List
>>> > > > I then convert this request into ProductsListWebCall
>>> > > > And then I go to my container and do the following:
>>> > > >                        var webCallHandlers =
>>> > > > windsorContainer.ResolveAll<Handles<TWebCall>>(new { EngineContext =
>>> > > > engineContext,  ControllerContext = context});
>>> > > >                        var webCall =
>>> > Activator.CreateInstance<TWebCall>();
>>>
>>> > > >                        foreach (var handler in webCallHandlers)
>>> > > >                        {
>>> > > >                                handler.Handle(webCall);
>>> > > >                        }
>>> > > > And the Handle interface is:
>>> > > >    public interface Handles<T> where T: WebCall
>>> > > >    {
>>> > > >                void Handle(T command);
>>> > > >    }
>>>
>>> > > >        public interface WebCall
>>> > > >        {
>>> > > >        }
>>>
>>> > > > As u can see I'm also injecting the ControllerContext and
>>> > > > EngineContext so that in the Handler I can do this:
>>> > > >         public class ProductsListHandler :
>>> > > > Handles<ProductsListWebCall>
>>> > > >        {
>>> > > >                public IEngineContext EngineContext { get; set; }
>>> > > >                public IControllerContext ControllerContext { get; set;
>>> > }
>>>
>>> > > >                public void Handle(ProductsListWebCall webCall)
>>> > > >                {
>>> > > >                        ControllerContext.PropertyBag["message"] =
>>> > "Hello from handler";
>>> > > >                }
>>> > > >        }
>>>
>>> > > > Sorry about the formatting of the code, I'll try to write a blog post
>>> > > > about it soon.
>>>
>>> > > > Cheers
>>> > > > John
>>>
>>> > > > On Mar 16, 1:26 pm, Jan  Limpens <[email protected]> wrote:
>>> > > >> From my point of view, I hope nobody minds my late involvement in 
>>> > > >> this
>>> > > >> discussion, MR's future should concentrate less in features and more
>>> > > >> in architecture.
>>>
>>> > > >> After all, functionality like the one provided by
>>> > > >> SmartDispatcherController should be (and mainly is) provided as an
>>> > > >> aspect.
>>>
>>> > > >> The aforementioned functionality to render multiple controller 
>>> > > >> actions
>>> > > >> into a single view inverts the mvc paradigm and is no good idea in my
>>> > > >> point of view. The view should not be able to make such decisions,
>>> > > >> that's the controllers job.
>>> > > >> The controller how it is today is a point of very low cohesion and 
>>> > > >> one
>>> > > >> of the points that should be implemented in a very different way.
>>> > > >> Fortunately, with the availability of DynamicActions, the controller
>>> > > >> could actually become the aspect providing Action-registration node,
>>> > > >> it ought to be, imho.
>>> > > >> This would make reuse much more efficient and would allow for better
>>> > > >> composibility. Imagine, one has (fake MEF style)
>>>
>>> > > >> public class MyController {
>>>
>>> > > >>    [Import]
>>> > > >>    public void MyAction {
>>> > > >>    }
>>>
>>> > > >> }
>>>
>>> > > >> [Export("MyController.MyAction")]
>>> > > >> public class MyActionContent : DynamicAction{
>>> > > >> //impl
>>>
>>> > > >> }
>>>
>>> > > >> [Export("MyController")]
>>> > > >> public class MyActionLayout : DynamicAction{
>>> > > >> //impl
>>>
>>> > > >> }
>>>
>>> > > >> this would solve composition pretty well - on the controller side.
>>>
>>> > > >> On the view side, I completely dig OpenRasta's codec and content
>>> > > >> negotiation paradigm. It is sad, MR does not offer such a clean
>>> > > >> implementation.
>>>
>>> > > >> Composite UI is much more difficult to envision, in my eyes, because,
>>> > > >> contrary to WebForms, we do not have externally programmable views 
>>> > > >> (we
>>> > > >> can not say "Body.Insert(new Whatever())"). But from a separation of
>>> > > >> concerns point of view, this is a good thing, probably. Still all
>>> > > >> frameworks offering composite GUIs have this somewhere. The problem
>>> > > >> is, that a view in a composite world cannot know of what parts it
>>> > > >> consists, but probably the solution ought to be similar to the
>>> > > >> controller: the view as a registration point for sub views based on
>>> > > >> some conventions.
>>>
>>> > > >> <% SubViews
>>> > > >>    .For(v => v.ForNode = "contentNode")
>>> > > >>    .With(v => viewData.GetData(v))
>>> > > >>    .OrderedBy(v => layout.ApplyOrder(v)) %>
>>>
>>> > > >> Composition is a big deal (I'd love to read hammett's take on this,
>>> > > >> but both of his blogs seem abandoned...) and is something really
>>> > > >> difficult to implement currently.
>>>
>>> > > >> Probably I should have said IMHO, much more often, so please take 
>>> > > >> this
>>> > > >> as the opinion this is.
>>>
>>> > > >> --Jan
>>>
>>> > > >> On Jan 24, 8:15 pm, Mauricio Scheffer <[email protected]>
>>> > > >> wrote:
>>>
>>> > > >> > But you would still have to place these concerns somewhere in the
>>> > > >> > layout or in the view, so it's the same as RenderAction. The only
>>> > > >> > advantage is the possibility of processing all these sub-actions in
>>> > > >> > parallel, but you'd lose the ability to define different parameters
>>> > > >> > for each sub-action (i.e. they
>>>
>
>> ...
>>>
>>> read more »
>
>>--
>>You received this message because you are subscribed to the Google Groups 
>>"Castle Project Development List" group.
>>To post to this group, send email to [email protected].
>>To unsubscribe from this group, send email to 
>>[email protected].
>>For more options, visit this group at 
>>http://groups.google.com/group/castle-project-devel?hl=en.
>
>


-- 
Ken Egozi.
http://www.kenegozi.com/blog
http://www.delver.com
http://www.musicglue.com
http://www.castleproject.org
http://www.idcc.co.il - הכנס הקהילתי הראשון למפתחי דוטנט - בואו בהמוניכם

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Development List" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-devel?hl=en.



      

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Development List" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-devel?hl=en.

Reply via email to