Aug
8
2011

WCF RIA Services EF 4.1 Scaffolding Support, WCF RIA Services Contrib, and NuGet

Two big announcements today. First, the old RiaServicesContrib.dll file has been replaced with RiaServicesContrib.EntityTools.dll and is now available as a NuGet package. The package name is RiaServicesContrib.EntityTools. Hope that is easy to remember.

The other news is that RIA Services Contrib has a new scaffolding system for EF 4.1.

Soon after WCF RIA Services support for EF 4.1 was released, Rudi Larno released a scaffolding system for building the DomainServices based on the EF model. Unfortunatly, Rudi doesn't have time to maintain what he built so I am taking it over for him. Today I added the scaffolding code to the RIA Services Contrib project on Codeplex and published it on NuGet.

The scaffold is not exactly the same as what Rudi was using. When you create a DomainService using the scaffold you may need to add a new using statement with the namespace where your POCO entities are. Also, I modified what is generated to match the snippet code supplied by Microsoft.

To install the scaffolder

1) In the Package Manager Console select the package that will contain the DomainService
2) Type Install-Package RIAServicesContrib.EntityFramework.Scaffolding and push enter

To use the scaffolding system, in the PackageManagerConsole type in the following command line:

Scaffold RiaContribEfDomainService <TEntity> <TDbContext> <TDomainService>

So, if you are adding the Customer entity from the OrderEntities DbContext and you are creating the OrderDomainService you would type

Scaffold RiaContribEfDomainService Customer OrderEntities OrderDomainService

 

 

Jun
30
2011

WCF RIA Services support for EF 4.1 and Snippets

WCF RIA Services now has support for EF 4.1. Varun Puranik and Jeff Handley have details on their blogs about how to use it.

One of the really interesting things Varun provides is a snippet to help setup the DbDomainService since the Wizard will not be available until SP2 is released. After using the snippet I am not sure what we all did without it.

To help make it even better, I have made my own modifications and, since Varun released the original under MS-PL, I am adding the snippets to RIA Services Contrib. For now they are available at the bottom of this post.

I actually have six different snippets for both VB and CS covering both DbDomainService and LinqToEntitiesDomainService.

The six snippets are:

  • dbcrud : Code snippet for DbDomainService CRUD Methods
  • dbcrudt : Code snippet for DbDomainService CRUD Methods With Timestamp
  • dbnu : Code snippet for a DbDomainService Named Update Method
  • ltecrud : Code snippet for LinqToEntitiesDomainService CRUD Methods
  • ltecrudt : Code snippet for LinqToEntitiesDomainService CRUD Methods With Timestamp
  • ltenu : Code snippet for a LinqToEntitiesDomainService Named Update Method

RiaServicesContribSnippets.zip (3.78 kb) 

 

May
4
2011

MEFing up RIA Services Part 2: Kyle's Turn

Last week Kyle McClellan from the WCF RIA Services team at Microsoft posted his own version of the Book Club sample. Not wanting Kyle to be left out, I decided to MEF up his code as well.

Here is the result:

MEFedUpRIAServicesMVVM_V2.zip (3.27 mb)

I think Kyle is doing some really interesting things with this code, but I think I prefer how John's original code used ObservableCollections (which were really EntityLists) instead of how Kyle is casting everything to IEnumerable or ICollection. What I will be creating next is my version of the Book Club which will be a mix of John's code, Kyle's code, and some completely different concepts that I am working on.

Apr
13
2011

The State of the Blog: Please Welcome HTML and JQuery to the Party

Since this blog first opened in June of 2009 it has been named The Elephant and the Silverlight. The name came from John Godfrey Saxe’s The Blind Men and the Elephant. At the time, WCF RIA Services was all about Silverlight and people were arguing about just what WCF RIA Services and Silverlight were. The name made sense at the time.

However, this blog has really always been about WCF RIA Services, Silverlight was just along for the ride. Here in 2011, WCF RIA services isn’t just about Silverlight anymore. With the release of RIA/JS, HTML is joining Silverlight as a fully functional client of WCF RIA Services. While I am still primarily a Silverlight programmer, I will be expanding my coverage and my community support efforts to include the HTML platform. So, the name of this blog is changing to just The RIA Services Blog to reflect the new platform agnostic approach I will be taking around here.

So, to the HTML JQuery programmers out there, welcome to my blog. Please cut me some slack, it will take me a little while to get fully up to speed on this whole JQuery thing but I am eager to learn.

