So for things like Active Record data binding, fetching etc. would that be
something like?

config.For("/Product/Update/")
 .MapToCommand<ProductListCall>()
 .BindWith(new ActiveRecordDataBinder { Prefix="product" });

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

> >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]<castle-project-devel%[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]<castle-project-devel%[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]<castle-project-devel%[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