My Thoughts on an MVVM-friendly DomainDataSource


The DomainDataSource (DDS) could be a great example of an aggregate component. It has a simple public API and does a lot of awesome things at the flip of a switch. The only problem with the thought is there’s little-to-no aggregation going on. All the composition that occurs is hidden behind a wall of internal API. This is especially frustrating for MVVM development where a lot of what the DDS does is not as useful.

In creating an MVVM-friendly DDS we have to figure out the primary components and how they work together. Here’s a rough sketch of where I imagine this design will go. This pattern is so well-worn, I’d almost feel guilty deviating from it.

image

Even with something so familiar as the base, there are a ton of features to pack in. Here are the set I considered with a few ‘cut’ lines drawn through for priority. High-priority features are the bare essentials for an MVVM-friendly DDS. Medium-priority features are great, but not critical. Low-priority features are things I’ll consider but will probably never get to. Please let me know if you think something needs to be added, removed, or moved to a different priority level.

   ===== High Priority =====

Source: EntitySet – Using an EntitySet with the rest of the features.
Source: EntityCollection – Using an EntityCollection with the rest of the features.
Source: Read-Only Collection – Using a read-only collection with the rest of the features.
Source: Mutable Collection – Using a mutable collection with the rest of the features.

Server: Sorting – Applying sorting to the data on the server.
Server: Grouping – Applying grouping to the data on the server.
Server: Paging – Applying paging to the data on the server.

Editing: Adding – Adding a new Entity to the source collection.
Editing: Removing – Removing an Entity from the source collection.

Testing: Component Base Classes – Abstract base classes for individual components.

Designer: View – Any view property can be set in xaml using a designer.

Quality: Toolkit – High-quality, partially-supported features.

   ===== Medium Priority =====

Client: Filtering – Applying a filter to the source collection on the client.

Server: Filtering – Applying a filter to the data on the server.

Query: Dynamic ‘And’ – Creating an EntityQuery using ‘And’ from a dynamic set of filters on the client.
Query: Dynamic ‘Or’ – Creating an EntityQuery using ‘Or’ from a dynamic set of filters on the client.
Query: Nested – Creating an EntityQuery with nested clauses from a dynamic set of filters on the client.
Query: Shaping– Creating an EntityQuery from a dynamic set of sorts, groups, or paging parameters on the client.

Other: Strong-Typing – Strongly-typed API for Entity interaction.
Other: Source Code – Feature source code.
Other: Samples – Feature samples.

Quality: Framework – High-quality, fully-supported features.

   ===== Low Priority =====

Client: Sorting – Applying sorting to the source collection on the client.
Client: Grouping – Applying grouping to the source collection on the client.
Client: Paging – Applying paging to the source collection on the client.

Loading: Auto – Tracking changes that affect the query and automatically reloading.
Loading: Timed – Reloading based on a timed interval.
Loading: Incremental – Incrementally loading a large data set in smaller blocks.

Testing: Top-level Interfaces – Interfaces for the top-most aggregate objects.
Testing: Component Interfaces – Interfaces for individual components.

Designer: Filtering – Defining filters in xaml using a designer.
Designer: Sorting – Defining sorts in xaml using a designer.
Designer: Grouping – Defining groups in xaml using a designer.

Other: Hot-Swapping – Switching between client and server data shaping during use.

Quality: Preview – Medium-quality, mostly unsupported features; as soon as possible.

Comments (5)

  1. Keith Farmer says:

    IMHO —

    Consider emphasizing this metric: chatter (and bandwidth generally) should be reduced to a minimum

    To that end, Filtering on the server should be perhaps the biggest priority after being able to connect at all.

    Ordering next, and Paging after that — paging is an application of ordering and filtering.

    Both of these should trump editting/adding.  More reporting of data happens than data entry, in my estimation.

    I'd move client-side filtering to a lower priority.  Until you have an offline data scenario (and, therefore, a client-side cache of the data) there's little point.

  2. kylemc says:

    @Keith

    My thinking on this was slightly different. In the context of a DDS, we're talking about filtering via ICollectionView.Filter. It's not exactly clear how to 'translate' this to server filtering.

    Alternatively, RIA supports server-side filtering quite well already. I imagine the 'Loader' component will be the primary piece written by MVVM developers to define how their data is loaded. My thought was they could use the stock RIA filtering until something gets baked deeper into this design.

  3. Aquilax says:

    Sometimes I miss the good old asp.net object data source.

    For me it was a good bridge between the controls architecture and a BL class (or view model).

    When you are unit testing a BL class, it's more logic a method like UpdateObjectX(ObjectX obj) than a method UpdateCurrentObjectX() with a property CurrentObjectX.

  4. weitzhandler says:

    Hi Kyle and thanks for your great work!

    I actually somewhat agree with Keith.

    I would add support for a local cache in higher priority than local filter etc.

    Because once the cache is there it's easier to define whether there are more data to load (according to results from a total Count query etc.), and if there isn't any expected data in server we don't query the db (or we make access to server on demand leaving the current cache be the strong-side, unless user clicked or check "load from server", will be useful in long running client applications).

    Thanks a lot

  5. Ession says:

    Dear Kyle McClellan:

       I have got a problem while using  DomainDataSource + DataGrid + Sorting. The service-side  

    paging and sorting  can NOT work if  code like this :

         public IQueryable<TB_SORDER> GetTB_SORDER()

           {

                return this.ObjectContext.TB_SORDER.AsQueryable();

           }

    But if I add the ToList() Method, then code like this :

         public IQueryable<TB_SORDER> GetTB_SORDER()

           {

               return this.ObjectContext.TB_SORDER.ToList().AsQueryable();

           }

    It CAN work  but take a lot more time.

    What can I do to solve this problem?  

    Thanks very much for  your help !

    P.S.  It is a oracle database .

Skip to main content