Dec
3
2009

To Share or Not to Share

One of the really interested puzzles that occurred to me with the release of SL4 and the VS2010 version of WCF RIA Services is what the new ability of .NET 4 to reference SL4 code libraries means to the WCF RIA Services shared file feature. My thinking goes like this:

  1. The shared code feature was created because the Silverlight and Desktop CLRs couldn’t share assemblies.
  2. The Desktop CLR can now reference Silverlight 4 assemblies
  3. Given that the shared code feature is not being removed, there must still be a use case for shared code
  4. The use case for shared code must be uniquely related to RIA Services, otherwise the feature would become part of Visual Studio itself
  5. Given both 3 and 4, it follows that while the shared feature is important, we must be careful to limit our usage.
The Use Case for Shared Code

The use case is very simple, RIA Services uses a DAL or PM object and a RIA Services Entity on the client. Those are two completely different objects yet we have business logic and partial classes that we want to share between the two tiers.

One way to fix this problem might be to apply a shared interface to the client and server side objects. If that interface was defined in a Silverlight class library then both the server and client could share that same interface. Then all of the business logic could be defined within a Silverlight class library and shared between the client and the server. However, creating interfaces and class libraries doesn’t really fit in with the “RAD for Silverlight” image that RIA Services has.

The shared code feature handles this by copying un-compiled code between projects. This allows the same code to be compiled against two completely different objects (the server side DAL/PM object and the client side Entity) without having having to have any real interfaces. Also, to be frank, for most people putting interfaces on data objects is taking things a little too far.

The Case Against Shared Code

I am not going to get too deep into this one. Suffice to say, there is a reason that we use multiple projects that compile into dlls instead of just copying all of the code files for a solution into a single mega project and producing a single mega-dll. The shared code feature is part of RIA Services that Shawn Wildermuth would probably call a “Visual Studio Trick”. It is, much like the metadata file used to attach business rules, a bit of a kludge. I wouldn’t be surprised if the shared code feature doesn’t end up getting ripped out of Silverlight in a few years when some new feature of the CLR gives us a better way of solving the core use cases.More importantly, since the shared code feature is purely a compile time piece of trickery I don’t expect Microsoft to be worrying to much about keeping backwards compatibility of shared files too high on their must do list.

Great, so what is the recommendation?

To put it quite simply, for any code that needs to interact directly with both the Entity and the DLR/PM objects you should be using the Shared file feature. Any shared code should be kept as shallow as possible so keep as much of your code as possible in a Silverlight class library that is shared by both the server and client sides of your project.

Nov
18
2009

Undocumented DomainService Wizard change in WCF RIA Services

UPDATE: Turns out this is a bug, check this newer post.

As everybody is busy upgrading their .NET RIA Services application to a WCF RIA Services application, there is one change that wasn't documented as it isn't a breaking change but it is something you probably want to look at. The DomainService wizard generated Update methods slightly differently then it used to.

The previous version would have generated something like this:

public void UpdateMyEntity(MyEntity currentMyEntity)
{
    this.ObjectContext.AttachAsModified(currentMyEntity, this.ChangeSet.GetOriginal(currentMyEntity));
}

The new version will look like this:

public void UpdateMyEntity(MyEntity currentMyEntity)
{
    if ((currentMyEntity.EntityState == EntityState.Detached))
    {
        this.ObjectContext.AttachAsModified(currentMyEntity, this.ChangeSet.GetOriginal(currentMyEntity));
    }
} 

If you don't want to regenerate all of your DomainServices I recommend going through and making this change yourself. It is a pretty easy change and makes sure that your code matches everybody elses.

UPDATE: The Breaking Changes document is being updated to have this information.

Nov
18
2009

A guide to new features of WCF RIA Services

This is an exciting day, everyone can now get their hands on the brand new WCF RIA Services.  Here is a quick guide to some of the new features in WCF RIA Services as well as my personal guidance on how you can use the new features.

The new name

OK, WCF RIA Services has now replaced .NET RIA Services. I know I have talked about the ADO.NET Data Services integration but it turns out that RIA Services has gone beyond that (it has gone plaid!) and it now fully a WCF service. By default, your DomainService is now exposed as a standard WCF service using binary encoding. Sweeeeet!

Stay tuned to Saurabh Pant's blog for more information on how WCF is used by WCF RIA Services.

New rules for Error Handling

This is probably the most important change to understand while converting to the new WCF RIA Services. If errors come back from a SubmitOperation, InvokeOperation, or LoadOperation and is not handled by us then an exception will be thrown. This stops the problem where people new to RIA Services try to Submit or Load and never get an error, they will now get an exception. This can be a breaking change if you have errors coming back from the server that you were not previously handling.

Compositional Hierarchy