To my fellow Silverlight developers, don’t worry I am not going anywhere. I still strongly believe in Silverlight and most of my development efforts will continue to be in the Silverlight space. I think there is an opportunity with RIA/JS for us Silverlight developers to show how easy it would be to create fallback HTML versions of our Silverlight applications so that we can get the best of both worlds. Silverlight for the platforms that support it, and HTML for the platforms that don’t. With tools like RIA/JS, maybe this dual approach will not mean actually writing the application twice.

Mar
21
2011

MEFing up John Papa’s MVVM code from Firestarter

Back on December 2, 2010 John Papa gifted the community with an excellent example of proper Silverlight architecture and I have been recommending people watch the video, download John’s code, and follow the pattern to create their own applications.

Over the last couple of weeks I have started a new project at work and this time I have decided to follow the example I have given to others. This experience is showing some places where my own preferences diverge from John’s so I have decided to share my changes with the community. I am taking the experiences in my own project and porting them into John’s project. I am not going to dump all of my changes in at once, I am going to be making gradual changes across at least three blog posts. In this first post I will be integrating Marlon Grech’s MEFedMVVM library into John’s code. Over the new two blog posts I will be changing the DataServices to use ICollectionView instead of EntityList and in the third post I will be changing the design time DataServices to use the actual RIA Servics entities instead of separate design time entities. Kyle McClellan on the RIA Services team at Microsoft has come up with something better then what I was working on for parts 2 and 3. Check it out at http://blogs.msdn.com/b/kylemc/archive/2011/04/29/mvvm-pattern-for-ria-services.aspx. I will be posting up a MEFed up version of Kyle's project.

MEFing up the code

Out with the old

I am going to be gutting John’s provider and locator code to replace them with MEFedMVVM replacements. This means that I first deleted the following classes:

  • Assets\ObjectResourceDictionary
  • DesignServices\DesignServiceConductor
  • Services\ServiceProvider
  • Services\ServiceProviderBase
  • ViewModels\ViewModelLocator

Then I removed the following line from the App.xaml

<ResourceDictionary Source="Assets/ObjectResourceDictionary.xaml"/>

MEFing up the views

Now I was ready to put MEFedMVVM into place. First I coped MEFedMVVM.SL.dll into the Lib directory of the project and added a reference. Then I needed to add MEF itself which is done by referencing System.ComponentModel.Composition

Next, BookView.xaml, CheckoutView.xaml, and EditBookWindow.xaml need the meffed namespace registered:

xmlns:meffed="http:\\www.codeplex.com\MEFedMVVM"

 

Then in BookView.xaml and EditBookWindow.xaml John’s original locator code was replaced with:

meffed:ViewModelLocator.SharedViewModel="Book"

In CheckoutView.xaml the locator code was replaced with:

meffed:ViewModelLocator.NonSharedViewModel="Checkout"

The use of SharedViewModel and NonSharedViewModel mirrors the original design that John used. BookView.xaml and EditBookWindow.xaml will share the same instance of the ViewModel while CheckOutView.xaml will get a new instance of its ViewModel every time it loads.

MEFing up the ViewModels

I registered the BookViewModel with MEF using the MEFedMVVM ExportViewModel attribute

    [ExportViewModel("Book")]
    public class BookViewModel : ViewModel

then I decorated the constructor:

[ImportingConstructor]
public BookViewModel(IPageConductor pageConductor,IBookDataService bookDataService)

CheckoutViewModel was edited the same way:

[ExportViewModel("Checkout")]
public class BookViewModel : ViewModel
public CheckoutViewModel(IPageConductor pageConductor,IBookDataService bookDataService)

MEFing up the DataServices and PageConductors

Last step was registering the DataServices and PageConductors. These were registered with MEF using MEFedMVVM’s RegisterService attribute which allows us to set a ServiceType of Runtime, DesignTime, or Both. By registering the DesignBookDataService and the DesignPageConductor as having a ServiceType of DesignTime we will get the same design time data support that John had in the original version.

[ExportService(ServiceType.DesignTime, typeof(IBookDataService))]
public class DesignBookDataService : IBookDataService
[ExportService(ServiceType.DesignTime, typeof(IPageConductor))]
public class DesignPageConductor : IPageConductor
[ExportService(ServiceType.Runtime, typeof(IBookDataService))]
public class BookDataService : IBookDataService
[ExportService(ServiceType.Runtime, typeof(IPageConductor))]
public class PageConductor : IPageConductor

 

Conclusion

I think the MEFedMVVM way of doing things is both simpler and more powerful than John’s original method. It greatly reduces the amount of classes needed and makes it much easier to add new Views, ViewModels, and DataServices to your solution. Here is the ZIP file containing the modified solution:

MEFedUpRIAServicesMVVM.zip (6.56 mb)

