Wednesday, July 17, 2013

About me and how I see the role of an architect

 

There is a point where you start spending more time thinking on how you will build something than actually building it. You start thinking on what can you take out of your software instead of what can you put in. You realize that the only way to succeed today is to aim for the perfect simplicity. Although simplicity may sound easy, elegant simplicity is the most challenging goal in the software industry. If you are there you’ve passed the point of no return where you become an architect.

Although I have been on the role for a couple of years, and I had the basic skills associated with architecture only recently I have gone across that point and things look a lot more clear today. It’s a jungle out there.

Some believe that building software has become easier because technology has evolved, they could not be farther from the truth, building software has never been so hard, the timelines have never been so short and the basic requirements have never been so complex.

Shared identity, devices as in BYOD, form factors, usability, multi-tenancy, scalability, resilience are just a few of the attributes that users have been thought to take as normal, granted, part of any software that goes in the browser. Traditional software, at least the trend, had one, two, certainly not all. So how do you achieve it and still meet that weekly cycle?

Well the good news is that it doesn’t take a lot of code, only the right code and building on top of the right tools; it’s about how deeply you understand the problems, the protocols and the frameworks and how you put that knowledge in place to make it as simple as humanly possible and still make it great.

One example, I recently had to build an OAuth 2.0 server followed by an ASP.NET WebApi AuthorizationFilter to check the authorization token issued by that server. One print page of lines of code, weeks of reading to learn the protocol, to understand how claims can be used to simplicity the identity problems, how the token is digitally signed and how do you validate that signature, what can you do with OAuth 2.0, what does it enable, how can you extend it to go beyond what common OAuth providers do, and so one. It’s quite simple now because I have gone to the process of making it simple, a very hard process. If had just designed a custom solution, the best designed custom solution, it would have taken longer and it would be much less useful. An architect must embrace the pain of being ignorant about most of the things, and deal with it.

To finalize another example, also recently I have been working on applying different system metaphors (the list of parts you need to code to build a feature) to web development using .NET, trying to find one that isn’t just an hack that no one can evolve in the long run, but also that keeps the rate one screen one day (my goal for now). I really know how to build it with all the layers, make it SOLID, make it unit testable, as well designed as you can dream of but it breaks the one day goal, and no design is good if it doesn’t fit on the budget. I have finally made it, and guess what, it scales really well, I just have to tell my coworker what is the best example to follow and he can just add a new view in html with the bindings in place, a new viewmodel with those Knockout observables in place, a resource model, an api controller, a domain model, the repository, and a new property on the DbContext and it just works. If more coworkers are available they can repeat the steps and we can move really fast, it will have a balanced architecture, not to complex, not just an hack and you can make it move a little bit faster by adding more hands to the job. If I had a part to the metaphor I lose the productivity and if I take one out than it gets harder to test and to meet all the non-functional requirements, it’s a balance. In the end this is more about architecture then just the design or the protocols.

Tuesday, August 23, 2011

Multi-Targeting made easy

This is just a very short post to point to a CTP of a toolset that will be very important for those that like me have to write code that runs in multiple CLR hosts. The Portable Library Tools adds a new project template to visual studio that helps you through the process of writing code that runs on all selected platforms. Once the project goes RTM there is the promise to support executing the produced assembly in all the hosts. To do this today I have to maintain separate project files even if the code is exactly the same. You can read more about it here.

Sunday, July 17, 2011

Model Based Programming

I am glad to announce the I decided to start blogging about what I have been working on on the past years - Model Based Software Development. If you want to learn about the new exciting age of generation full products based only on models stay tuned at Model Based Programming blog.

Thursday, May 19, 2011

Some LINQ to Object Internals – How does the C# compiler mix Expression Trees with the LINQ operators extension methods?

I’m build a lot of code on top of LINQ that uses Queryables and Expression Trees and I have to admit it gave me a hard time. This post is about sharing some of the stuff I have learned by looking at the LINQ source code and I hope that some of you will also share some of your understanding on this topic here.

For the sake of simplicity lets stick with LINQ to Objects and group all extension methods and LINQ providers that deal with IEnumerable as Enumerables and the ones that deal with IQueryable as Queryables. If you look at their source code you will see that the actual code that runs behind the scenes is quite simple and most of the magic is actually triggered by the signatures.

Queryables receive Expression<Delegate> and Enumerables delegates. By reading through the documentation the explanation for this is quite simple. An Enumerable is designed to work locally while a Queryable is designed in a way that you can serialize the query and execute it somewhere else.

The first example here will start with a very simple query:

var root = new int[] { }.AsQueryable();
var query = from r in root
    where r > 10
    orderby r descending
    select r;

