WCF RIA Services Support for EF 4.1 (and EF Code-First)

I am pleased to announce that WCF RIA Services now supports EntityFramework 4.1 (including EF Code-First). This will be added to the WCF RIA Services Toolkit, but we are releasing it today as a NuGet package.


In April 2011, EntityFramework released version 4.1 of their product, which contained 2 important updates –

  1. DbContext based API
  2. Code-First support

You can get more information about the EF 4.1 release on the ADO.NET team blog. We are adding support to these 2 features in the WCF RIA Services V1.0 SP2 release. This consists of the following additions / changes –

  • A new domain service that supports DbContext and Code-First known as DbDomainService.
  • Tooling support to generate code for the custom DbDomainService, just like the LinqToEntitiesDomainService.

This will allow you to use EF DbContext in either the data first, model first or Code First modes with WCF RIA Services.



    – You will need WCF RIA Services V1.0 RTM, SP1 or SP2 installed.

NuGet package – The WCF RIA Services runtime support for EF 4.1 is in the assembly Microsoft.ServiceModel.DomainServices.EntityFramework.dll. You can get it here-

RIAServices.EntityFramework NuGet Package

DbDomainService CRUD Methods Code Snippet – For the benefit of anyone trying this preview, I have put together code snippets that will generate CRUD methods for the custom DbDomainService. Please note that these code snippets will not be released/supported officially. They are there only to make the process of trying out this preview as easy as possible. You can download the code snippets here –

C# Snippet / VB Snippet

What is not included?

1. Wizard support – The wizard support for DbDomainService is embedded in the product and cannot be added until we are ready with the next release. For now, you will have to manually code a DbDomainService or use the Code Snippets provided

2. Database Initializer settings – The EF Database Initializer needs to be tweaked depending on whether the context is runtime or design-time. This logic is also in the product and not available as a part of this preview. So for this preview, you have to set the initializer manually for design-time as I explain in the walkthrough below.

Getting started

Here I will walk you through how you can get started with using EF Code-First in a WCF RIA Services App. Let us assume that you have WCF RIA Services installed. If not, you can install it from here.

1. Create a WCF RIA Services Application

Create a Silverlight Application with the Enable RIA Services option enabled or any other WCF RIA Services project (like the Silverlight Business Application).

2. Add the RiaServices.EntityFramework NuGet package to the project.

To do that, go to Package Manager Console and type “Install-Package RIAServices.EntityFramework”.

This should automatically install the EntityFramework 4.1 for you, if you don’t have it already installed. If you already have it installed, add a reference to EntityFramework.dll to the project. You will also need to add a reference to System.Data.Entity.dll.

3. Add an EntityFramework Model using the Code-First approach to the web project.

So let us define an entity called Product, with some properties on it. We will also define a  DbContext called ProductDbContext that has a DbSet of Products on it. (You can find more information on how to use EF Code-First here). So the code looks like this –