Jun
1
2010

WCF RIA Services Speculation: EntityCollectionView

Disclaimer:
I am not a Microsoft employee, I have not even played a Microsoft employee on television. What follows is my own ideas on a what part of a future version of WCF RIA Services could look like.

What we know


As of this writing, MVVM friendly DomainDataSource is the fifth most requested feature for the next version of WCF RIA Services. According to Jeff Handley, this is what he envisions for this feature:

    What I have been imagining is taking the existing DomainDataSource feature and splitting it up into a set of components that can be used selectively from a ViewModel, or used all together as the DomainDataSource control that you know.
    The PagedEntityCollectionView class would likely become public, as well as the EntityCollectionView. I'd also like to break the data loading functions out so that the logic used to submit the requests for loads and the response handling could be utilized from a ViewModel. The DomainDataSource manages situations such as hierarchical data and there's a lot of code involved to replicate that in a ViewModel--I'd love to see those functions exposed for easy consumption without using the DomainDataSource control in the UI.
    So I really see this item as a way to get the features of the DomainDataSource out of the DomainDataSource, and available to developers to use how they wish."

Why this matters

Over the last two posts, I have been discussing ways that a ViewModel could present collection of Entities to the View. Of the options I presented only the PagedCollectionView is acceptable to me in the short term but in the long term there clearly has to be a better way. The other option which I hadn't previously mentioned is to build something new from scratch, an option that I have contemplated myself. The reason that I haven't is that I do not like duplicating logic that already exists and the fact that the PagedCollectionView and the EntityCollectionView already exist make me unlikely to want to write my own ICollectionView from scratch. To me, the best solution is to get the public EntityCollectionView that some of us have been talking about for a year now.

EntityCollectionView? What is that?


Outside of a few old blog entries from Jeff and Brad you probably haven't heard of the EntityCollectionView. The EntityCollectionView is everything that the PagedCollectionView isn't. It is strongly typed, it supports the Entity, it supports IEditableCollectionView against an EntitySet, it supports external delegates to implement adds, removes, and deletes, and finally there is a PagedEntityCollectionView that adds RIA Services integrated paging support. Unfortunately, the current EntityCollectionView is internal and can only be used by the DomainDataSource. It will take lots of time to properly refactor the DDS and get all of the interfaces fully implemented, time that simply didn't exist for the initial release of RIA Services. Anyone who has been following the development of RIA Services knows the DomainDataSource was probably the most actively modified component of RIA Services right up to the end. They would also know that the DomainDataSource also the most monolithic parts of RIA Services.
What we can gather from Jeff's above statement is that he wants to refactor the DomainDataSource to better match the rest of RIA Services itself. That means being more modular and being more programmer driven. For the rest of this post, I am going to discuss some scenarios that I think should be covered by the new classes:

EntityQuery support


In the previous post I had a link to an overview of the ICollectionView. One of the issues with most implementations of ICollectionView is that sorting is slow due to reflection issues. Another issue that is specific to RIA Services is that for loading data we have the EntityQuery but for the ICollectionView we have the Filter and the SortDescriptions. Having two different methods of doing the same thing would be annoying. What would be better is the ability to supply the EntityQuery to the EntityCollectionView. This would allow the same EntityQuery to be used for the load and the filter.
The unknown here is if the ICollectionView.Filter and ICollectionView.SortDescriptions should still be implemented or not. The SortDescriptions could probably be derived from the EntityQuery (and the reverse) but the Filter is tricky.

Read Only Mode and user providable methods for insert and delete

The ViewModel needs to be the owner of the EntityCollectionView and control of insert, deleting, and paging. In many cases, the EntityCollectionView can be left to default functionality but in others the ViewModel needs to provide the actual logic. A good example of this would be to look at how the EntityCollection is implemented in your generated code. That shows an example of how add and delete logic can be externally supplied.
Unfortunately, this does mean that the constructor for the EntityCollectionView may end up being rather complex. It is possible that some kind of "controller" object may be needed that can be supplied during construction and held onto by the ViewModel.

Strongly Typed


One of the biggest problems with the PagedCollectionView is that it is not strongly typed. The problem here is that there may be other logic within the ViewModel that wants to use the same CollectionView that the View itself is seeing. Without strong typing, this requires lots of type casting which is, at best, annoying.

Paging


Yes, the need for paging is obvious, but it also important to keep in mind the type of paging that is needed. It is possible that in some situations that the paging is being done only against already loaded entities. Much like with the update and the delete, we need to be able to override the paging so that the ViewModel can override.

Conclusion