In the brackgroung the compiler is emitting something equivalent to the following snippet (I have changed the code a bit to make it easier to read):

var parameter = Expression.Parameter(typeof(int), "item");
var q = new int[0].AsQueryable<int>().Where<int>(
     Expression.Lambda<Func<int, bool>>(
         Expression.GreaterThan(parameter, Expression.Constant(10, typeof(int)))
         , new ParameterExpression[] { parameter })
 )
 .OrderByDescending<int, int>(
     Expression.Lambda<Func<int, int>>(
         parameter = Expression.Parameter(typeof(int), "r"), 
 new ParameterExpression[] { parameter }));

When the AsQueryable extension method is called it receives an array of items with 0 elements. The where clause in C# will translate into a call to the Where extension method (in this case the one that applies to Queryable). Because that extension method receives Expression<Delegate> and not the Delegate the compiler translates the “r > 10” into the equivalent expression tree. That expression tree can then be serialized and sent to be executed elsewhere or it can be translated to code by calling Lamdba.Compile.

I was trying to understand why taking an Expression from an IQueryable and calling provider CreateQuery on another queryable over the same data type did not work. By looking to the code generated by the compiler the awnser seams obvious. Although a part of the Expression is constructed by using Expression Trees the most important part (the Where) is still a call to the generic Where on top of an array that contains zero elements. The only way to change this is to create a visitor that emits an equivalent call chain on another data source. If I was using a LINQ to Blah Blah Blah provider that serialized the query it might work because it would depend on the interpretation that the provider gave to the root of the query, that is int[0], maybe a customers[] would be interpreted as the table of customers :).

Have fun,

Thursday, May 5, 2011

Beatifull Code Part 2 – Combining RIA Services with Reactive Extensions to build a push based search

A common scenario in most applications is looking up values based on the user input in a auto-complete fashion. If you want to do this with a RIA service you have to (let’s ignore MVVM for the sake of simplicity) subscribe to the TextChanged event, grab the Text value, get the query from the DomainContext, apply a Where clause using the given text, let’s say StartsWith, create a LoadOperation, wait for the completed event and on the completed event clear the contents of the previous search and write the new search result. Its really messy!

It is complex because you are converting a data source that is push based (the textbox pushes text to your application) in to a pull based logic and you have to handle all those async problems yourself. But imagine that your text box is pushing a projection of the data filtered by the typed value into the search result control. You can think of a “eih C# just put the xxxs that StartWith ‘text’ into the data grid!” How do we write this?

I use a very dummy user interface:

<sdk:DataGrid AutoGenerateColumns="True" Height="296" HorizontalAlignment="Left" Margin="26,178,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="598" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="26,139,0,0" Name="textBox1" VerticalAlignment="Top" Width="278" />
<sdk:Label Height="28" HorizontalAlignment="Left" Margin="26,105,0,0" Name="label1" VerticalAlignment="Top" Width="120" Content="Name" />

And this is the code that pushes the TextChanged event into the service and back to the datagrid:

  var observableText = Observable.FromEvent<TextChangedEventArgs>(this.textBox1, "TextChanged");

  var text = (from change in observableText
             select ((TextBox)change.Sender).Text)
             .DistinctUntilChanged()
             .Throttle(TimeSpan.FromSeconds(1));

  var queryStream = from input in text
                    select context.GetCustomersQuery().Match(i => i.FirstName.StartsWith(input));

  var loadStream = from query in queryStream
                   select CreateLoad(query);

  var resultEventStream = from load in loadStream
                          select
                               Observable.FromEvent<EventArgs>(load, "Completed");

  var resultStream = from ev in resultEventStream
                     select ev
                         .ObserveOnDispatcher()
                         .Subscribe(current =>
                         {
                             var completedOperation = (LoadOperation<IndividualCustomer>)current.Sender;
                             this.customers.Clear();
                             foreach (var c in completedOperation.Entities)
                             {
                                 this.customers.Add(c);
                             }
                         });


  this.topmost = resultStream.Subscribe(); 

  this.dataGrid1.ItemsSource = this.customers;

The CreateLoad is just a helper function to allow customizing the query:

private LoadOperation<IndividualCustomer> CreateLoad(EntityQuery<IndividualCustomer> q)
{
    return this.context.Load(q);
}

The algorithm is quite simple, I take the event from the TextBox and convert it to an Observable of Text inputs. Then I take that Observable and create an Observable of Queries, them into an Observable of queries loading and  finally to an Observable of the results of loading those queries. I subscribe to this final one and conceptually I have the text that the user typed pushing loaded data back to me :).

Have fun,

Pedro

Wednesday, May 4, 2011

Beatifull Code Part 1 – Implement the repository pattern asynchronously with RIA Services

 

