Silverlight and WCF RIA Services (4 – RIA Services Libraries)
Silverlight and WCF RIA Services (4 – RIA Services Libraries)
Specifying mime types for content in WCF Data Services
WCF Data Services provides an specific operator “$value” for retrieving the underline value of any of the properties in exposed resources. Let’s say you have a resource “Configuration” that exposes a field “Xml” whose content should be treated as a mime type “text/xml”. When you execute a query like this to retrieve the value of that field, “myService.svc/Configurations(1)/Xml/$value”, what you get is the content of that field but expressed as plain text (text/plain). This happens because the default behavior for WCF Data Services is to return most of the primitive types as “text/plain” and some others like byte arrays as “application/octet-stream”. So, how do you change that default behavior to retrieve property content with other mime types ?. Here is where the MimeTypeAttribute can be used to change that behavior.
The MimeTypeAttribute can actually only be used with the ReflectionProvider, which is the default provider for exposing objects that are not EF entities. If you want to change the mime type for the EF Provider, you need to modify the underline CSDL model (This is the part that is not well documented, and I only found some incomplete references in some forums).
For the reflection provider, the attribute must be specified at class level,
[MimeType("Xml", "text/xml")]
public class Configuration
{
public string Xml { get; set; }
}
For the EF provider, a few additional changes are required in the CSDL model. Edit the CSDL by opening the EDM model in Xml view, and adding a reference to this namespace "xmlns:m1="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" in the <edmx:ConceptualModels> node of the CSDL section in the EDMX file. Right after that, locate the entity that you want to modify and add the MimeType definition in the property.
<EntityType Name="Configuration">
<Property Name="Xml" m1:MimeType="text/xml" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
Windows Phone 7 Resources
Professional WCF 4.0: Windows Communication Foundation with .NET 4.0
The book in which I been working on since last year finally went to the light this week. It has been the result of hard work between me and three other Connected Systems MVP, my friend Fabio Cozzolino, Kurt Claeys and Johann Grabner. If you are interested in learning the new features in WCF 4.0, but also WCF in general and how to apply in real world scenarios, this book is for you. I dedicated three chapters of this book to one of my favorites topics, Security, from the basics to more complicated scenarios with Claim-Based security and Federated authentication using WCF services with Windows Identity Foundation. You can find more information about the book and the table of contents in the Wrox web site here.
Microsoft UK Event: Managed Extensibility Framework (MEF) with Glenn Block
Silverlight and WCF RIA Services (3 – Client)
Implementing a generic repository for WCF data services
The repository implementation I am going to discuss here is not exactly what someone would call repository in terms of DDD, but it is an abstraction layer that becomes handy at the moment of unit testing the code around this repository. In other words, you can easily create a mock to replace the real repository implementation.
The WCF Data Services update for .NET 3.5 introduced a nice feature to support two way data bindings, which is very helpful for developing WPF or Silverlight based application but also for implementing the repository I am going to talk about. As part of this feature, the WCF Data Services Client library introduced a new collection DataServiceCollection<T> that implements INotifyPropertyChanged to notify the data context (DataServiceContext) about any change in the association links. This means that it is not longer necessary to manually set or remove the links in the data context when an item is added or removed from a collection.
Before having this new collection, you basically used the following code to add a new item to a collection.
Order order = new Order
{
Name = "Foo"
};
OrderItem item = new OrderItem
{
Name = "bar",
UnitPrice = 10,
Qty = 1
};
var context = new OrderContext();
context.AddToOrders(order);
context.AddToOrderItems(item);
context.SetLink(item, "Order", order);
context.SaveChanges();
Now, thanks to this new collection, everything is much simpler and similar to what you have in other ORMs like Entity Framework or L2S.
Order order = new Order
{
Name = "Foo"
};
OrderItem item = new OrderItem
{
Name = "bar",
UnitPrice = 10,
Qty = 1
};
order.Items.Add(item);
var context = new OrderContext();
context.AddToOrders(order);
context.SaveChanges();
In order to use this new feature, you first need to enable V2 in the data service, and then use some specific arguments in the datasvcutil tool (You can find more information about this new feature and how to use it in this post).
DataSvcUtil /uri:"http://localhost:3655/MyDataService.svc/" /out:Reference.cs /dataservicecollection /version:2.0
Once you use those two arguments, the generated proxy classes will use DataServiceCollection<T> rather than a simple ObjectCollection<T>, which was the default collection in V1.
There are some aspects that you need to know to use this feature correctly.
1. All the entities retrieved directly from the data context with a query track the changes and report those to the data context automatically.
2. A entity created with “new” does not track any change in the properties or associations. In order to enable change tracking in this entity, you need to do the following trick.
public Order CreateOrder()
{
var collection = new DataServiceCollection<Order>(this.context);
var order = new Order();
collection.Add(order);
return order;
}
You basically need to create a collection, and add the entity to that collection with the “Add” method to enable change tracking on that entity.
3. If you need to attach an existing entity (For example, if you created the entity with the “new” operator rather than retrieving it from the data context with a query) to a data context for tracking changes, you can use the “Load” method in the DataServiceCollection.
var order = new Order
{
Id = 1
};
var collection = new DataServiceCollection<Order>(this.context);
collection.Load(order);
In this case, the order with Id = 1 must exist on the data source exposed by the Data service. Otherwise, you will get an error because the entity did not exist.
These cool extensions methods discussed by Stuart Leeks in this post to replace all the magic strings in the “Expand” operation with Expression Trees represent another feature I am going to use to implement this generic repository.
Thanks to these extension methods, you could replace the following query with magic strings by a piece of code that only uses expressions.
Magic strings,
var customers = dataContext.Customers
.Expand("Orders")
.Expand("Orders/Items")
Expressions,
var customers = dataContext.Customers
.Expand(c => c.Orders.SubExpand(o => o.Items))
That query basically returns all the customers with their orders and order items.
Ok, now that we have the automatic change tracking support and the expression support for explicitly loading entity associations, we are ready to create the repository.
The interface for this repository looks like this,
public interface IRepository { T Create<T>() where T : new(); void Update<T>(T entity); void Delete<T>(T entity); IQueryable<T> RetrieveAll<T>(params Expression<Func<T, object>>[] eagerProperties); IQueryable<T> Retrieve<T>(Expression<Func<T, bool>> predicate,
params Expression<Func<T, object>>[] eagerProperties); void Attach<T>(T entity); void SaveChanges(); }
The Retrieve and RetrieveAll methods are used to execute queries against the data service context. While both methods receive an array of expressions to load associations explicitly, only the Retrieve method receives a predicate representing the “where” clause.
The following code represents the final implementation of this repository.
public class DataServiceRepository: IRepository { ResourceRepositoryContext context; public DataServiceRepository() : this (new DataServiceContext()) { } public DataServiceRepository(DataServiceContext context) { this.context = context; } private static string ResolveEntitySet(Type type) { var entitySetAttribute = (EntitySetAttribute)type
.GetCustomAttributes(typeof(EntitySetAttribute), true).FirstOrDefault(); if (entitySetAttribute != null) return entitySetAttribute.EntitySet; return null; } public T Create<T>() where T : new() { var collection = new DataServiceCollection<T>(this.context); var entity = new T(); collection.Add(entity); return entity; } public void Update<T>(T entity) { this.context.UpdateObject(entity); } public void Delete<T>(T entity) { this.context.DeleteObject(entity); } public void Attach<T>(T entity) { var collection = new DataServiceCollection<T>(this.context); collection.Load(entity); } public IQueryable<T> Retrieve<T>(Expression<Func<T, bool>> predicate,
params Expression<Func<T, object>>[] eagerProperties) { var entitySet = ResolveEntitySet(typeof(T)); var query = context.CreateQuery<T>(entitySet); foreach (var e in eagerProperties) { query = query.Expand(e); } return query.Where(predicate); } public IQueryable<T> RetrieveAll<T>(params Expression<Func<T, object>>[] eagerProperties) { var entitySet = ResolveEntitySet(typeof(T)); var query = context.CreateQuery<T>(entitySet); foreach (var e in eagerProperties) { query = query.Expand(e); } return query; } public void SaveChanges() { this.context.SaveChanges(SaveChangesOptions.Batch); } }
For instance, you can use the following code to retrieve customers with First name equal to “John”, and all their orders in a single call.
repository.Retrieve<Customer>(
c => c.FirstName == “John”, //Where
c => c.Orders.SubExpand(o => o.Items));
In case, you want to have some pre-defined queries that you are going to use across several places, you can put them in an specific class.
public static class CustomerQueries
{
public static Expression<Func<Customer, bool>> LastNameEqualsTo(string lastName)
{
return c => c.LastName == lastName;
}
}
And then, use it with the repository.
repository.Retrieve<Customer>(
CustomerQueries.LastNameEqualsTo("foo"),
c => c.Orders.SubExpand(o => o.Items));
Dynamic Type to do away with Reflection
The dynamic type in C# 4.0 is a welcome addition to the language. One thing I’ve been doing a lot with it is to remove explicit Reflection code that’s often necessary when you ‘dynamically’ need to walk and object hierarchy. In the past I’ve had a number of ReflectionUtils that used string based expressions to walk an object hierarchy. With the introduction of dynamic much of the ReflectionUtils code can be removed for cleaner code that runs considerably faster to boot.
The old Way - Reflection
Here’s a really contrived example, but assume for a second, you’d want to dynamically retrieve a Page.Request.Url.AbsoluteUrl based on a Page instance in an ASP.NET Web Page request. The strongly typed version looks like this:
string path = Page.Request.Url.AbsolutePath;
Now assume for a second that Page wasn’t available as a strongly typed instance and all you had was an object reference to start with and you couldn’t cast it (right I said this was contrived :-))
If you’re using raw Reflection code to retrieve this you’d end up writing 3 sets of Reflection calls using GetValue(). Here’s some internal code I use to retrieve Property values as part of ReflectionUtils:
/// <summary> /// Retrieve a property value from an object dynamically. This is a simple version /// that uses Reflection calls directly. It doesn't support indexers. /// </summary> /// <param name="instance">Object to make the call on</param> /// <param name="property">Property to retrieve</param> /// <returns>Object - cast to proper type</returns> public static object GetProperty(object instance, string property) { return instance.GetType().GetProperty(property, ReflectionUtils.MemberAccess).GetValue(instance, null); }
If you want more control over properties and support both fields and properties as well as array indexers a little more work is required:
/// <summary> /// Parses Properties and Fields including Array and Collection references. /// Used internally for the 'Ex' Reflection methods. /// </summary> /// <param name="Parent"></param> /// <param name="Property"></param> /// <returns></returns> private static object GetPropertyInternal(object Parent, string Property) { if (Property == "this" || Property == "me") return Parent; object result = null; string pureProperty = Property; string indexes = null; bool isArrayOrCollection = false; // Deal with Array Property if (Property.IndexOf("[") > -1) { pureProperty = Property.Substring(0, Property.IndexOf("[")); indexes = Property.Substring(Property.IndexOf("[")); isArrayOrCollection = true; } // Get the member MemberInfo member = Parent.GetType().GetMember(pureProperty, ReflectionUtils.MemberAccess)[0]; if (member.MemberType == MemberTypes.Property) result = ((PropertyInfo)member).GetValue(Parent, null); else result = ((FieldInfo)member).GetValue(Parent); if (isArrayOrCollection) { indexes = indexes.Replace("[", string.Empty).Replace("]", string.Empty); if (result is Array) { int Index = -1; int.TryParse(indexes, out Index); result = CallMethod(result, "GetValue", Index); } else if (result is ICollection) { if (indexes.StartsWith("\"")) { // String Index indexes = indexes.Trim('\"'); result = CallMethod(result, "get_Item", indexes); } else { // assume numeric index int index = -1; int.TryParse(indexes, out index); result = CallMethod(result, "get_Item", index); } } } return result; }
/// <summary> /// Returns a property or field value using a base object and sub members including . syntax. /// For example, you can access: oCustomer.oData.Company with (this,"oCustomer.oData.Company") /// This method also supports indexers in the Property value such as: /// Customer.DataSet.Tables["Customers"].Rows[0] /// </summary> /// <param name="Parent">Parent object to 'start' parsing from. Typically this will be the Page.</param> /// <param name="Property">The property to retrieve. Example: 'Customer.Entity.Company'</param> /// <returns></returns> public static object GetPropertyEx(object Parent, string Property) { Type type = Parent.GetType(); int at = Property.IndexOf("."); if (at < 0) { // Complex parse of the property return GetPropertyInternal(Parent, Property); } // Walk the . syntax - split into current object (Main) and further parsed objects (Subs) string main = Property.Substring(0, at); string subs = Property.Substring(at + 1); // Retrieve the next . section of the property object sub = GetPropertyInternal(Parent, main); // Now go parse the left over sections return GetPropertyEx(sub, subs); }
As you can see there’s a fair bit of code involved into retrieving a property or field value reliably especially if you want to support array indexer syntax. This method is then used by a variety of routines to retrieve individual properties including one called GetPropertyEx() which can walk the dot syntax hierarchy easily.
Anyway with ReflectionUtils I can retrieve Page.Request.Url.AbsolutePath using code like this:
string url = ReflectionUtils.GetPropertyEx(Page, "Request.Url.AbsolutePath") as string;
This works fine, but is bulky to write and of course requires that I use my custom routines. It’s also quite slow as the code in GetPropertyEx does all sorts of string parsing to figure out which members to walk in the hierarchy.
Enter dynamic – way easier!
.NET 4.0’s dynamic type makes the above really easy. The following code is all that it takes:
object objPage = Page; // force to object for contrivance :)
dynamic page = objPage; // convert to dynamic from untyped object string scriptUrl = page.Request.Url.AbsolutePath;
The dynamic type assignment in the first two lines turns the strongly typed Page object into a dynamic. The first assignment is just part of the contrived example to force the strongly typed Page reference into an untyped value to demonstrate the dynamic member access. The next line then just creates the dynamic type from the Page reference which allows you to access any public properties and methods easily. It also lets you access any child properties as dynamic types so when you look at Intellisense you’ll see something like this when typing Request.:
In other words any dynamic value access on an object returns another dynamic object which is what allows the walking of the hierarchy chain.
Note also that the result value doesn’t have to be explicitly cast as string in the code above – the compiler is perfectly happy without the cast in this case inferring the target type based on the type being assigned to. The dynamic conversion automatically handles the cast when making the final assignment which is nice making for natural syntnax that looks *exactly* like the fully typed syntax, but is completely dynamic.
Note that you can also use indexers in the same natural syntax so the following also works on the dynamic page instance:
string scriptUrl = page.Request.ServerVariables["SCRIPT_NAME"];
The dynamic type is going to make a lot of Reflection code go away as it’s simply so much nicer to be able to use natural syntax to write out code that previously required nasty Reflection syntax.
Another interesting thing about the dynamic type is that it actually works considerably faster than Reflection. Check out the following methods that check performance:
void Reflection() { Stopwatch stop = new Stopwatch(); stop.Start(); for (int i = 0; i < reps; i++) { // string url = ReflectionUtils.GetProperty(Page,"Title") as string;// "Request.Url.AbsolutePath") as string; string url = Page.GetType().GetProperty("Title", ReflectionUtils.MemberAccess).GetValue(Page, null) as string; } stop.Stop(); Response.Write("Reflection: " + stop.ElapsedMilliseconds.ToString()); } void Dynamic() { Stopwatch stop = new Stopwatch(); stop.Start(); dynamic page = Page; for (int i = 0; i < reps; i++) { string url = page.Title; //Request.Url.AbsolutePath; } stop.Stop(); Response.Write("Dynamic: " + stop.ElapsedMilliseconds.ToString()); }
The dynamic code runs in 4-5 milliseconds while the Reflection code runs around 200+ milliseconds! There’s a bit of overhead in the first dynamic object call but subsequent calls are blazing fast and performance is actually much better than manual Reflection.
Dynamic is definitely a huge win-win situation when you need dynamic access to objects at runtime.