This has been an interested three part series for me as it helped clarify some ideas that I have had for awhile. For this post in particular, if you have any scenarios that you think the EntityCollectionView needs to cover please let me know and I will see if I can modify the post to account for it.

May
29
2010

Advanced Paged Collection View

In the previous post I showed some of the ways that collections of entities can be exposed from your ViewModel. The load examples I showed was relatively simple as it demonstrated a simple load with no ordering or filtering and there was only a single load. In a more realistic example where ordering or filtering is being used and the EntitySet cannot be cleared between loads then only the PagedCollectionView and ObservableCollection will work. In this post, I will show a more full example of how you can combine WCF RIA Services, ViewModel, and PagedCollectionView to fully support filtering, sorting, and multiple loads.

private PagedCollectionView _customers; 
public PagedCollectionView Customers
{ 
    get
    {
        if (_customers == null)
        {
            _customers = new PagedCollectionView(Context.Customers);
            _customers.SortDescriptions.Add(new SortDescription("Name", ListSortDescription.Ascending));

         }
        return _customers;
    }
}

public void LoadCustomersByState(string state)
{
    var qry = this.Context.GetCustomersQuery().Where(c=>c.State == State).OrderBy(c=>c.Name);
    LoadOperation loadOp = this._customerContext.Load(qry);
    Customers.Filter = c=>((Customer)c).State == state;
}

When the PagedCollectionView was created, a SortDescription was set, this ensures that the PagedCollectionView will always be correctly sorted. The load is not clearing the EntitySet so it is possible for customers from multiple states to be loaded at the same time but the filter on the PagedCollectionView makes sure that only the currently selected state’s customers is being shown.

It is possible to get the same effect using the ObservableCollection but it requires refilling the ObservableCollection every time an entity is updated or inserted into the EntitySet which can cause problems for the bound UI controls.

 

The above example shows how to keep the load in sync with the PagedCollectionView, here is a second scenario where the load is separated from what is being shown in the UI:

private PagedCollectionView _customers; 
public PagedCollectionView Customers
{ 
    get
    {
        if (_customers == null)
        {
            _customers = new PagedCollectionView(Context.Customers);
            _customers.SortDescriptions.Add(new SortDescription("Name", ListSortDescription.Ascending));
            _customers.Filter = c=> (string.IsNullEmpty(SelectedState) || ((Customer)c).State == SelectedState);
         }
        return _customers;
    }
}

