Of course, this is really just a custom binding question in general.. I just
like to mention ActiveRecord because I still maintain some AR+Monorail
codebases, and it's batteries included experience for basic app's is still
quite compelling to beginning users.

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

> Sorry Alex but I haven't really thought about AR, I'm a NHF + NH guy.
> But once I have something working and ready to share, I'm open for
> suggestions ;)
>
> Cheers John
>
> On 22/03/2010, at 18:18, Alex Henderson <[email protected]> wrote:
>
> 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]>
> [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>
>> 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]>[email protected]>
>> *To:* <[email protected]>
>> [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]>
>> [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>
>>> 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]>
>>> [email protected].
>>> To unsubscribe from this group, send email to
>>> <castle-project-devel%[email protected]>
>>> [email protected].
>>> For more options, visit this group at
>>> <http://groups.google.com/group/castle-project-devel?hl=en>
>>> http://groups.google.com/group/castle-project-devel?hl=en.
>>>
>>>
>>
>>
>> --
>> Ken Egozi.
>> <http://www.kenegozi.com/blog>http://www.kenegozi.com/blog
>> <http://www.delver.com>http://www.delver.com
>>  <http://www.musicglue.com>http://www.musicglue.com
>>  <http://www.castleproject.org>http://www.castleproject.org
>> <http://www.idcc.co.il>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]>
>> [email protected].
>> To unsubscribe from this group, send email to
>> <castle-project-devel%[email protected]>
>> [email protected].
>> For more options, visit this group at
>> <http://groups.google.com/group/castle-project-devel?hl=en>
>> 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]>
>> [email protected].
>> To unsubscribe from this group, send email to
>> <castle-project-devel%[email protected]>
>> [email protected].
>> For more options, visit this group at
>> <http://groups.google.com/group/castle-project-devel?hl=en>
>> 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.
>
>
>
>
> --
> 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