Future support for ASP.Net MVC DisplayTemplates, etc.

Sep 19, 2010 at 3:07 PM
I'm spending some time evaluating frameworks for my current project, and I'm down to choosing between Magellan or nRoute.  I have three questions that should sway my decision either way. :)

1) Are you planning to add a feature similar to ASP.Net MVC's Object Templates, which recursively nests views based on model type (and/or other factors) (see http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html).
2) Do you have plans to add Async ViewModel properties.  In one of your examples, you accomplish this by using the new .Net rX framework and subscribing to events and raising events, however, this solution is rather clunky.  I'd like to see something a little simpler.  For example, just returning an expression that raises a CollectionChanged if part of the data inside it changes and would result in the overall collection change.  You can look at the Obtics library to see an example of a library that can do this.  However, the new .Net rX library at least partially does what Obtics does, so maybe there is already support for this inside rX and you just didn't use it in your examples?
3) Are you planning to add implicit routing support?  For that matter, implicit View/ViewModel/Controller locating using naming conventions.  For examples, see http://code.google.com/p/magellan-framework/wiki/ViewEngines.

 

Sep 19, 2010 at 3:09 PM

Actually, let me add a fourth.  Once of Magellan's strongest features is its integration with other frameworks.  You can use pretty much any other framework with it (Prism, MVVM, MVC, Unity, etc.).

How is nRoute's integration, and will you add support for any other popular presentation or IOC frameworks?

Coordinator
Sep 19, 2010 at 8:51 PM

Hi Josh, interesting questions, though I presume you are coming from a MVC background? If so, then I would suggest than keep an
open-mind about using the features already in WPF rather trying to turn WPF into a skirt-wearing MVC clone decorated with xaml. Each
architecture/platform has its strengths, play to those and extend where you must. 

Now as for your first point, the MVC Object templates - well, IMHO WPF already has a much superior templating engine that can be
extended/customized quite easily. Plus, it features a well-defined seperation between the logical and the visual representation, which
is far more natural than using display templates at the control level like with your link. At a higher level of abstraction, you can depending
on the use-case, easily choose between switching data-templates or use a Url based switching. Multiple times I've used Url based
switching of Views and it works well - but at that level of usage we are talking more-so about navigation than templating. Semantics, I suppose.

