Showing posts with label HowTo. Show all posts
Showing posts with label HowTo. Show all posts

Wednesday, 16 October 2013

How to serialize an Expression

Download (or use NuGet):  https://github.com/esskar/Serialize.Linq

using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Serialize.Linq.Serializers;
using Serialize.Linq.Tests.Internals;
using System;
using System.Linq.Expressions;

namespace Serialize.Linq.Tests
{
public class FilmDto
{
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
}

[TestClass]
public class HowToSerializeAnExpressionTests
{
public TestContext TestContext { get; set; }

private static IQueryable<FilmDto> GetFilms()
{
return new List<FilmDto>
{
new FilmDto { Name = "Gravity", ReleaseDate = new DateTime(2013, 10, 15) },
new FilmDto { Name = "Blade Runner", ReleaseDate = new DateTime(1975, 2, 28) },
new FilmDto { Name = "Superman", ReleaseDate = new DateTime(1985, 6, 6) },
}
.AsQueryable();
}

[TestMethod]
public void BasicExpressionSerialization()
{
var predicate = (Expression<Func<FilmDto, bool>>)(film => film.Name.ToLower().Contains("n"));
var serializer = new ExpressionSerializer(new BinarySerializer());
var bytes = serializer.SerializeBinary(predicate);
var predicateDeserialized = serializer.DeserializeBinary(bytes);
this.TestContext.WriteLine("{0} serializes to bytes with length {1}", predicate, bytes.Length);

ExpressionAssert.AreEqual(predicate, predicateDeserialized);

var films = GetFilms();
var expectedCount = films.Where(predicate).Count();

// a simple example of executing an expression, leveraging IEnumerable
var actualCount = films.Where((Expression<Func<FilmDto, bool>>)predicateDeserialized).Count();
Assert.AreEqual(expectedCount, actualCount);

// constructing the same call using more Expressions
Expression whereMethodCall = Expression.Call(
typeof(Queryable),
"Where",
new[] { films.ElementType },
films.Expression,
Expression.Quote(predicateDeserialized));

// executing the expression, leveraging IQueryable
actualCount = films.Provider.CreateQuery<FilmDto>(whereMethodCall).Count();
Assert.AreEqual(expectedCount, actualCount);
}
}

// Bear in mind this issue with .NET 45: http://forums.asp.net/t/1864636.aspx
// reproducible if you use: (film => film.ReleaseDate < new DateTime(1990, 01, 01))
// (which is fixed with .NET 451!)
// For finer grain support:
// http://msdn.microsoft.com/en-us/library/vstudio/bb882637.aspx
}


image



If you want to swap out the BinarySerializer for Json, this would be the payload:

{
"__type":"L:#Serialize.Linq.Nodes",
"NT":18,
"T":{
"G":[
{
"N":"Serialize.Linq.Tests.FilmDto"
},
{
"N":"System.Boolean"
}
],
"N":"System.Func`2"
},
"B":{
"__type":"MC:#Serialize.Linq.Nodes",
"NT":6,
"T":{
"N":"System.Boolean"
},
"A":[
{
"__type":"C:#Serialize.Linq.Nodes",
"NT":9,
"T":{
"N":"System.String"
},
"V":"n"
}
],
"M":{
"D":{
"N":"System.String"
},
"M":8,
"S":"Boolean Contains(System.String)"
},
"O":{
"__type":"MC:#Serialize.Linq.Nodes",
"NT":6,
"T":{
"N":"System.String"
},
"A":[

],
"M":{
"D":{
"N":"System.String"
},
"M":8,
"S":"System.String ToLower()"
},
"O":{
"__type":"M:#Serialize.Linq.Nodes",
"NT":23,
"T":{
"N":"System.String"
},
"E":{
"__type":"P:#Serialize.Linq.Nodes",
"NT":38,
"T":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"N":"film"
},
"M":{
"D":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"M":16,
"S":"System.String Name"
}
}
}
},
"P":[
{
"__type":"P:#Serialize.Linq.Nodes",
"NT":38,
"T":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"N":"film"
}
]
}


If you want to swap it out for the XmlSerializer, this would be the payload:

<?xml version="1.0" encoding="UTF-8"?>
<E xmlns="http://schemas.datacontract.org/2004/07/Serialize.Linq.Nodes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="L">
<NT>Lambda</NT>
<T>
<G>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<T>
<N>System.Boolean</N>
</T>
</G>
<N>System.Func`2</N>
</T>
<B i:type="MC">
<NT>Call</NT>
<T>
<N>System.Boolean</N>
</T>
<A>
<E i:type="C">
<NT>Constant</NT>
<T>
<N>System.String</N>
</T>
<V xmlns:a="http://www.w3.org/2001/XMLSchema" i:type="a:string">n</V>
</E>
</A>
<M>
<D>
<N>System.String</N>
</D>
<M>Method</M>
<S>Boolean Contains(System.String)</S>
</M>
<O i:type="MC">
<NT>Call</NT>
<T>
<N>System.String</N>
</T>
<A />
<M>
<D>
<N>System.String</N>
</D>
<M>Method</M>
<S>System.String ToLower()</S>
</M>
<O i:type="M">
<NT>MemberAccess</NT>
<T>
<N>System.String</N>
</T>
<E i:type="P">
<NT>Parameter</NT>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<N>film</N>
</E>
<M>
<D>
<N>Serialize.Linq.Tests.FilmDto</N>
</D>
<M>Property</M>
<S>System.String Name</S>
</M>
</O>
</O>
</B>
<P>
<E i:type="P">
<NT>Parameter</NT>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<N>film</N>
</E>
</P>
</E>

Wednesday, 6 July 2011

Comparing ProtoBuf-net Serialisation

ProtoBuf-net is a C# engine for Protocol Buffers, a binary serialisation format created by Google.

The project is written and maintained by Marc Gravell who currently works for Stack Overflow. 

The source for this project can be found here: http://code.google.com/p/protobuf-net/

probuf-net_logo

I’ll be comparing the size of the output along with the speed for serialisation and deserialisation speed for the following methods:

  • Xml Serializer with binary formatter using the [Serializable] attribute
  • Data Contract Xml Serializer using the [DataContract] & [DataMember] attributes
  • Data Contract Json Serializer again using the [DataContract] & [DataMember]
  • ProtoBuf-net v2 BETA (but used by StackOverflow) using the reflection and [ProtoContract] & [ProtoMember] attributes
  • ProtoBuf-net v2 BETA (but used by StackOverflow) using a compiled model with no attributes on my data classes
  • ProtoSharp ALPHA (another C# Protocol Buffers serialisation engine by Torbjorn Gyllebring)

For my tests I’ll be using the following model:

model

Here’s the object model view when populated with data:

Data

Simple to use

Here is an example of how to create a Protobuf-net compiled model as opposed to attributes on the class and fields:

Write and Read from Memory Stream

ScreenShot077

Shared Object References

If you have multiple pointers to the same object you can utilise the graph support added in v2.

This example was taken from a Stack Overflow question answered by Marc Gravell:

http://stackoverflow.com/questions/6063729/does-protocol-buffers-support-serialization-of-object-graphs-with-shared-referenc/6063837#6063837

Conclusion

With Protobuf-net serialisation and deserialisation times are reduced so you should get a quick win out of the box.

If the largest bottleneck in your solution is the transfer speed of data between processes this engine can greatly benefit your project as the data footprint is dramatically reduced.

In order to accurately calculate if your solution would benefit from the use of ProtoBuf-net, you’ll need to set up scenarios that mimic your real world requirements as closely as possible.

Downloads

You can download the source code here:

http://stevenhollidge.com/blog-source-code/Protobuf-net-Tests.zip

Thursday, 2 June 2011

Demystifying WCF RIA Services Part 2

Following on from Part 1, we’ll now add insert, update and delete methods to our WCFRIA domain service.

Update your PersonService.cs class as follows:

Note I’m using attributes here to explicitly define the operations for Insert, Update and Delete.  I could have left these off as WCFRIA Services picks up Insert/Create/Add within the method for Insert, Update/Edit and Updates and Remove/Delete for deletions but I prefer to keep things explicit.

We are also overriding the Submit method here, which isn’t required but get’s called by the client proxy and passes back the changed item set before each of the the insert/update/delete methods are called for the individual changed items.

We'll keep the GUI real simple with just a datagrid, save button and status textblock but you'll see how powerful the grid is shortly: MainPage.xaml

Finally update your code behind on the server, note the callback methods for each of the service calls.  Remember all service calls are async in Silverlight and I reckon including the call back methods to response to any errors that might have occurred during the service call: MainPage.xaml.cs

On start up our service loads the data grid with data:

ScreenShot066

As our generated strongly typed Person object knows an Age is both required and an integer, the data grid automatically picks up the validation notifications and displays them to the user.

ScreenShot067

When we update the data with valid info and click save our success message shows us our service call encountered no errors.

ScreenShot068

The source code for this project can be downloaded here:

http://stevenhollidge.com/blog-source-code/WcfRiaWithPocos-part2.zip

Thursday, 19 May 2011

Threading Locks and Synchronisation

Locks

The usual pattern for locking a piece of code so that other threads cannot enter at the same time is:


Which internally is the same as using the Monitor keyword:


Synchronisation

To cause a thread to block you can use the AutoResetEvent. The WaitOne method will block until the Set method is called:

Or you can use the Monitor class with a lock to achieve the same result:

Sunday, 17 April 2011

Introduction to Gibraltar for C# Log Analysis

Gibraltar monitors .Net application to record errors, events, trace statements and performance metrics then lets you effortlessly analyse the results.

gibrgib

There are three parts to Gibraltar:

Agent

The Agent is a DLL (Gibraltar.Agent.Dll) referenced by your .Net application that records the errors, events and metrics of your app.  It’s really simple to add to your project and can be configured automatically via a wizard or manually by editing an Xml file or programmatically via the Gibraltar API.

Hub

The Hub serves as a delivery mechanism for transporting the results from each Agent to the Analyst.

Analyst

The Analyst is a GUI application that lets developers view and analyse results through drilldowns, filtering and charts.

Some examples of using the Analyst can be seen here:

Analyst-example-1

It’s very simple to drilldown to specific targetted areas using grouping and filtering by categories, namespace/class hierarchies, thread id, severity, etc.

Analyst-example-2

You can see here that the Analyst shows you the source code that has generated the message.

I highly recommend the following video from Gibraltar Software that gives and excellent overview of Gibraltar.  The video also gives an example of teaming the software up with PostSharp, the popular AOP (Aspect Oriented Programming) framework:

Using PostSharp with Gibraltar

To download trial versions of Gibraltar and PostSharp please visit the official websites:

http://www.gibraltarsoftware.com/

http://www.sharpcrafters.com/postsharp

Monday, 21 March 2011

How to build a Dynamic Data website in 60 seconds

Do you want to be able to create a website to edit the records in your database without having to write any code?  Well with Dynamic Data and .Net it’s easy.

This step by step guide will automagically create your website so quickly that within a minute from now you’ll be able to create, read, update and delete the records in your database tables via your own web application.

For this demo I am going to use our old friend the Northwind database, a SQL Server sample database from Microsoft.

northwind

Step 1:  Open Visual Studio 2010 and create a New Project from the Web template “ASP.NET Dynamic Data Entities Web Application”

VS-add-project

Step 2: Right click on your project and select Add > New item...  Within the Data category choose “ADO.NET Entity Data Model”

add-entity-model

Step 3: Select Generate from database and click Next

Generate-from-database

Step 4: Click on the “New Connection…” button to add a new connection to your database, enter your server and database name, click Test Connection to make sure your user has access.  Assuming the connection is fine you can click OK.

add-connection 

choose-data-connection

Step 5: Click Next :)  That step was easy eh?!  Just notice the Entity Data Model name has defaulted to NorthwindEntities.  This is important because we’ll be referencing this object shortly,.

Step 6:  Choose the objects you want your website to interact with.  For this example I’m going to tick the tables box to select all tables.  I’ll manually remove the system table named sysdiagrams as we don’t need to be interacting with these tables.  Now click Finish.

choose-your-database-objects 

You can now see your tables within the designer view of your Entity model.

entity-model 

Step 7: For the last step you need to update the Global.cs file to reference your new Entity Model.  You do this by scrolling down to the “public static void RegisterRoutes(RouteCollection routes)” method, uncomment out the line highlighted below and enter the name of your EntityModel.

global

Change the line from this:


To this:


And that’s it - all done!  Your new website is now ready for you to use.  Just press F5, (you’ll be asked if you want to enable debugging click Ok) and then your new web application will appear.


debugging-not-enabled


The home page displays all your tables, ready for you to interact with.


 dynamic-data-site-home


Click on one of the tables, I’ve selected Categories, and the site will display a page containig the data, links for insert, edit and deleting the records.  You’ll also get a link to “View” referenced data like in Products in the example below.


dynamic-data-site-categories 


The “Insert” page for Categories:


dynamic-data-site-categories-add


The “Edit” page for Categories:


dynamic-data-site-categories-edit


The “View” page for for our referenced Products table takes use to the Products page.


dynamic-data-site-categories-products   




If you want to restrict which tables are displayed within the application go back to the line you edited within the Global.asax.cs file and set the ScaffoldAllTables = false;


Now create a new partial class for each table you want to edit and add the attribute [ScaffoldTable(True)] to the class, where the claasname matches the database table name.  For example, I’ve created one file called ScaffoldTables.cs and added two partial classes for the Category and Customer table in Northwind.


scaffold-tables


Now when you run your web application you’ll only be shown the tables you explicitly added partial classes for.


scaffold-tables-web


I hope you find this quick introduction to Dynamic Data useful - happy coding!


Source code:  DynamicDataDemo.zip