This is a big change for people who need real parent/child hierarchies in their code. For example, with a compositional hierarchy the parent’s HasChanges will be true if the child has been changed. However, I think a question that needs to be answered is what the default setup should be. My guidance here is that if you need composition, use composition. If you don’t need composition, or if you don’t know if you need composition, then don’t use composition. The default no-composition model is more flexible and has the potential of having better performance.

Inheritance Support (VS2010 Only)

This has been one of my biggest feature requests. I am extremely happy to say that not only does WCF RIA Services support inheritance, but the team has gone way above and beyond the level of support that I would have been happy with. They really did an incredible job and it is a real testament that Microsoft is listening to us.

Presentation Model

This is huge addition to WCF RIA Services and I don’t think the potential for this feature is really fully understood yet. I think there is going to be a tendency by some people to think that “Best Practices” would be to always use PM for all entities. I don’t think this is the case, it is easy to replace a regular entity with a PM entity without having to change the client so I think the better model is to mix PMs in with regular entities as you need them.

Domain Data Source Changes

I am not an expert in the use of the DDS. Personally, I don’t use it but I know that a lot of people do. The new version of the DDS has the bugs worked out and some simplifications made. Stay tuned to Jeff Handley’s blogfor all of the details.

Nov
18
2009

Updated ApplyState/ExtractState Library

Export more blog entries this week. I will be putting up my guide to the major new features after todays keynote.

In the meantime, here is an updated ApplyState/ExtractState refactored to use the EntitySet instead of the EntityList. I will put up a VS2010 version as well tonight.

RIAServicesContrib2008.zip (235.60 kb)

Oct
19
2009

State of the Blog and Boilerplate

I have gotten several questions about what is going on with this blog. The answer is that I am currently waiting for the next CTP to be released just like everyone else.  Once the next CTP is released come back and I will have a ton of new blog entries for you.

On the same note, I am not going to be participating in any speculation of what RIA Services will or will not support as of 10/11 at 11:30 AM. So that people don't think I am ignoring them I am going to reply with a simple link to this blog post if they ask me a direct question. In the meantime, I strongly suggest getting on Twitter and following the RIA Services team. They have been dropping lots of hints.

See you all back here in November. This is going to be fun.

Sep
8
2009

Interlude 2 - Diagram of MVVM and RIA Services

I promise that the rest of DomainClient will be posted tonight, but John Papa just posted up a very easy to read overview of MVVM. I couldn’t help doodling on his graphic to indicate one way you can map RIA Services to MVVM. As always, I will be hitting these concepts in more detail later.

RIAInMVVM

Note: My crudely drawn lines are trying to show that the DomainContext is taking the place of the two original links.

Sep
6
2009

Interlude – Entities do not have children

Since this is the first interlude, let me explain what an interlude is. I have the main series of articles for this blog planned out, but every so often I will feel the need to jump ahead and give a small sample of what I will be posting about in the future. This can be triggered by a tweet, a post in the message boards, or a passing thoughts catches my fancy.

This particular interlude is about terminology. In RIA Services, every entity should be considered a top level entity. There is no such thing as a parent child relationship in RIA Services; all entities are equal to each other. The hows and whys of this I will cover in the EntityContainer/EntityList series. The point is, the correct terminology should be Entity and Associated Entities, not Parent and Children.

Why is this important?

When we talk about a parent/child releationship there are certain preconceptions we bring to the table. For example, we would expect that the child cannot exist without the parent. We would call such an object an “orphan”. In RIA Services, as there are no children, there are no orphans. If you delete the “parent” the “children” are still tracked in their respective EntityList, all that happened is that the key value that uses to be shared with the deleted entity was cleared severing the association. Granted, you may or may not fail a foreign key check when you get back to the database but that is a matter of correct programming.

This goes back to swo’s question back on the EntityCollection where he asked why the Add and Remove methods were designed in the way that they were. The answer is here in the question of naming. If you use the words parent and child then removing the child from the parent would seem to imply that the child should be deleted. However, if you use the words Entity and Associated Entity that removing the Associated Entity from the Entity would indicate that you are simply severing the association. As are most things are in programming, it is all about finding the proper names for things so that we can correctly understand concepts.

Ok, one thing on why RIA Services is designed this way

RIA Services is actually designed to work a lot like a database does. If you created a SQL Database where all of the foreign keys were nullable and you had cascading turned on you would have something that would act a lot like RIA Services does. That database design would have the virtue of being able to model and other database design that you can come up with in SQL Server. Just something to think about.

(Do not actually go and design a database that way, what works really well for a data model works horribly for an actual database.)

Sep
3
2009

Meet the DomainClient