I’ve bought the book “Beautiful Code” published by O’Reilly and edited by Andy Oram and Greg Wilson and it has inspired my work in the last days. It doesn’t actually teach writing beautiful code or it would just be another GoF or Fowler book, it teaches you how the best think and it puts you thinking like the best. Hopefully thinking like the best will make you one of the best :).

Ten years ago when I left school if one would ask me where the best programmers spend their time I guess that I would answer writting very complex very fast. Yet today I spent hours thinking on an interface and how would people use it. I did that because I realized (through the book) that the best delete code instead of writing it. Code is bad! Code is ugly! Code is money spent! The less the better! What I really want is to reuse the same code over and over to solve equivalent problems by hiding the details.

What I was trying to do is to bridge the gap between the way you change collections of objects and the way you use RIA services to change tables. I looked at IEnumerable<T>, at ICollection<T>, at IList<T>, at EntitySet<T>, all the change tracking interfaces and the paged collection interfaces and at the end the only phrase on my brain was what a mess!

It is amazing how a mess can be created from a very simple mistake, the idea that operations that act on sets are synchronous. Have you ever asked yourself why would Add return void? Why would it return “immediately”? Imagine you are adding one element to a collection that as 10^9 elements and must always be sorted, it can take quite some time until add returns control to the caller. Until that happens the caller is blocked, wasting resources doing nothing. But if you say Add cannot be synchronous what would it look like? Well if I was on the Desktop market then I would say Task<T> but since I am on the Silverlight I must come up with a different name to the same idea because I don’t want to clash with that name in the future. So I came up with IResult:

 

/// <summary>
/// Represents the result of a method that cannot be completed synchronously.
/// </summary>
/// <remarks>
/// For void methods we consider that if no Exception was thrown the method executed successfully.
/// </remarks>
public interface IResult
{
    /// <summary>
    /// Occurs when all the activities initiated by the method that return this instance are completed.
    /// </summary>
    event EventHandler<EventArgs> Completed;

    /// <summary>
    /// Gets the error that ocurred during the execution of the activities triggered by the method that 
    /// returned this instance or null if no error occurred.
    /// </summary>
    Exception Error
    {
        get;
    }

    /// <summary>
    /// Gets a value indicating whether the method that returned this instance terminated in error.
    /// </summary>
    bool HasError
    {
        get;
    }

    /// <summary>
    /// Gets a value indicating whether the method that returned this instance finished its execution.
    /// </summary>
    bool IsComplete
    {
        get;
    }

    /// <summary>
    /// Gets a tag that identifies the method that returned this instance.
    /// </summary>
    string Action
    {
        get;
    }

    /// <summary>
    /// Gets a value representing the input of the method that returned this instance.
    /// </summary>
    IEnumerable Request
    {
        get;
    }

    /// <summary>
    /// Blocks the current thread until the underlaying activities complete.
    /// </summary>
    void Wait();

    /// <summary>
    /// Blocks the current thread until the underlaying activities complete but setting a timeout.
    /// </summary>
    /// <param name="miliseconds">The amount of time in miliseconds that the current thread will wait for a result.</param>
    void Wait(int miliseconds);
}

IResult is basically a pull based mechanism for someone to pull asynchronous method call state. We will get to a push base mechanism on a future article. IResult is inspired in OperationBase from RIA but it attempts to hide the semantics linked with web requests.

Ok, now that we have IResult how would a Repository contract look like?

/// <summary>
/// A set of elements that cannot be changed synchronously and that interfaces with a persistent storage
/// using a collection like interface.
/// </summary>
/// <typeparam name="T">The Type of elements in the repository.</typeparam>
public interface IRepository<in T>
{
    /// <summary>
    /// Gets a value indicating whether the repository can be modified.
    /// </summary>
    bool IsReadOnly
    {
        get;
    }

    /// <summary>
    /// Gets a value indicating whether the repository was modified.
    /// </summary>
    bool IsChanged
    {
        get;
    }

    /// <summary>
    /// Gets a value indicating whether the repository allows adding elements.
    /// </summary>
    bool CanAdd
    {
        get;
    }

    /// <summary>
    /// Gets a value indicating whether the repository allows removing elements.
    /// </summary>
    bool CanRemove
    {
        get;
    }

    /// <summary>
    /// Gets the number of elements in the set asynchronously.
    /// </summary>
    IResult<int> Count
    {
        get;
    }

    /// <summary>
    /// Adds the given element to the set asynchronously.
    /// </summary>
    /// <param name="item">The element to add to the set.</param>
    /// <returns></returns>
    IResult Add(T item);