namespace EFCFSample.Web
    public class Product {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public int? CategoryID { get; set; }
        public Decimal? UnitPrice { get; set; }
        public bool Discontinued { get; set; }

    public class ProductDbContext : DbContext {
        public ProductDbContext()
            if (HttpContext.Current == null)

        public DbSet<Product> Products { get; set; }

Notice the code I have in the ctor of the ProductDbContext? That piece of code checks if the HttpContext is null and if it is, sets the database initializer to null. Here is why we need it.

Additional Code Changes Needed to Work with the Preview –

EntityFramework initializes the database when you create a DbContext. instance. You want that to happen at runtime but not at design time. WCF RIA Services will initialize the DbContext at design time as well (only for EF Code-First). So we need to prevent the database from being initialized at design time. The logic to to do this is embedded in the product that will be released with the RIA Services V1.0 SP2.

So, until then, you will have to manually prevent the database from being initialized at design time. To do that, we identify if the execution context is design time context (by checking if the HttpContext.Current is null) and if it is, we set the database initializer to null. Note that this will not be required with the actual release bits of WCF RIA Services V1.0 SP2 and Toolkit.

4. Add a DbDomainService.

Alright, now that the DbContext has been set up, we can go ahead and define a class deriving from DbDomainService<ProductDbContext> (similar to any other RIA Services DomainService) like this –

namespace EFCFSample.Web
    public class DomainService1 : DbDomainService<ProductDbContext>

5. Add CRUD Methods to the DbDomainService

Now, we will use the C# code snippet to generate the CRUD methods for us. So download the code snippet to the disk. Then use the VS Code Snippet Manager to import it to Visual Studio. For more information on how to do that, refer to this msdn documentation. I would recommend importing it to My Code Snippets (which will be typically under c:\Users\<username>\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets)

When that is done, from within the class declaration, use the shortcut “dbcrud” to get your DbDomainService CRUD methods defined for you.

Note that this code snippet has 3 variables that you need to supply –

  1. Name of the Entity (in this case, Product)
  2. Name of the DbSet property corresponding to the entity (Products)
  3. Name of the entity (this is used to generate the names of the CRUD methods – like GetProducts, etc.).

So our DbDomainService looks like this-

namespace EFCFSample.Web
    public class DomainService1 : DbDomainService<ProductDbContext>
        public IQueryable<Product> GetProducts()
            return this.DbContext.Products;

        public void InsertProduct(Product entity)
            DbEntityEntry<Product> entityEntry = this.DbContext.Entry(entity);
            if ((entityEntry.State != EntityState.Detached))
                entityEntry.State = EntityState.Added;
            else {

        public void UpdateProduct(Product currentProduct)
            this.DbContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct), this.DbContext);

        public void DeleteProduct(Product entity)
            DbEntityEntry<Product> entityEntry = this.DbContext.Entry(entity);
            if ((entityEntry.State != EntityState.Deleted))
                entityEntry.State = EntityState.Deleted;
            else {


Again, the SP2 release bits will have full wizard support for DbContext. So you should not need to do any of this dance with the code snippet. But till then, this should be easy enough for you to do.

5. Use the DbDomainService in your App

With this, you have a RIA Services DomainService talking to a EF Code-First database that you can use, just like in any other RIA Services application. Of course, you can add/modify the methods in the generated DomainService or add more CRUD methods for other entities in your EF Model.

In short, your EF Code-First model is ready for use in the WCF RIA Services app! 

If you are interested in trying using EF Code-First or simply DbContext with WCF RIA Services, try out this preview and let us know how you find it. Any feedback from you will be highly appreciated!


OperationTag–Its Demise and Workarounds

In the WCF RIA Services V1.0 SP2 Preview (April 2011) release, we introduced a new feature called OperationTag. It allowed you to tag server requests with a Client/Session/Operation Id known as an OperationTag, for client/session/operation tracing/tracking respectively. We have decided to cut this feature from the next release of the V1.0 SP2. I intend to explain the reasons for our decision and other alternatives that you could use instead, in this post.

Original Design and Implementation

As I mentioned before, the OperationTag was intended to be used to tag server requests with an ID for per client/session/operation tracking.  It is strictly metadata and not a part of the Data sent over to the server.

So the options we had to send this additional info were –

  1. As part of the message body

    This would work, technically. However, there were 2 problems with this approach –
    a. The OperationTag is not really part of the “Data” being sent to the server, it is really “metadata”. The data being sent in the body is expected to be consumed on the client. The OperationTag doesn’t quite fit into that category.
    b. And more importantly, currently, the data is sent directly in the body of the message. To be able to send additional metadata in the body, we would have to introduce some sort of enclosing tags to differentiate it form the data. That would be a breaking change.

  2. As a Query parameter on the URL

    Again, this could have worked, technically. But it has problems similar to the one above, viz-
    a. It is semantically incorrect – a query parameter is not the right place to put additional (client tracking) metadata.
    b. And more importantly, this would only work for Queries. For Invoke and Submit Operations, it would not work.

  3. Custom HTTP Header

    HTTP allows adding custom headers that are intended to carry any metadata that needs to be sent across requests and responses. This seemed like the best option to implement the OperationTag. It is correct semantically, it would work for all types of requests (query/invoke/submit) and not break any existing scenarios.
    For these reasons, we decided to go with the HTTP Header approach. That was the implementation we released in the WCF RIA Services V1.0 SP2 Preview (April 2011).

(Note: We also considered some other options, but they were all rejected for various reasons. I will not enumerate all of them, for brevity.)
In the HTTP Headers based implementation, the user could specify the OperationTag on the client which would then be sent to the server on subsequent server calls using a custom HTTP Header. The RIA Services server code would access it from the HTTP header and surface it via the OperationTag property on the DomainServiceContext.

(Note: In this post, the term “OperationTag” is used to denote the Client ID, Session ID or the Operation ID used for tracking purposes).

Demise of the OperationTag

    The HTTP Header based implementation of the OperationTag discussed above, though seemingly straightforward and full-proof, failed in a number of scenarios.

1. Cross-Domain Calls

Custom HTTP Headers are not supported for Cross Domain Calls by the browser. This means you cannot use Cross Domain calls with RIA Services if you use this feature – a restriction we certainly would not want to impose on RIA Services customers.

2. Custom HTTP Headers cause Firefox to crash with Default settings

Firefox crashes if you have custom HTTP Headers in Silverlight and the OOPP (Out of Process Plug-ins) flag turned on (it is on by default). It is a bug external to RIA Services and is being tracked in Bugzilla. The problem goes away if you manually turn the OOPP switch off. But we do want to support all browsers in their default configurations for RIA Services. Not doing that would cause frustration to a large number of RIA Services users out there who may be unaware of this problem.

3. HTTP Headers encoding

HTTP Headers allow only ASCII values. Since the OperationTag is set by the user, it is likely that the user would  use something other then ASCII characters, which would cause the HTTP stack to throw an exception. To get rid of that, we could use some sort of encoding for the OperationTag value. But that would mean 2 things –
– The OperationTag would be less readable “On the wire”.
– Since the Server would always use that encoding to decode the incoming OperationTag value, anyone implementing their custom clients (presumably for the JSON/SOAP endpoints), would have to implement similar encoding schemes for the OperationTag.
Both these might be unnecessary complications for someone intending to send plain ASCII tags.

In short, the current implementation would not work in all scenarios cleanly. Also there didn’t seem to be an alternate solution available right now that would fit all our requirements. Because of these reasons, we decided to pull out the OperationTag feature from the RIA Services codebase.


While we could not find a means to provide a framework level solution for this feature, we have identified some workarounds that many of you who wanted to use this feature, may benefit from. These should be relatively easy to implement in your application. But please be aware of their limitations; these workarounds are provided “as is” with no warranties.

1. Cookies

You can use cookies for client tracking on the server. In this approach, on the first call from the client, the server sets a cookie identifying that particular client on the outgoing response. Thereafter, all the calls from that client will contain that cookie, which the server can use to identify the client.

So on the server, you can use methods like these to set / get the cookie –

private static void SetCookie(string clientID)
    HttpContext context = HttpContext.Current;
    if (context != null && context.Response != null)
        if (context.Response.Cookies["ClientIDCookie"] == null)
            context.Response.Cookies.Add(new HttpCookie("ClientIDCookie") { Value = clientID });

private static string GetCookie()
    HttpContext context = HttpContext.Current;
    string cookieValue = string.Empty;
    if (context != null && context.Request != null)
        HttpCookie clientCookie = context.Request.Cookies["ClientIDCookie"];
        if (clientCookie != null)
            cookieValue = clientCookie.Value;
    return cookieValue;

(Note that you can have more sophisticated implementations for cookies. I have used a simple one just as a sample).

Then,  the first time a client connects to the server, you set a cookie on the HttpResponse with a generated ClientID using SetCookie(). After that, all the calls from that client will contain the cookie with the ClientID that you can obtain using GetCookie().

Advantages –

  • The implementation is simple and straightforward and should work in most of the cases.
  • No changes are required on the client.

Disadvantages –

  • Since this approach is implemented by the server, you can only implement Client/Session level tracking with this approach. Operation level tracking is not possible.

2. Implementing the OperationTag via HTTP Headers on top of RIA Services

You can have your own implementation of OperationTag based on HTTP Headers, similar to the one released in WCF RIA Services V1.0 SP2 Preview (April 2011).

To implement this, you need to insert the OperationTag in an HTTP Header on the client. You can do it in a number of ways. One of them is to use a IClientMessageInspector. You would hook up an IClientMessageInspector to the to your DomainContext using a WebHttpBehavior. The inspector would add the OperationTag to a HTTP Header on the outgoing message.

You can set the value of the OperationTag from your main page using a Thread Local Storage property on the MessageInspector.

So on the client, the code would look something like this –

namespace BusinessApplicationNamespace
    /// <summary>
    /// Custom client WebHttpBehavior to add our CustomMessageInspector to the runtime.
    /// </summary>
    internal class ClientCustomBehavior : WebHttpBehavior
        public ClientCustomBehavior()
            : base()

        public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            base.ApplyClientBehavior(endpoint, clientRuntime);
            clientRuntime.MessageInspectors.Add(new CustomMessageInspector());

    /// <summary>
    /// Custom MessageInspector that will add the OperationTag to the outgoing message.
    /// </summary>
    internal class CustomMessageInspector : IClientMessageInspector
        // Thread specific storage to hold the OperationTag value.
        public static string OperationTag { get; set; }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
            if (OperationTag != null && OperationTag.Length > 0)
                this.AddOperationTagToHttpHeader(ref request);
            return null;

        private void AddOperationTagToHttpHeader(ref Message message)
            // HTTP Header size is typically 4k.
            if (OperationTag.Length > 4096)
                throw new InvalidOperationException("Header too big");

            // First check if the outgoing message has a HttpRequestMessageProperty and use that. Else create a new one.
            HttpRequestMessageProperty httpRequestMessageProperty;
            if (message.Properties.ContainsKey(HttpRequestMessageProperty.Name))
                httpRequestMessageProperty = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
                httpRequestMessageProperty = new HttpRequestMessageProperty();
                message.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessageProperty);

            // Add the OperationTag to the header with the name "OperationTag".
            httpRequestMessageProperty.Headers["OperationTag"] = OperationTag;

In the main code, you can hook up the CustomWebHttpBehavior to the DomainContext by accessing the ChannelFactory on the DomainClient. You also set the OpertionTag value using the public property on the MessageInspector.

public partial class MainPage : UserControl
    DomainService1 ds;
    public MainPage()

        ds = new DomainService1();

        ChannelFactory factory = ((WebDomainClient<BusinessApplicationNamespace.Web.DomainService1.IDomainService1Contract>)ds.DomainClient).ChannelFactory;
        factory.Endpoint.Behaviors.Add(new ClientCustomBehavior());

        CustomMessageInspector.OperationTag = "Client1";

On the server, you can check if the incoming message has a HTTP Header containing the OperationTag. If it does, then you access its value to get your client/session/operation ID.

/// <summary>
/// Get the OperationTag from the HTTP Header if there exists one.
/// </summary>
/// <returns>The OperationTag value is there is one, else null.</returns>
private static string GetOperationTag()
    string operationTag = null;
    OperationContext operationContext = OperationContext.Current;
    if (operationContext != null)
        HttpRequestMessageProperty httpRequestMessageProperty = (HttpRequestMessageProperty)operationContext.IncomingMessageProperties[HttpRequestMessageProperty.Name];
        if (httpRequestMessageProperty != null)
            operationTag = httpRequestMessageProperty.Headers["OperationTag"];
    return operationTag;

Advantages –

  • Unlike the Cookie based approach, you can implement operation level tracking (along with client/session level tracking) with this approach.

Disadvantages  –

  • This approach has all shortcomings noted above, because of which we could not implement it in the WCF RIA Services product itself. However, for those who can live with them (for eg. if you don’t care about cross domain calls or supporting Firefox default config), then this implementation could work very well for you.

3. Tweaking the DomainService

Now if you want to have operation level tracking and also not have to deal with the shortcomings of the HTTP Headers, then you could modify the domain service itself to carry the OperationTag to the client. This needs to be done differently for each type of server call –

a. Query methods – Add an OperationTag parameter. You can then pass the OperationTag as the query parameter and access the parameter on the server.

b. Submit operations – Add a dummy entity type to your solution that contains a dummy property called, say, OperationTag. Then add this entity to the changeset being submitted. Then on the server, you can retrieve the OperationTag by accessing the property on the dummy entity.

c. Invoke Operation – Add an OperationTag parameter, just like the query method.

Advantages –

  • This approach should work in all the scenarios RIA Services currently supports.

Disadvantages –

  • Unlike the other approaches, it does not sit on top of RIA Services – you need to modify your DomainService to implement this.
  • This solution is “not pretty”. Smile

However, as I said before, all these implementations are fairly simple and straightforward to implement. Hopefully, using one of these, it should not be too heavy to implement the client/session/operation tracking on top of your domain service. If you find any approaches better than these, please let me know!

Happy Coding!

Custom VB CodeGenerator with RIA Services T4 Code Generator

The T4 Code Generator that ships with the RIA Services Toolkit doesn’t have a VB Code Generator. So for VB Code Generation, you would have to use the CodeDom Code Generator that ships with the RIA Services Product. Or you could write your own Custom VB Code Generator using T4 templates and plug it in to the T4 ClientCodeGenerator.

However, this would not work earlier because of a bug in the code, that prevented any VB Code Generators from working. We have fixed the bug now and the fix is now available with the WCF RIA Services Toolkit (April 2011). Note that this does not contain a VB Code Generator using T4 Templates. It just contains the fix to let anyone stick in their own T4 VB CodeGenerator and use it with RIA Services.

T4 Code Generator December 2010 Update

As I mentioned in my first blog on the T4 Code Generator the T4 Code Generator was released as a experimental feature with almost no testing done. Naturally, it had bugs which many of you have faced. And although working around the issues is relatively easy because of the extensibility features of the T4 code generator, it is certainly unnecessary work. So we have made a number of code fixes and improvements to the T4 Code Generator that will be released with the WCF RIA Services Toolkit release today.

Here is the list of what has changed and what has not in the T4 Code Generator –

  1. First of all, the API remains the same. So the list of methods that you can override to customize the generated code and the way to do it remains the same (as described in my previous post).
  2. There were bugs around the type names being generated incorrectly (including the one blogged by Jeff in his T4 Walk-up experience post). They have been fixed now. So you should not get errors related to type names being generated incorrectly (including enums, generic types, arrays, etc).
  3. There were also bugs around the code that was being generated for Association Properties. Those have been addressed as well. We have done functional testing for this particular fix and made sure that all the association property cases work fine with the T4 Code Generator.
  4. We have fixed bugs and done QA testing to make sure that the code generated by the T4 Code Generator builds fine for all the different scenarios handled by WCF RIA Services. Note that this was not functional testing, but testing to simply ensure that the code generated builds without error.
    So in short, the state of the T4 Code Generator has improved significantly since the Beta release last month. We are still some distance away from the place we want to be, where all WCF RIA Services apps out there are guaranteed to work with T4 Code Generator, but this is a definite step in that direction. We hope to get there in one of our next releases.

Please let us know if you find any more bugs in the code generator and we will try to address them as soon as possible. Also, feedback about the API, features, usability and the T4 Code Generator in general will be greatly appreciated.

T4 Code Generator Extensibility

In my previous post, I covered the overall structure of the T4 Code Generator and how it can be used instead of the default code generator. Here I will cover how you can customize it.

The T4 Code Generator is intended to be extensible.  You should be able to derive from it and tweak the code generation to modify the generated code as required. For that, the generator has the following extensibility points:


Each of the 5 code generators (CSharpDomainContextGenerator, CSharpEntityGenerator, CSharpComplexObjectGenerator, CSharpEnumGenerator and CSharpWebContextGenerator) contain a number of protected virtual methods. Each of these methods roughly map to the corresponding part of generated code. To modify the code for a particular component, you can derive from that particular code generator and override the method for the part for which you want to modify the generated code.

For example, consider the CSharpDomainContextGenerator that generates DomainContext code in C# given a DomainServiceDescription. It contains the following protected virtual methods:

protected virtual void GenerateAttributes(IEnumerable<Attribute> attributes);
protected virtual void GenerateBody();
protected virtual void GenerateClassDeclaration();
protected virtual void GenerateConstructors();
protected virtual void GenerateCustomMethods();
protected virtual void GenerateDomainOperationEntry(DomainOperationEntry domainMethod);
protected virtual void GenerateEntityContainer();
protected virtual void GenerateEntitySet(Type entityType);
protected virtual void GenerateEntitySets();
protected virtual void GenerateExtensibilityMethods();
protected virtual void GenerateInvokeOperations();
protected virtual void GenerateQueryMethod(DomainOperationEntry domainOperationEntry);
protected virtual void GenerateQueryMethods();

Now, if you want to modify the code generated for the DomainContext constructors, you would declare a type that derives from the CSharpDomainContextGenerator and override the GenerateConstructors() method. Note that if you want to add code before or after the code generated by the base method, you can follow the following pattern (which is pretty convenient in quite a few cases):

class MyDomainContextGenerator : CSharpDomainContextGenerator
protected override void GenerateConstructors()
//Add code before


//Add code after

Of course, you can completely change the generate code by not calling into the base class implementation, if that suits your needs.

Each of the above virtual methods generate code as indicated by their names. All the other code generators also have such virtual methods that can be overridden in a similar fashion. I won’t go into the details of each one of those here.
The GenerateBody() method is special (it exists on all the code generators). This method generates the entire body of the class by calling into other protected virtual methods above. If you want to add additional code to the class, you will override this method, call base.GenerateBody() and then add any additional code that you might want to generate.
Note: This method does not include the class declaration (it does not call the ClassDeclaration() method).

The ClientCodeGenerator class (which is the base class for CSharpClientCodeGenerator) contains protected abstract properties for the 5 code generators.

protected abstract ComplexObjectGenerator ComplexObjectGenerator { get; }
protected abstract DomainContextGenerator DomainContextGenerator { get; }
protected abstract EntityGenerator EntityGenerator { get; }
protected abstract EnumGenerator EnumGenerator { get; }
protected abstract WebContextGenerator WebContextGenerator { get; }

The CSharpClientCodeGenerator populates them with the default implementations of the code generators above. To make the code generator use your custom generator for any of the above generators, define a type that derives from CSharpClientCodeGenerator and override the property for the generator you want to substitute with your own. This now becomes your custom T4 Code Generator. So the WCF RIA Services code generation process will use this type to do all code generation. For that you will have to add the attribute [DomainServiceClientCodeGenerator] on the type you define. For example, to use the custom DomainContextGenerator from the above example, you will define a type as follows:

[DomainServiceClientCodeGenerator(“MyCustomGenerator”, “C#”)]
class MyCSharpClientCodeGenerator : CSharpClientCodeGenerator
protected override DomainContextGenerator DomainContextGenerator
return new MyDomainContextGenerator();

Now this is your T4 Code Generator. Then when you add a reference to your assembly (containing these types) on the server and a <RiaClientCodeGeneratorName>property indicating the assembly name to the Silverlight project file, you will get your custom code generated on the client.

For a complete walkthrough of the T4 Code Generation customization process (along with ways to work around the bugs in it), please refer to a great post by Jeff here.

T4 Code Generator for WCF RIA Services

I had always wanted to have a technical blog since I joined Microsoft, but somehow never ended up writing one. Now, finally, after we released WCF RIA Services V1.0 SP1 Beta and WCF RIA Services Toolkit October 2010 last week, I have decided to blog about the T4 Code Generation feature we have added to the WCF RIA Services Toolkit.
This post will focus on the design and use of the feature. I will follow-up with a post on the extensibility mechanism of the code generator.

The Code Generation module that ships with RIA Services is now extensible to allow different Code Generators to be used instead of the default CodeDom based code generation. This is to allow customers to modify the code generation process and generate custom code on the client.

To that end we have shipped the T4 Code Generator that is customizable to allow you to tweak the code generation and modify the generated code as required. Currently it supports only C# based code generation.


The T4 Code Generator consists of 2 parts:
1. CSharpClientCodeGenerator

This is the main component of the T4 Code Generation process that hooks into the extensibility features of the WCF RIA Services Code generation process. It controls code generation of different types on the client.

2. The 5 different code generators:

  • CSharpDomainContextGenerator
  • CSharpEntityGenerator
  • CSharpComplexObjectGenerator
  • CSharpEnumGenerator
  • CSharpWebContextGenerator

As their names indicate, each of these generators generate code for their respective types (CSharpEntityGenerator generates Entity types in C# and so on). These code generators generate code using the TextTemplates. (For more information about T4 you can follow the msdn documentation or Oleg Synch’g blog)

The CSharpClientCodeGenerator implements the IDomainServiceClientCodeGenerator interface and returns a string containing the generated code. It also declares itself to the WCF RIA Services code generation using the [DomainServiceClientCodeGenerator] attribute (which uses a MEF based approach underneath).

The code generation process calls passes a list of DomainServiceDescriptions to the CSharpClientCodeGenerator. Using that list, it generates code for DomainContexts, Entities, ComplexObjects, Enums and the application wide WebContext by calling into the respective individual code generators.

The CSharpClientCodeGenrator also contains public properties for ClientCodeGenerationOptions and ICodeGenerationHost. It acts as the context for each of the different code generators.

Using the T4 Code Generator

To use the T4 Code Generator instead of the default CodeDom based code generator you will have to do the following:

  1. Add a reference to the assembly Microsoft.ServiceModel.DomainServices.Tools.TextTemplate which contains the T4 Code Generator.
  2. Edit the silverlight project file and add the following tag:
    Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35

Now when you build, the code will be generated on the client using this code generator.

I will cover how this T4 Code Generators can be extended to generate custom code in my next post.