As for you second question, I reckon there is no good case for using not using INPC or INCC. And that is because WPF/SL UI
controls are geared to listen to those built-in interfaces, as opposed to Rx notifications - for example to use Obtics with WPF,
you have to dabble with a helper (http://obtics.codeplex.com/wikipage?title=ObticsWpfHelper&referringTitle=Home). That to
me means you not only have to go out of you way with the VM but also with the View, which IMHO leads to a more
fragile/unmaintainable codebase. This is not to say you can't use helper or other techniques; be assured nRoute provides
a fair share of helpers/components to help where it can.

Thirdly, implicit routing is possible today - just implement a custom IRouteHandler. Further, to use Controllers based View/VMs
all the necessary infrastructure is already there, just I've not been keen on using a MVC type setup with a VM as it doesn't make
much sense in an entirely client-side application where MVVM is more appropriate pattern. Why do we need a controller, when
 we can go directly to a (live) View-VM pairing using navigation - and in 0.05% of cases where you do need to go
through a Controller, nRoute features a NavigateResult ActionResult-type or you can create your own ActionResult.

Lastly, about integration with other frameworks - humm, honestly I've not tried recently because nRoute does cover almost all of 
bases as far as a composite application framework is concerned. Though other projects are having some success like this one
http://bit.ly/bn7co7. However, I'll admit, as of now nRoute doesn't play nice with other IoC containers because it has it's own
"open-ended" DI/IoC component (quite like MEF), but the next release will see the use of IServiceLocator so you can plug in
your choice of IoC/DI component. 

Hope this helps,
Rishi 

PS: nRoute doesn't use Rx-framework, per se. We share IObserver/IObservable definitions, so it allows you to use Rx with nRoute
but nRoute doesn't depend on Rx itself. We have our own implementations, most notably an event aggregator like implementation
we call Messaging Channels. 

 

Sep 20, 2010 at 5:26 PM

In bringing up Obtics, I think I kind of blurred two different features together.  First, the ability to provide "auto-async" members from the VM (provide a temporary value while you wait for the slow value to finish loading).  And second, the ability to have a self-updating expression result.  The second is provided by Obtics, rX, and a few other frameworks, and I see no need for it in a Presentation framework.  The first is what seems like its missing from nRoute.

As for code maintainability, without the use of an "auto-async value provider mechanism", one commonly does the following:
For each property available for binding, provide a temporary value. Subscribe to change notifications on the real value query.  When the real query finishes, replace the temporary value.  And then raise the appropriate change events.
Now skipping all that and providing some auto-async provider seems like much less code and work, making it more maintainable.
For example, Caliburn provides an attribute you can apply to any VM member that automatically makes binding to that member async.  I haven't used this one, but it seems pretty simple.  In the past, I've just rolled my own, which works, too.
Coordinator
Sep 21, 2010 at 6:48 PM

I get you, so basically want infrastructure support for non-visual asynchronous consumption. Well, my take is that Rx is perhaps the best framework out there for asynchronous consumption – and it even plays nice with the dispatchers in WPF/SL. Plus, by its very nature it is extensible and the syntax/API is quite compact too. Also, once you get a hang of its approach, using observables becomes second-nature quite like LINQ has.

Also, not to nitpick, but you don’t/shouldn’t need a temporary value – the default null value is the temporary value, and your UI should be able to handle that gracefully. So really, the only thing you are missing is auto-raising of notifications, which if you are so adamant about, you can use code-weaving to totally get out of INPC business. And from what I understand, the issue/problem with caliburn’s notification infrastructure is that it requires the use a custom contraption on the View – which means for one you are now tightly coupled to caliburn’s unique way (not that there's anything wrong with that ™), and second you lose lot of tooling support like with Blend.

That’s my 2 cents, cheers
Rishi

Coordinator
Sep 22, 2010 at 11:15 AM
Edited Sep 22, 2010 at 11:17 AM

@Josh This library might interest you - it uses Rx with MVVM, XAML and WPF http://blog.paulbetts.org/index.php/category/programming/reactive-extensions/

Cheers,
Rishi

Sep 28, 2010 at 2:57 AM
Edited Sep 28, 2010 at 3:07 AM

@Josh Hi, I'm the author of ReactiveXaml, the library that Orktane mentioned - I believe that RxXaml would let you do that fairly easily via ReactiveAsyncCommand (an ICommand implementation that helps out with running things in the background and returning the results).  Here's how you would do this:

 

public class CoolViewModel : ReactiveObject
{
    //
    // Standard way in RxXaml to declare a notification-enabled property
    // 

    string _InputData;
    public string InputData {
        get { return _InputData; }
        set { this.RaiseAndSetIfChanged(x => x.InputData, value); }
    }

    // Our ICommand - invoking this will *begin* the async operation
    ReactiveAsyncCommand DoubleTheString;

    //
    // OAPH will create an 'output' property - that is, a property who will 
    // be updated via an IObservable<string>
    // 

    ObservableAsPropertyHelper<string> _OutputData;
    public string OutputData {
        get { return _OutputData.Value; }
    }

    public CoolViewModel(Window MainWindow)
    {
        DoubleTheString = new ReactiveAsyncCommand(null, 1);

        IObservable<string> doubled_strings = DoubleTheString.RegisterAsyncFunc(x => {
            // Pretend to be a slow function
            Thread.Sleep(1000);
            return String.Format("{0}{0}", x);
        });

        //
        // ReactiveAsyncCommand will fire its OnNext when the command is *invoked*,
        // and doubled_strings will fire when the command *completes* - let's use
        // this to our advantage:
        //

        IObservable<string> result_or_loading = Observable.Merge(
            DoubleTheString.Select(x => "Loading..."),
            doubled_strings
        );

        // Hook up our new 'result_or_loading' to the output
        _OutputData = this.ObservableToProperty(result_or_loading, x => x.OutputData);

        //
        // We can even be a little clever here
        //

        Observable.Merge(
            DoubleTheString.Select(x => "LoadingState"),
            doubled_strings.Select(x => "NormalState")
        ).Subscribe(state => VisualStateManager.GoToState(MainWindow, state, true));
    }
}

 

Sep 28, 2010 at 2:59 AM

Whoops, that first line should read "class CoolViewModel : ReactiveObject", but you get the idea.