    /// <summary>
    /// Determines asynchronously whether the given element is in the set or not.
    /// </summary>
    /// <param name="item">The element to check whether it is on the set or not.</param>
    /// <returns>A representation of the current state of the activities initiated by the method call.</returns>
    IResult<bool> Contains(T item);

    /// <summary>
    /// Removes asynchronously the element from the set.
    /// </summary>
    /// <param name="item">The element to add to the set.</param>
    /// <returns>A representation of the current state of the activities initiated by the method call.</returns>
    IResult Remove(T item);

    /// <summary>
    /// Accepts the changes made to the set making them permanent.
    /// </summary>
    /// <returns>A representation of the current state of the activities initiated by the method call.</returns>
    IResult AcceptChanges();

    /// <summary>
    /// Discards the changes made to the set reverting to the values that where previously on the persistent media.
    /// </summary>
    /// <returns>A representation of the current state of the activities initiated by the method call.</returns>
    IResult RejectChanges();
}

I would recommend you to spend a couple of minutes thinking on Count. In a standard collection Count would return the number of elements that are in the data structure holding the data, but when we are counting records on a table through a service call that can take quite some time. It makes sense to return an IResult. When the Count operation is completed then the Completed event will be raised and the program can use that value. Until that happens it can do other stuff. In the next article we will see how we can tweak this interface to take advantage of pull base mechanisms and reactive extensions. I’m building a framework based on these ideas and I will release the source code if someone is interested in it.

Thursday, January 13, 2011

MEF TIP – How to initialize CompositionHost with all the assemblies contained in the application main XAP?

It’s a very a simple operation although not obvious (at least to me):

- Create an instance of the DeploymentCatalog class using the empty constructor. This gets the list of parts included in the manifest of the main XAP.

- Call CompositionHost.Initialize(deploymentCatalog, …)

If you are loading XAPs outside of MEF you must keep track of the assemblies you load and save that information, then create one AssemblyCatalog for each of then and merge them in a AggregateCatalog.

Have fun,

Pedro

Tuesday, June 1, 2010

Lambdas as EventHandlers

At the moment I’m writing a guide to do design review for .NET 4.0 applications writen in C#. One of the small questions I had was what to do with event handlers that use lambda expressions and closures.

The problem of closures is that by using members that are on the scope of the object defining the lambda they create references to those members and can cause unexpected leaks.

One of the things I wanted to try is to see if using the same lambda (Test1) to unsubscribe would remove it from the invocation list of the event. The answer is NO it does not. I have seen code that uses this but as this test shows it does nothing. The only way to remove it from the invocation list is to hold the reference to the lamdba in a variable and use that to subscribe and unsubscribe (Test2). The code loses the beauty of using the lamdba to shorten it and I am considering to allow only the use of lamdbas that do not use members of the object.

 

class Program
{
   static void Main(string[] args)
   {
       Console.WriteLine("Test 1 : Do not hold the lambda in a variable:");
       Console.WriteLine();
       Test1();

       Console.WriteLine("Test 2 : Hold the lambda in a variable.");
       Console.WriteLine();
       Test2();
   }

   private static void Test1()
   {
       EventPublisher ep = new EventPublisher();
       ep.TestEvent += (o, e) => { };
       Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers);
       ep.TestEvent -= (o, e) => { };
       Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers);
       Console.ReadLine();
   }

   private static void Test2()
   {
       EventPublisher ep = new EventPublisher();

       EventHandler<EventArgs> t = (o, e) => { };

       ep.TestEvent += t;
       Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers);
       ep.TestEvent -= t;
       Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers);
       Console.ReadLine();
   }
}

class EventPublisher
{
   public event EventHandler<EventArgs> TestEvent;

   public int NumberOfSubscribers
   {
       get
       {
           if (this.TestEvent != null)
           {
               return this.TestEvent.GetInvocationList().Length;
           }

           return 0;
       }
   }

   public void Publish()
   {
       this.OnTestEvent(new EventArgs());
   }

   protected virtual void OnTestEvent(EventArgs e)
   {
       if (this.TestEvent != null)
       {
           this.TestEvent(this, e);
       }
   }
}

The output of this small program is the following:

Test 1 : Do not hold the lambda in a variable:

Number of subscribers = 1
Number of subscribers = 1

Test 2 : Hold the lambda in a variable.

Number of subscribers = 1
Number of subscribers = 0

As you can see beware of lambdas in Event Handlers.

Have fun,

Thursday, April 22, 2010

Techdays 2010 – Just bought some new toys

Techdays is almost over, as always there are way too many products on the table and it is time to choose what to buy and take home. This year I would like to highlight a couple of stars. One was here before but has grown from a promising idea to a great tool, PEX:

Pex and Mole