For those following along, I will be covering the Entity, EntityList, EntityContainer, DomainContext, and DomainService in the future and in that order, but for today I am jumping to the DomainClient. Roughly speaking, I am introducing each object in the reverse order of what you may expect. The point I am trying to make here is that RIA Services is more than just a bunch of meaningless plumbing designed to pump data from between the DomainService and the DomainDataSource. There is great power, great flexibility, and quite a bit of elegance to be found within RIA Services. Nowhere is this more apparent than with the DomainClient.

Everything you thought you knew was wrong

One of the early lessons that newcomers to RIA Services learns is that the DomainDataSource doesn’t actually do all the things that they think it does. The DomainDataSource doesn’t actually load data, the DomainDataSource doesn’t actually submit changes, and the DomainDataSource doesn’t actually store the entities. The DomainDataSource is a proxy that passes all of those commands to the DomainContext. Well, if you are reading this blog you are now a more advanced student of RIA Services so here is your next lesson: The DomainContext doesn’t do all the things you think it does. It doesn’t actually load data from the server and it doesn’t actually submit changes to the server; those jobs are actually done by the DomainClient. (It also isn’t really where the entities are stored, come back for the EntityContainer post for more info.)

Power of Simplicity, Flexibility of Abstraction

The DomainClient does three things: Query, Submit, and Invoke. Each of the three has a public Begin, Cancel,  and End function and each of those has a protected abstract version that has a name ending with Core. For example, there is both a public BeginQuery and a protected abstract BeginQueryCore. The DomainClient class itself is abstract and cannot be used directly; you must use one of the two provided implementations or create your own implementation

Each public method of the DomainClient does an argument validity check, wraps the callback inside its own callback, in the case of a BeginSubmit converts the ChangeSet into a list of EntityOperation objects, and finally passes it all to the protected Core method. That is it, that is all that the DomainClient does. Everything else is up to the particular implementation of DomainClient.

Notice I haven’t said anything about the DomainService; that is because the DomainClient and DomainContext are actually completely abstracted from the DomainService and whatever type of communication is going to be used to talk to that DomainService. In fact, your specific implementation of DomainClient may not even be talking to a DomainService at all. This is quite ironic considering that the DomainContext is usually generated by analyzing a compiled DomainService. Currently, the generated DomainContext that must of us deal with is hard coded to use the HttpDomainClient. The HttpDomainClient is a a one trick pony that only knows how to communicate with the DataServiceFactory (aka DataService.axd) but that will change when what is currently named the AtomDomainClient becomes the default implementation in the PDC release of RIA Services.

Wilco Bauwer has a very cool demo showing how the AtomDomainClient can connect directly to an Azure service.  Without a DomainService the code generator doesn’t work so Wilco uses a few T4 templates to generate the Entities and DomainContext. Future versions of RIA Services, meaning after the initial release next year, are going to use T4 templates for all code generation. This will make it even easier going forward to use the RIA Services client with back ends other than the DomainService.

Wrap-Up

There are going to be several more posts (more code, less text) on the DomainClient before I move on in in the future, but I want to wrap up this post before all this text puts everyone to sleep. Some important thoughts I would like you to take from this article are:

  • The DomainClient is the client side object in RIA Services that actually performs does the Load, Submit, and Invoke actions that we ask the DomainContext to do.
  • The DomainClient is an abstract class that has no dependencies on how communications will be performed or what is being communicated with.
  • The DomainClient has no methods marked internal, this makes it really easy for us to implement.
  • The DomainClient is so simple that creating your own implementation is not difficult. It would be really easy to mock the DomainClient for unit tests.
Detour

I have come to the realization that I need to move on to the Entity and other, more interesting objects. The main problem is that I don’t want to cover the HttpDomainClient and the AtomDomainClient since both of them are temporary code but talking about the code in abstract is just…boring to write about. So, I am moving on. If anyone has any specific questions about the DomainClient and how it works let me know and I will get them answered.

Sep
2
2009

The Problem with the DomainDataSource

WARNING: This post is not meant to be documentation on the DomainDataSource. Just a stream of consciousness mini-rant on DomainDataSource posted here because the 140 characters that Twitter limits me to was too few.

Jeff Handley has a poll going on the DomainDataSource. Please check it out and give an answer.

Since the question is on the table, I decided to put together my own thoughts on the subject. I have not been shy to state that I simply do not use the DomainDataSource. Personally, I find it clunky and not nearly as refined as the rest of RIA Services. It also does not work well with my ViewModel. I think what Jeff is trying to figure out though is why that is. I can say it is clunky, we can all say it doesn’t feel right, but can we put our finger on what the problem is?