private string _selectedState = null;
public string SelectedState
{
    get {return _selectedState;}
    set
    {
        _selectedState = value;
        Customers.Refresh(); //this lets the PCV know that the filter changed
        RaisePropertyChanged(“SelectedState”);
    }

public void LoadCustomers()
{
    var qry = this.Context.GetCustomersQuery().OrderBy(c=>c.Name);
    LoadOperation loadOp = this._customerContext.Load(qry);
}

 

Wrap Up

The most important thing that the PagedCollectionView gains you is a clear separation of concerns within the ViewModel. Any business logic code adding, deleting, or updating entities does need to worry about updating the UI, that is taken care of by the PagedCollectionView which is monitoring the EntitySet itself for those changes. The only thing that the PagedCollectionView cannot detect for itself is when the any external values used in the Filter are modified so you do need to keep track of that and call the Refresh method whenever that happens. Other then that, in the ViewModels that the above code would be a part of no other reference to the PagedCollectionView properties would be necessary. The same can not be said for any of the other options that are available. In the last part of this series I will be discussing what is coming in the future.

May
29
2010

View Model Collection Properties for WCF RIA Services

For the most part combining WCF RIA Services with the MVVM pattern is easy. One area of difficulty is in exposing collections of entities from the ViewModel. This post is going to show some of the current possibilities including my favorite solution, the PagedCollectionView. In two follow up posts I will be discussing some more advanced PagedCollectionView examples and then some future possibilities.

Using LoadOperation.Entities

private IEnumerable<Customer> _customers; 
public IEnumerable<Customer> Customers
{ 
    get {return _customers;}
    private set
    {
        _customers = Customers;
        RaisePropertyChanged("Customers");
    }
}

public void LoadCustomers()
{
    LoadOperation loadOp = this.Context.Load(Context.GetCustomersQuery());
    Customers = loadOp.Entities;
}

Pros

  • Simple, easy to understand.
  • Matches example code from RIA Services documentation.

Cons

  • LoadOperation.Entities is read only, so this is only suitable for read only applications.

Using EntitySet

public IEnumerable<Customer> Customers
{ 
    get {return Context.Customers;}
}

Pros

  • Simple
  • EntitySet does implement INotifyCollectionChanged so as it is updated the UI will be automatically refreshed.

Cons

  • Exposing the EntitySet to the view, even hidden behind IEnumerable, gives the view too much access.
  • Binding to the EntitySet means that there is no ability to filter, everything in the EntitySet will be bound to the UI.
  • The built in add/remove abilities of the DataGrid and DataForm do not support the EntitySet

Using ObservableCollection

private ObservableCollection<Customer> _customers; 
public ObservableCollection<Customer> Customers
{ 
    get {return _customers;}
    private set
    {
        _customers = Customers;
        RaisePropertyChanged("Customers");
    }
}

public void LoadCustomers()
{
    this.Context.Load(Context.GetCustomersQuery(), LoadCustomersCompleted, null);
}

private void LoadCustomersCompleted(LoadOperation<Customer> lo)
{
    Customers = new ObservableCollection<Order>(Context.Customers);
}

Pros

  • ObservableCollection is not read only so this code is not limited to read only applications.
  • ObservableCollection does implement INotifyCollectionChanged so as it is updated the UI will be automatically refreshed.

Cons

  • Every insert, delete, clear, detach, attach, and load within the ViewModel has to manually keep the ObservableCollection in synch. This makes it easy to get into situations where the ObservableCollection gets out of synch with the DomainContext. The worst case scenario here is that a deleted entity gets re-added as a new entity accidently because it hadn’t been removed from the ObservableCollection.
  • ObservableCollection implements IList. This means that the built in add and remove for both the DataGrid and DataForm will be enabled even though any entities added or removed directly to the ObservableCollection will not be added or removed from the EntitySet.

Using an ICollectionView

What is ICollectionView?

Marlon Grech has a good primer on the ICollectionView, I suggest you go and read his entry on them and then come back.

Have a good read? Great, so now you know what ICollectionView does. Unfortunately, the classes demonstrated by Marlon are marked as internal in Silverlight so we can’t use them. Fortunately, we did get a consolation prize back in Silverlight 3: PagedCollectionView.

Using PagedCollectionView (PCV)

private PagedCollectionView _customers; 
public PagedCollectionView Customers
{ 
    get
    {
        if (_customers == null)
            _customers = new PagedCollectionView(Context.Customers);
        return _customers;
    }
}

public void LoadCustomers()
{
    LoadOperation loadOp = this.Context.Load(Context.GetCustomersQuery());
}

Pros

  • PCV automatically refreshes based on the contents of the EntitySet.
  • PCV has full sorting and filtering ability. This will be demonstrated in the second post of this series.

Cons

  • The PCV’s implementations of IEditableCollectionView and IPagedCollectionView are not compatible with the EntitySet. However, the incompatibility is reported by the PCV so the built in add/remove abilities of the DataForm and DataGrid are properly disabled.
  • The PCV is not strongly typed limiting its usefulness inside the ViewModel.
  • ICollectionView includes a “CurrentItem” property which is used by bound list controls. For example, if two comboboxes are sharing the same PagedCollectionView for the ItemsSource then changing the selection in one combobox will cause the selection to change in the second combobox as well.

Conclusion

None of the above options are perfect, but the PagedCollectionView is certainly the best option that we currently have. In my next post I will be discussing the PagedCollectionView in more depth and in the third post I will be discussing what the optimal solution would be.

Jan
5
2010

Proposed WCF RIA Services Sessions for MIX10

Earlier today Microsoft opened voting for the MIX10 Open Call entries. I am happy to see that at least eleven of the submissions mention WCF RIA Services. Even if you are not attending MIX10 it is still important that everyone posts as the sessions will be available on the web along with the rest of the MIX10 sessions.

You can see all of the submissions here.

Real World Silverlight Line of Business ApplicationsMix10_Vote_grn_240

I do have my own horse in this race, and it is the session I have linked above. The application I will be showing is actually rather important from a historical perspective as it is the application I have been writing for the last year. If you have been helped by any of my blog entries, answers on the forums or tweets then this is the application you have to thank. The total list of technologies that I used (and in some cases changed) are:

  1. Silverlight 2 –> 3
  2. Data Services –> .Net RIA Services –> WCF RIA Services
  3. Enitty Framework
  4. Deep Earth –> Bing Silverlight Map Control –> ESRI Silverlight API
  5. XAML Power Tools (thanks Karl!)
  6. Prism
  7. SandDock/SandRibbon –> Telerik Controls
  8. SQL Server 2005/2008
  9. Visual Studio 2008
  10. ArcGIS Server

As you can see, I have a pretty large stack of stuff that I have used so I will not be able to cover all of it in depth. If my session is selected I will be open to suggestions on what pieces I cover more than other pieces.

Month List