The other nominee I would describe it with the idea of chaos theory where the butterfly’s wings might be the igniter for a tornado! The tools is Rx Extensions. The idea is basically if you have iterators that you can use to pull data out of collections why can’t you have iterators that throw data at you! Instead of having to continuously checking for data availability you get notified. What this bring is a shift from programs that way of users to interact with them to programs that react to changes and do things. Programs will always be interactive in some way but this can be a starting point to create new compelling experiences.

Rx Extensions

And the next one is The toy for architects. If you want to amaze with the latest craziest stunt then you should go event driven and start processing tens of millions of events using StreamInsight. Get your backbones fibered and your cores lubed :)

Stream Insight 

And last but not least a toy to use when you are tired after eight hours of coding really scientific applications that do something as challenging as inserting data into a database and  you want to do stupid coding such as autonomous robots this is what you need. .NET Micro Framework.

.NET Micro Framework

Just heard about this really nice (cheap) platform: TinyClr

Have fun,

Wednesday, April 21, 2010

Monday, April 19, 2010

I will be on Techdays 2010 presenting the product I’ve been working on

My session is about software industrialization. I’ve working on a Domain Driven Development framework on Primavera and this is the first public presentation we are doing about it. The last months have been hard but are starting to payoff. You can find better details here:

The age of software industrialization – Combining Domain Driven Design with Code Generation

The description is only available in Portuguese but most of the contents are in United States English.

Our platform will support the product lines of the next generation of Primavera ERPs. We have achieved a high level of automation by using Microsoft DSL tools and T4 templates to generate a very large portion of the software. Our objective is to reach 100% of generated code! This is very very hard but we are highly motivated to pursuit it.

Tuesday, April 13, 2010

Silverlight Serialization – Avoiding having public setters in Properties

In Silverlight you cannot use Reflection to call a non-public setter on a class unless you are in the scope of the class. This has a side-effect in serialization because it requires having public setters for all properties that must be serialized. Well that is not really the case. You can make them internal and use the InternalsVisibleTo attribute to expose those internals to the Microsoft serialization assemblies like this:

   1: [assembly: InternalsVisibleTo("System.Runtime.Serialization, PublicKey="
   2:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
   3:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
   4:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
   5:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
   6:     + "37AB", AllInternalsVisible = true)]
   7:  
   8: [assembly: InternalsVisibleTo("System.ServiceModel.Web, PublicKey="
   9:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
  10:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
  11:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
  12:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
  13:     + "37AB", AllInternalsVisible = true)]
  14:  
  15: [assembly: InternalsVisibleTo("System.Runtime.Serialization.Json, PublicKey="
  16:     + "00240000048000009400000006020000002400005253413100040000010001008D56C76F9E86493"
  17:     + "83049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E"
  18:     + "9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4"
  19:     + "BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B"
  20:     + "37AB", AllInternalsVisible = true)]

Once this is done you can make your setters internal and prevent outside code from calling them.

Have fun,

Tuesday, February 9, 2010

WCF RIA Services – Short Notes – Refreshing data from the server

By default if an Entity arriving from the server has the same Identity has one already in the DomainContexts at the client it is discarded. This behavior can be changed by calling the Load method of the DomainContext giving a MergeOption. It can be:

  1. MergeOption.OverwriteCurrentValues – What is comming from the server overrides the changes on the client.
  2. MergeOption.KeepCurrentValues – What is on the client remains the same what comes from the server is discarded.
  3. MergeOption.KeepChanges – Changes that where made on the client are maintained and everything else is replaced from what is on the server.

Have fun,

WCF RIA Services – Short Notes – Transactions

You can easily integrate transactions in a DomainService by overloading the Submit method on the service and creating the transaction scope there:

   1: using (var tx = new TransactionScope( TransactionScopeOption.Required, 
   2:     new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted })) 
   3: { 
   4:     base.Submit(changeSet); 
   5:     tx.Complete(); 
   6: }

The Insert*, Update* and Delete* methods will be called one by one inside the given scope.

Have fun,

WCF RIA Services – Short Notes – Custom logic on solving concurrency errors

DomainServices have solving concurrency errors as a first class scenario. If you want to override the framework default logic you should.

Have an update operation for the entity.

Have a method that handles the concurrency and that:

  1. Begins with the word Resolve plus the name of the entity.
  2. Follows the signature template:
   1: public bool ResolveEntityA(EntityA current, EntityA original, EntityA store, bool deleteOperation)

Have fun,

WCF RIA Services – Short Notes – Server Side sequence of operations

When the domain service is processing a changeset the sequence of operation is:

Submit – This is the entry point for a submit operation.
AuthorizeChangeSet – In this point the entries in the changeset should be checked against the authorization rules.
ValidateChangeSet – The entries in the changeset should be checked against business rules.
ExecuteChangeSet – The business methods in the domain service are called from this method one by one.
PersistChangeSet – The changeset is persisted.
ResolveChangeSet – If there are any concurrency conflicts they are resolved here.

Kind Regards,

Pedro

WCF RIA Services – Advanced Topics – Fully supporting inheritance

One of the limitations on WCF RIA Services is not support inheritance though making EF inheritance feature impossible to use with LinqToEntities. When you try to set a property of a base class you get this error:

Entity type 'Square' does not contain a public property named 'ShapeId'.

I found that this error is actually a problem with Silverlight reflection. Because of the new restrictions on reflection the change tracking code is unable to get the value of the property. But there is a workaround for it. Let’s illustrate the problem. I have this object model:

Overview

There are several things you have to do to make this model work. First you need to put the correct annotations on your model.

   1: public class RootEntity
   2: {
   3:     [Key]
   4:     public Guid Id
   5:     {
   6:         get;
   7:         set;
   8:     }
   9:  
  10:     public Guid ChildId
  11:     {
  12:         get;
  13:         set;
  14:     }
  15:  
  16:     public string Name
  17:     {
  18:         get;
  19:         set;
  20:     }
  21:  
  22:     [Composition]
  23:     [Association("RootEntity_ChildEntity", "ChildId", "Id")]
  24:     public ChildEntity Child
  25:     {
  26:         get;
  27:         set;
  28:     }       
  29: }
  30:  
  31: public class ChildEntity
  32: {
  33:     public ChildEntity()
  34:     {
  35:         this.SubChildren = new List<SubChildEntity>();
  36:     }
  37:  
  38:     [Key]
  39:     public Guid Id
  40:     {
  41:         get;
  42:         set;
  43:     }       
  44:  
  45:     [Composition]
  46:     [Association("ChildEntity_SubChildEntity", "Id", "ChildEntityId")]
  47:     public IList<SubChildEntity> SubChildren
  48:     {
  49:         get;
  50:         private set;
  51:     }
  52: }
  53:  
  54: public class SubChildEntity
  55: {
  56:     public SubChildEntity()
  57:     {            
  58:     }
  59:  
  60:     [Key]
  61:     public Guid Id
  62:     {
  63:         get;
  64:         set;
  65:     }
  66:  
  67:     public Guid ChildEntityId
  68:     {
  69:         get;
  70:         set;
  71:     }
  72:  
  73:     [Include]
  74:     [Association("SubChildEntity_Shape", "Id", "SubChildEntityId")]
  75:     public Shape Shape
  76:     {
  77:         get;
  78:         set;
  79:     }
  80: }
  81:  
  82: [KnownType(typeof(Square))]
  83: [KnownType(typeof(Circle))]
  84: public abstract class Shape
  85: {
  86:     [Key]
  87:     public Guid ShapeId
  88:     {
  89:         get;
  90:         set;
  91:     }
  92:  
  93:     public Guid SubChildEntityId
  94:     {
  95:         get;
  96:         set;
  97:     }
  98:  
  99:     public int CenterX
 100:     {
 101:         get;
 102:         set;
 103:     }
 104:  
 105:     public int CenterY
 106:     {
 107:         get;
 108:         set;
 109:     }
 110: }
 111:  
 112: public class Circle : Shape
 113: {
 114:     public int Radius
 115:     {
 116:         get;
 117:         set;
 118:     }
 119: }
 120:  
 121: public class Square : Shape
 122: {
 123:     public int RoudingRadius
 124:     {
 125:         get;
 126:         set;
 127:     }
 128:  
 129:     public bool RoundCorners
 130:     {
 131:         get;
 132:         set;
 133:     }
 134: }

You have to notice the Composition attribute and the KnownType attribute.