I think the fundamental problem with the DomainDataSource is that it is not extensible at all. It is a completely sealed black box and there is very little way for us to extend it. This isn’t nearly as refined and elegant as the rest of RIA Services, such as the DomainContext which uses an EntityContainer to store all of the EntityLists and the DomainClient to talk to the server. If we want we want RIA Services to talk to the server using a port with everything under ROT13 encryption we can do that, we just have to create our own DomainClient that does that and tell the DomainContext to use it. We can’t do anything like that with the DomainDataSource. It just sits there in the XAML talking directly to our DomainContext and cutting our code completely out of the loop.

What makes the DDS really annoying though is that the really useful paging code is locked inside it and its internal lackey the EntityCollectionView. I still live in hope that this will be fixed and that we will get a back end object that can generate the paging queries.

So, what is the DomainDataSource doing exactly (this is not meant to be a full list)?

  1. Declarative access to DomainContext status (IsBusy, IsLoading, IsSubmittingChanges, etc.)
  2. Paging display attributes (PageSize)
  3. AutoLoad (which is data access logic)
  4. Paging load attributes (LoadSize) (data access logic)
  5. Setting the query name
  6. Setting the query attributes
  7. Submit changes

I would have to say that from a MVVM perspective, 3, 4, 5, 6, and 7 are all problematic to me. The UI shouldn’t be worrying about the name of the query, how many records are being loaded outside of the PageSize, and I don’t think the UI should know what of its bound values are being used to filter queries. Letting the UI call directly to the DomainContext to SubmitChanges is also a big problem for me.  I do like the idea of a UI object that can allow binding of DomainContext statuses such as IsLoading and setting page size is a definite UI job.

Sep
1
2009

Meet the EntityRef and the AssociationAttribute

Today I am going to cover the EntityRef and the AssociationAttribute, but first some cleanup on the EntityCollection. In the Advanced EntityCollection post I had part of the constructor explained incorrectly, it has been corrected as well as some cleanup on the code to make it more understandable.

The EntityRef

The EntityRef is the one-to-one relationship version of the EntityCollection, which means it is probably even less well known. Like the EntityCollection, the EntityRef has two different jobs depending on if the Entity is attached to an EntityList or not. However, the EntityRef is not directly exposed by the Entity, instead it is used to back a property with the type of the associated Entity. Here is the Book Entity’s Library property, the other side of the association covered in the EntityCollection posts.

[Association("Library_Book", "LibraryId", "LibraryId", IsForeignKey=true)] 
[XmlIgnore()] 
public Library Library 
{ 
    get 
    { 
        if ((this._library == null)) 
        { 
            this._library = new EntityRef<Library>(this, "Library", this.FilterLibrary); 
        } 
        return this._library.Entity; 
    } 
    set 
    { 
        Library previous = this.Library; 
        if ((previous != value)) 
        { 
            this.ValidateProperty("Library", value); 
            if ((previous != null)) 
            { 
                this._library.Entity = null; 
                previous.Book.Remove(this); 
            } 
            this._library.Entity = value; 
            if ((value != null)) 
            { 
                value.Book.Add(this); 
                this.LibraryId = value.LibraryId; 
            } 
            else 
            { 
                this.LibraryId = default(Nullable<Guid>); 
            } 
            this.RaisePropertyChanged("Library"); 
        } 
    } 
}

private bool FilterLibrary(Library entity) 
{ 
    return (entity.LibraryId == this.LibraryId); 
}

One important thing to note if you want to create your own properties backed by an EntityRef which are not read only, the this.ValidateProperty(“Library”, value) line is actually causing the getter to be called making sure that the _library field is getting populated. If you remove that line without replacing it you may get null reference exceptions.

 

Meet the AssociationAttribute

public AssociationAttribute( 
    string name, 
    string thisKey, 
    string otherKey 
) 

Parameters
name: Name of the association
thisKey Comma separated list of the property names of the key values on this side of the association
otherKey comma separated list of the property names of the key values on the other side of the association

So, what does that pesky AssociationAttribute actually do? Both the EntityCollection and EntityRef require it but it is not obvious why that is. Also, what is the benefit of using EntityCollection and EntityRef over using a real CollectionView and a regular property?

Both the EntityCollection and EntityRef monitor an EntityList for any changes to make sure that the associations are always kept up to date. However, if the various Filter method were called every time anything changed on the entities the performance issues would quickly get out of control. For example, lets say we have 10 libraries and we are entering 20 books with each book have 15 fields that we are changing. By the time we were done we would have called the FilterBook method 3,000 times (10 libraries * 20 books * 15 fields. This is not very efficient.

To solve this problem, the EntityCollection and EntityRef only listen for changes made to those fields listed in the AssociationAttribute. This reduces us to 200 calls to FilterBook (10 libraries * 20 books * 1 field). By using the EntityRef and EntityCollection in our own code we are able to leverage this huge performance advantage ourselves. RIA Services probably has other uses for AssociationAttribute, but this is a really important one.

Month List