Second you have to put methods to the CUD the detail objects on the server. This will force the EntitySets on the DomainContext to allow all kinds of changes. Also notice the fixup I have to do on the Ids that are involved in the associations in the InsertRootEntityMethod.

   1: [EnableClientAccess]
   2: public class RootEntityService : DomainService
   3: {
   4:     private static List<RootEntity> dataSource = new List<RootEntity>();
   5:  
   6:     public IQueryable<RootEntity> GetRootEntities()
   7:     {
   8:         var q = from r in dataSource
   9:                 //from src in r.Child.SubChildren
  10:                 select r;
  11:  
  12:         return q.AsQueryable();
  13:     }
  14:  
  15:     public IQueryable<ChildEntity> GetChildEntities(Guid parentId)
  16:     {
  17:         var q = from r in dataSource
  18:                 where r.Id == parentId
  19:                 select r.Child;
  20:  
  21:         return q.AsQueryable();
  22:     }
  23:  
  24:     public IQueryable<SubChildEntity> GetSubChildren(Guid parentId)
  25:     {
  26:         var q = from r in dataSource
  27:                 from s in r.Child.SubChildren
  28:                 where r.Id == parentId
  29:                 select s;
  30:  
  31:         return q.AsQueryable();
  32:     }
  33:  
  34:     public IQueryable<Shape> GetShapes(Guid parentId)
  35:     {
  36:         var q = from r in dataSource
  37:                 from sc in r.Child.SubChildren                    
  38:                 where r.Id == parentId
  39:                 select sc.Shape;
  40:  
  41:         return q.AsQueryable();
  42:     }
  43:  
  44:     public void InsertRootEntity(RootEntity value)
  45:     {
  46:         if (dataSource.Find(entity => entity.Id == value.Id) != null)
  47:         {
  48:             throw new InvalidOperationException("Cannot add two entities with the same key");
  49:         }
  50:  
  51:         dataSource.Add(value);
  52:         value.ChildId = value.Child.Id;
  53:         foreach (var sub in value.Child.SubChildren)
  54:         {
  55:             sub.ChildEntityId = value.Child.Id;
  56:             sub.Shape.SubChildEntityId = sub.Id;
  57:         }            
  58:     }
  59:  
  60:     public void UpdateRootEntity(RootEntity value)
  61:     {
  62:         var desiredEntity = dataSource.Find(entity => entity.Id == value.Id);
  63:         if (desiredEntity == null)
  64:         {
  65:             throw new InvalidOperationException("The given entity is not part of the data source");
  66:         }
  67:  
  68:         dataSource.Remove(desiredEntity);
  69:         dataSource.Add(value);
  70:  
  71:         value.ChildId = value.Child.Id;
  72:     }
  73:  
  74:     public void DeleteEntity(RootEntity value)
  75:     {
  76:         var desiredEntity = dataSource.Find(entity => entity.Id == value.Id);
  77:         if (desiredEntity == null)
  78:         {
  79:             throw new InvalidOperationException("The given entity is not part of the data source");
  80:         }
  81:  
  82:         dataSource.Remove(desiredEntity);
  83:     }
  84:  
  85:     public void InsertChildEntity(ChildEntity value)
  86:     {
  87:     }
  88:  
  89:     public void UpdateChildEntity(ChildEntity value)
  90:     {
  91:     }
  92:  
  93:     public void DeleteChildEntity(ChildEntity value)
  94:     {
  95:     }
  96:  
  97:     public void InsertSubChildEntity(SubChildEntity value)
  98:     {
  99:     }
 100:  
 101:     public void DeleteSubChildEntity(SubChildEntity value)
 102:     {
 103:     }
 104:  
 105:     public void UpdateSubChildEntity(SubChildEntity value)
 106:     {
 107:     }
 108:  
 109:     public void InsertCircle(Circle circle)
 110:     {
 111:     }
 112:  
 113:     public void UpdateCircle(Circle circle)
 114:     {
 115:     }
 116:  
 117:     public void DeleteCircle(Circle circle)
 118:     {
 119:     }
 120:  
 121:     public void InsertShape(Shape Shape)
 122:     {
 123:     }
 124:  
 125:     public void UpdateShape(Shape Shape)
 126:     {
 127:     }
 128:  
 129:     public void DeleteShape(Shape Shape)
 130:     {
 131:     }
 132:  
 133:     public override System.Collections.IEnumerable Query(QueryDescription queryDescription, out IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> validationErrors, out int totalCount)
 134:     {
 135:         return base.Query(queryDescription, out validationErrors, out totalCount);
 136:     }
 137:  
 138:     public override bool Submit(ChangeSet changeSet)
 139:     {
 140:         return base.Submit(changeSet);
 141:     }
 142:  
 143:     public override void Initialize(DomainServiceContext context)
 144:     {
 145:         base.Initialize(context);
 146:     }
 147:  
 148:     public override object Invoke(DomainOperationEntry operation, object[] parameters, out IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> validationErrors)
 149:     {
 150:         return base.Invoke(operation, parameters, out validationErrors);
 151:     }
 152:     
 153:     protected override bool AuthorizeChangeSet(ChangeSet changeSet)
 154:     {
 155:         return base.AuthorizeChangeSet(changeSet);
 156:     }
 157:     
 158:     protected override bool ExecuteChangeSet(ChangeSet changeSet)
 159:     {
 160:         return base.ExecuteChangeSet(changeSet);
 161:     }
 162:  
 163:     protected override bool ValidateChangeSet(ChangeSet changeSet)
 164:     {
 165:         return base.ValidateChangeSet(changeSet);
 166:     }
 167:  
 168:     protected override bool PersistChangeSet(ChangeSet changeSet)
 169:     {
 170:         return base.PersistChangeSet(changeSet);
 171:     }
 172:  
 173:     protected override bool ResolveChangeSet(ChangeSet changeSet)
 174:     {
 175:         return base.ResolveChangeSet(changeSet);
 176:     }
 177:  
 178:     protected override bool Resolve(object current, object original, object store, ResolveOption resolveOption)
 179:     {
 180:         return base.Resolve(current, original, store, resolveOption);
 181:     }
 182:  
 183:     protected override int Count<T>(IQueryable<T> query)
 184:     {
 185:         return base.Count<T>(query);
 186:     }
 187:  
 188:     protected override void OnError(DomainServiceErrorInfo errorInfo)
 189:     {
 190:         base.OnError(errorInfo);
 191:     }        
 192: }

Finally and very important you need to apply this workaround on the client side:

   1: public partial class Square
   2: {
   3:     public new Guid ShapeId
   4:     {
   5:         get
   6:         {
   7:             return base.ShapeId;
   8:         }
   9:  
  10:         set
  11:         {
  12:             base.ShapeId = value;
  13:         }
  14:     }
  15:  
  16:     public new int CenterX
  17:     {
  18:         get
  19:         {
  20:             return base.CenterX;
  21:         }
  22:  
  23:         set
  24:         {
  25:             base.CenterX = value;
  26:         }
  27:     }
  28:  
  29:     public new int CenterY
  30:     {
  31:         get
  32:         {
  33:             return base.CenterY;
  34:         }
  35:  
  36:         set
  37:         {
  38:             base.CenterY = value;
  39:         }
  40:     }
  41: }

And you will be able to run this code on client side:

   1: RootEntity rootEntity = new RootEntity();
   2: rootEntity.Id = Guid.NewGuid();
   3: rootEntity.Name = "A";
   4:  
   5: ChildEntity child = new ChildEntity();
   6: child.Id = Guid.NewGuid();
   7: rootEntity.Child = child;
   8:  
   9: SubChildEntity subChild = new SubChildEntity() { Id = Guid.NewGuid() };
  10: child.SubChildren.Add(subChild);                
  11:  
  12: Square square = new Square { ShapeId = Guid.NewGuid(), CenterX = 10, CenterY = 10 };
  13: subChild.Shape = square;
  14:  
  15: this.domainContext.RootEntities.Add(rootEntity);
  16:  
  17: var submitOperation = this.domainContext.SubmitChanges();
  18: submitOperation.Completed += (o, ee) =>
  19:     {
  20:         var op = (SubmitOperation)o;
  21:         if (op.HasError)
  22:         {
  23:             this.errors.Add(op.Error);
  24:         }
  25:     };

I was able to do the update using this code:

   1: bool flag2 = false;
   2: bool flag3 = false;
   3: bool flag4 = false;
   4:  
   5: private void btRunTest2_Click(object sender, RoutedEventArgs e)
   6: {
   7:     try
   8:     {
   9:         var op = this.domainContext.Load(this.domainContext.GetRootEntitiesQuery());                
  10:  
  11:         op.Completed += (o, ee) =>
  12:             {                                                
  13:                 var entity = this.domainContext.RootEntities.First();
  14:                 var op2 = this.domainContext.Load(this.domainContext.GetChildEntitiesQuery(entity.Id));
  15:                 op2.Completed += (oo, eee) =>
  16:                     {
  17:                         flag2 = true;
  18:                         OnEditEntity();
  19:                     };
  20:  
  21:                 var op3 = this.domainContext.Load(this.domainContext.GetSubChildrenQuery(entity.Id));
  22:                 op3.Completed += (oo, eee) =>
  23:                     {
  24:                         flag3 = true;
  25:                         OnEditEntity();
  26:                     };
  27:  
  28:                 var op4 = this.domainContext.Load(this.domainContext.GetShapesQuery(entity.Id));
  29:                 op4.Completed += (oo, eee) =>
  30:                     {
  31:                         flag4 = true;
  32:                         OnEditEntity();
  33:                     };                       
  34:             };
  35:     }
  36:     catch (Exception ex)
  37:     {
  38:         this.errors.Add(ex);
  39:     }
  40: }
  41:  
  42: private void OnEditEntity()
  43: {
  44:     if (flag2 && flag3 && flag4)
  45:     {
  46:         var entity = this.domainContext.RootEntities.First();
  47:         entity.Name = "B";
  48:         this.domainContext.SubmitChanges();
  49:     }
  50: }

Notice that ALL related entitysets must have the entities loaded for the associations to be correctly initialized.

Have fun,