Thursday 28 August 2014

Command line Windows Update

Update: If you are behind a proxy, here is some additional code to add right after creating the update session:
'updateSession.WebProxy.AutoDetect = true 'try this first. It doesn't work so well in some environments if no authentication windows appears (*cough* Windows 8 *cough*)

strProxy = "proxy name or address:proxy port" 'ex: 1234:999
strProxyUser = "your username"
strProxyPass = "your password"

updateSession.WebProxy.Address=strProxy
updateSession.WebProxy.UserName=strProxyUser
updateSession.WebProxy.SetPassword(strProxyPass)

I am working behind a "secured" web proxy that sometimes skips a beat. As a result there are days in which I cannot install Window Updates, the normal Windows update application just fails (with Error Code: 0x80246002) and I am left angry and powerless. Well, there are options. First of all, none of the "solutions" offered by Microsoft seem to work. The most promising one (which may apply to you, but it did not apply to me) was that you may have corrupted files in the Download folder for Windows updates. As a result you need to:
  • Stop the Windows Update service issuing the command line command: net stop wuauserv or by going to Control Panel, Services and manually stopping it.
  • Go to the download folder parent found at %systemroot%\SoftwareDistribution (cd %systemroot%\SoftwareDistribution) and rename the Download folder (ren Download Download.old)
  • Start the Windows Update service issuing the command line command: net start wuauserv or by going to Control Panel, Services and manually starting it.

So my solution was to use a script that downloads and installs the Windows updates from the command line and I found this link: Searching, Downloading, and Installing Updates that pretty much provided the solution I was looking for. There are two issues with the script. The first is that it prompts you to accept any EULA that the updates may present. The second is that it downloads all updates, regardless of severity. So I am publishing here the script that I am using who fixes these two problems: EULA is automatically accepted and only Important and Critical updates are downloaded and installed:
Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "Siderite :) Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"

For I = 0 To searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
WScript.Echo "There are no applicable updates."
WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"

Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")

For I = 0 to searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)

addThisUpdate = false
If update.InstallationBehavior.CanRequestUserInput = true Then
WScript.Echo I + 1 & "> skipping: " & update.Title & _
" because it requires user input"
Else
If update.EulaAccepted = false Then
update.AcceptEula()
WScript.Echo I + 1 & "> Accept EULA " & update.Title
addThisUpdate = true
'WScript.Echo I + 1 & "> note: " & update.Title & " has a license agreement that must be accepted:"
'WScript.Echo update.EulaText
'WScript.Echo "Do you accept this license agreement? (Y/N)"
'strInput = WScript.StdIn.Readline
'WScript.Echo
'If (strInput = "Y" or strInput = "y") Then
' update.AcceptEula()
' addThisUpdate = true
'Else
' WScript.Echo I + 1 & "> skipping: " & update.Title & _
' " because the license agreement was declined"
'End If
Else
addThisUpdate = true
End If
End If

If addThisUpdate AND (update.MsrcSeverity = "Important" OR update.MsrcSeverity = "Critical") Then
'wscript.echo ("This item is " & update.MsrcSeverity & " and will be processed!")
Else
'comment these lines to make it download everything
wscript.echo (update.Title & " has severity [" & update.MsrcSeverity & "] and will NOT be processed!")
addThisUpdate=false
End If

If addThisUpdate = true Then
wscript.echo(I + 1 & "> adding: (" & update.MsrcSeverity & ") " & update.Title)
updatesToDownload.Add(update)
End If
Next

If updatesToDownload.Count = 0 Then
WScript.Echo "All applicable updates were skipped."
WScript.Quit
End If

WScript.Echo vbCRLF & "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")

rebootMayBeRequired = false

WScript.Echo vbCRLF & "Successfully downloaded updates:"

For I = 0 To searchResult.Updates.Count-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
WScript.Echo I + 1 & "> " & update.Title
updatesToInstall.Add(update)
If update.InstallationBehavior.RebootBehavior > 0 Then
rebootMayBeRequired = true
End If
End If
Next

If updatesToInstall.Count = 0 Then
WScript.Echo "No updates were successfully downloaded."
WScript.Quit
End If

If rebootMayBeRequired = true Then
WScript.Echo vbCRLF & "These updates may require a reboot."
End If

WScript.Echo vbCRLF & "Would you like to install updates now? (Y/N)"
strInput = WScript.StdIn.Readline
WScript.Echo

If (strInput = "Y" or strInput = "y") Then
WScript.Echo "Installing updates..."
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
Set installationResult = installer.Install()

'Output results of install
WScript.Echo "Installation Result: " & _
installationResult.ResultCode
WScript.Echo "Reboot Required: " & _
installationResult.RebootRequired & vbCRLF
WScript.Echo "Listing of updates installed " & _
"and individual installation results:"

For I = 0 to updatesToInstall.Count - 1
WScript.Echo I + 1 & "> " & _
updatesToInstall.Item(i).Title & _
": " & installationResult.GetUpdateResult(i).ResultCode
Next
End If
WScript.StdIn.Readline()

Save the code above in a file called Update.vbs and then creating a batch file that looks like this:
@ECHO OFF
start "Command line Windows update" cscript Update.vbs

Run the script and you will get the .vbs executed in a command line window that will also wait for pressing Enter at the end of execution so you can see the result.

For other solutions that are more system admin oriented, follow this link which provides you with a lot of possibilities, some in PowerShell, for example.

Also, I didn't find a way to install the updates without the Windows annoyance that asks me to reboot the computer popping up. If you know how to do that, I would be grateful.

Monday 18 August 2014

I was mentioned on TMRO (formerly known as Spacevidcast)

I have been watching this weekly space show made by a husband and wife couple working for SpaceX. Initially called Spacevidcast, now it is called TMRO (pronounced Tomorrow). It is a great show, great quality, nice humor and, more than anything, a comprehensive video report on weekly events in space exploration, commercial or otherwise. If you are even remotely interested in space, you should subscribe. And they have been doing it all from their own resources and crowdfunding for seven years! You gotta love that.

But the selfish reason I am blogging about them is that I got mentioned in the TMRO show! Click here to see how they are trying and even succeeding to pronounce my Internet nom de guerre. The effort is appreciated.


Thursday 14 August 2014

Google Hangouts hides its icon in the traybar

Because of idiotic firewall rules at my workplace I am forced to use Hangouts rather than Yahoo Messenger as an instant messenger. I am not going to rant here about which one is best, enough to say that most of my friends are on YM and being on Hangouts doesn't help. Hangouts has many annoyances for me, like its propensity to freeze when you lose Internet connection often or the lack of features that YM had. In fact I was so annoyed that I planned to do my own professional messenger to rule them all. But that's another story.

I am writing this post because of a behaviour of the Google Hangouts instant messenger (which, to be fair, is only a Chrome extension), mainly that after a while, the green traybar icon of the messenger goes in the "hidden icons" group. I have to customize it every day, sometimes twice, as it seems to reset this behavior after a period of use, not just on restarts. There is a Google product forum that discusses this here: System tray icon resets every time Chrome is started where you also see a few comments from your truly.

I immediately wanted to create a script or a C# program to fix this, but at first I just searched for a solution on the web and I found TrayManager, a C# app that does what the "Customize..." tray link does and more. One of the best features is a command line! So here is what you do after downloading the software and installing it somewhere: TrayManager.exe -t "Hangouts" 2. Now, probably that doesn't solve the problem long term. It is just as you would go into the Customize... link, but it's faster. Also, it has no side effects if run multiple times, so you can use Task Scheduler to run it periodically. Yatta!

Tuesday 12 August 2014

How to Catch a Comet - a BBC Four documentary about the Rosetta comet

Comet 67P picture and trajectory BBC's show The Sky at Night did a coverage of the Rosetta mission, called How to Catch a Comet. It is the standard popular science show, with a lot of fake enthusiasm from the reporters and simple language and explanations, but for people who read this blog entry and wonder what the hell Rosetta is, it does the job. The fat black reporter is really annoying, and not because she's black, but because she feels completely fake whenever she says anything. Other than that the show is decent.

You get to learn about comet 67P, the Rosetta probe features and mission, walk around ESA, talk to scientists and even see a how-to about photographing comets - it was funny to see a shooting star in the night sky while the guy was preparing his camera and talking in the video. Of course, for me the show stopped just when it was getting interesting. I know you can't do much in 29 minutes, but still. I hope they do follow-up shows on Rosetta and I can't wait for November when the lander module will try to grapple the comet and land.

Just in case I've stirred your interest, here are some links that can cover the subject in a lot more detail:
ESA Euronews: Comet Hunters: Rosetta's race to map 67P - 8 minutes and a half of Euronews report from 11 August.
ESAHangout: How do we journey to a comet? - Google Hangout from ESA explaining the mission. It's one hour long and it dates from the 26th of June. Many other videos about Rosetta can be found on the ESA channel.
A playlist about Rosetta from Mars Underground. The most interesting is this video, published on 11 Aug 2014. It lasts an hour and a half and shows the first mission images and science results.
Comets - A wonder to Behold, A continuing Stream of Surprises - The Beauty and the Danger, not about Rosetta, but one hour and a half about comets. The documentary is trying to justify a controversial theory about the electric nature of comets. It is well done with a lot of proof, but I know too little about the theory so I can't recommend it. Interesting, though.

Monday 11 August 2014

Ammonia from water and air!

In this post I will try to bring to your attention something that will probably change the world significantly. In 1909, German chemist Fritz Haber successfully fixed atmospheric nitrogen as ammonia in a laboratory and five years later a research team from BASF, led by Carl Bosch, developed the first industrial-scale application of the Haber process, sometimes called the Haber-Bosch process. Ammonia is extremely useful for many applications, the least of each is gunpowder and explosives and one of the most important is fertilizers. Without the Haber-Bosch process we probably wouldn't have the Green Revolution.

So today I found this article in Ars Technica that says that Researchers have developed a method to produce ammonia starting only with air and water. Not only is it more energy efficient than the century-old Haber-Bosch process that’s currently in use, but it’s also greener. The article goes on to say that almost 2% of the entire world energy is used to create ammonia; making the process more efficient is great! But I have to say that this is probably just the tip of the iceberg. Lowering the production cost of such a basic article will ripple throughout many industries, lead to innovation or the possibility to use some old innovation that until now was unfeasible.

I am not a chemist, so my enthusiasm may be way off-base, but my gut feeling is that this improvement on a century old process will have a great and positive effect.

Friday 8 August 2014

Sending complex objects to T-SQL using the XML type

I have been working on a REST API lately and, while using Entity Framework or some other similar framework to abstract the database is certainly possible, I wanted to control every aspect of the implementation. I know, reinventing wheels, but this is how one learns. One of the most annoying bits was trying to translate some complex object from JSON to the (two dimensional) database relational tables. This post will explore my attempts and the solutions I have found.

My first attempt was straightforward: just send all types as DataTables, with some extra property to define identity and parent entity. This relies on the Microsoft Server SQL mechanism that allows sending of table variables to stored procedures. But this approach has several downsides. One of them is that in order to send a datatable to SQL you need... DataTables. As I have pointed out in several blog posts, the DataTable object is slow, and sometimes downright buggy. Even if I didn't care about performance that much, in order for SQL to receive the content of the DataTable one must create corresponding User Defined Types on the database side. Working with UDTs is very difficult for several reasons: you cannot alter a UDT (unless employing some SQL voodoo that changes system tables), you can only drop it and recreate it. This does not work if you use the UDT anywhere, so a lot of renaming needs to be done. Even if you automate the process, it's still very annoying. Then the UDT definition has to be an exact duplicate of the DataTable definition. Move some columns around and it fails. Debugging is also made difficult by the fact that the SQL profiler does not see the content of table variables when sending them to the server.

Long story short, I was looking for alternatives and I found XML. Now, you might think that this leads to a simple, and maybe even obvious, solution. But it's not that easy. Imagine that you send a list of objects in an XML. Each object is represented by an XML element and each property by a child element. In order to get the value of a property you need to do iterate through all the nodes, for each node find the properties, for each property find the one element that defines it, then get the attribute value or content of the property, all while making sure you select everything in a table. It's not that easy.

The solution I found, which simplifies the SQL code (and hopefully brings some well needed performance to the table) is to serialize the objects in a way that makes the selection simple enough. Here is an example: I have a Configuration object with an Id and a Name that also has a property called Servers, containing Server objects having an Id and a Url. Here is an example of XML serialization from the DataContractSerializer:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>1</Id>
<Name>Test Config</Name>
<Servers>
<Server>
<Id>1</Id>
<Url>http://some.url</Url>
</Server>
<Server>
<Id>2</Id>
<Url>http://some.other.url</Url>
</Server>
</Servers>
</Configuration>
The SQL code to get the information from an XML variable with this content would look like this:
DECLARE @Xml XML='<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>1</Id>
<Name>Test Config</Name>
<Servers>
<Server>
<Id>1</Id>
<Url>http://some.url</Url>
</Server>
<Server>
<Id>2</Id>
<Url>http://some.other.url</Url>
</Server>
</Servers>
</Configuration>'


;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('(Id/text())[1]','INT') as Id,
T.Item.value('(Name/text())[1]','NVARCHAR(100)') as Name
FROM @Xml.nodes('//Configuration') as T(Item)

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('(Id/text())[1]','INT') as Id,
T.Item.value('(Url/text())[1]','NVARCHAR(100)') as Url
FROM @Xml.nodes('//Configuration/Servers/Server') as T(Item)

This works, but look at that code. In my case, the situation was worse, the object I was using was a wrapper which implemented IDictionary<string,object> and, even if it did implement ISerializable, both XmlSerializer and DataContractSerializer use the dictionary as their data and in the end I get ugly key elements and value elements that are even harder to get to and, I suppose, more inefficient to parse. Therefore I found the solution in IXmlSerializable, (yet) another serialization interface used exclusively by XML serializer classes. If every simple value would be saved as an attribute and every complex object in an element, then this could be the SQL code:
DECLARE @Xml XML='<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Config Id="1" Name="Test Config">
<Servers>
<List>
<Server Id="1" Url="http://some.url" />
<Server Id="2" Url="http://some.other.url" />
</List>
</Servers>
</Config>
</Configuration>'


;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('@Id','INT') as Id,
T.Item.value('@Name','NVARCHAR(100)') as Name
FROM @Xml.nodes('//Configuration/Config') as T(Item)

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('@Id','INT') as Id,
T.Item.value('@Url','NVARCHAR(100)') as Url
FROM @Xml.nodes('//Configuration/Config/Servers/List/Server') as T(Item)

Much easier to read and hopefully to parse.

I am not going to write here about the actual implementation of IXmlSerializable. There are plenty of tutorials on the Internet about that. It's not pretty, :) but not too difficult, either.

What was the purpose of this exercise? Now I can send a complex object to SQL in a single query, making inserts and updates simple and not requiring at a call for each instance of each type of complex object. Now, is it fast? I have no idea. Certainly if performance is needed, perhaps the UDT/DataTable approach is faster. However you will have to define a type for each type that you send as a DataTable to a stored procedure. An alternative can be a binary serializer and a CLR SQL function that translates it into tables. However, in my project I need to easily implement very custom API methods and to control every aspect, including tracing and profiling the various SQL calls. I believe the customized IXmlSerializable/XML in SQL approach is a reasonable one.

As always, I hope this helps someone.

Monday 4 August 2014

Efficiently implementing generic getters and setters

I am going to tell you about how I worked on an object that can wrap any object, serialize it, deserialize it, send it to a database, all efficiently and generically. But first, let me start with the beginning: you need a way to efficiently set/get values of properties in objects of different types. That's where TypeCache comes in. I am sure not everything is perfect with the class, but hopefully it will put you on the right track.

I will start with some of the code, the class that does everything. Something will be missing, though.
/// <summary>
/// It caches the property setters and getters for the public properties of a type
/// </summary>
public class TypeCache
{
private static ConcurrentDictionary<Type, TypeCache> _typeCacheDict = new ConcurrentDictionary<Type, TypeCache>();

public static TypeCache Get(Type type)
{
TypeCache cache;
if (!_typeCacheDict.TryGetValue(type, out cache))
{
cache = new TypeCache(type);
_typeCacheDict[type] = cache;
}
return cache;
}

private TypeCache(Type type)
{
Type = type;
Setters = new ConcurrentDictionary<string, Action<object, object>>();
Getters = new ConcurrentDictionary<string, Func<object, object>>();
var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
Properties = new ConcurrentDictionary<string, PropertyInfo>();
foreach (var prop in props)
{
if (prop.CanRead)
{
var objGetter = prop.GetValueGetter();
Getters[prop.Name] = objGetter.Compile();
}
if (prop.CanWrite)
{
var objSetter = prop.GetValueSetter();
Setters[prop.Name] = objSetter.Compile();
}
Properties[prop.Name] = prop;
}
}

public Type Type { get; private set; }
public ConcurrentDictionary<string, Action<object, object>> Setters { get; private set; }
public ConcurrentDictionary<string, Func<object, object>> Getters { get; private set; }
public ConcurrentDictionary<string, PropertyInfo> Properties { get; private set; }
}

public static class TypeCacheExtensions
{
/// <summary>
/// Set the value of a property by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Set<T>(this TypeCache cache, object item, string key, T value)
{
if (cache == null || item == null) return;
Action<object, object> setter;
if (!cache.Setters.TryGetValue(key, out setter)) return;
setter(item, (object)value);
}

/// <summary>
/// Get the value of a property by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Get<T>(this TypeCache cache, object item, string key)
{
if (cache == null || item == null) return default(T);
Func<object, object> getter;
if (!cache.Getters.TryGetValue(key, out getter)) return default(T);
return (T)getter(item);
}

/// <summary>
/// Set the value for a property to default by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
public static void Delete(this TypeCache cache, object item, string key)
{
if (cache == null || item == null) return;
Action<object, object> setter;
if (!cache.Setters.TryGetValue(key, out setter)) return;
var value = cache.Properties[key].PropertyType.GetDefaultValue();
setter(item, value);
}

/// <summary>
/// Set the values for all the public properties of a class to their default
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
public static void Clear(this TypeCache cache, object item)
{
if (cache == null || item == null) return;
Action<object, object> setter;
foreach (var pair in cache.Properties)
{
if (!cache.Setters.TryGetValue(pair.Key, out setter)) continue;
var value = pair.Value.PropertyType.GetDefaultValue();
setter(item, value);
}
}
}

(I used extension methods so that there would be no problems using a null value as the TypeCache) This class would be used something like this:
class Program
{
static void Main(string[] args)
{
var obj = new TestObject();
var cache = TypeCache.Get(obj.GetType());
Stopwatch sw = new Stopwatch();
sw.Start();
for (var i = 0; i < 100000; i++)
{
cache.Get<int>(obj, "TestProperty");
cache.Set<int>(obj, "TestProperty",i);
}
sw.Stop();
Console.WriteLine("Time: " + sw.Elapsed.TotalMilliseconds);
Console.ReadKey();
}
}

If you try to compile this, after adding all the namespaces required (System.Collections.Concurrent and System.Reflection), you will get an error, because you are missing the extension methods PropertyInfo.GetValueGetter and PropertyInfo.GetValueSetter. These should be returning Expressions that compiled get or set the value of an object. Here is the first attempt, using the normal PropertyInfo methods:
    public static class ReflectionExtensions
{
public static Expression<Func<object, object>> GetValueGetter(this PropertyInfo propertyInfo)
{
var getter=propertyInfo.GetGetMethod();
return (obj) => getter.Invoke(obj, new object[] { });
}

public static Expression<Action<object, object>> GetValueSetter(this PropertyInfo propertyInfo)
{
var setter = propertyInfo.GetSetMethod();
return (obj,val) => setter.Invoke(obj, new[] { val });
}

public static object GetDefaultValue(this Type type)
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
}
Wonderful thing! GetGet and GetSet :) Basically I am returning expressions that use reflection to get the getter/setter and then execute them. How long would the program with one million tries of get and set take? 1000 milliseconds. Could we improve on that?

Before .Net 4.0 the only solution to do that would have been to emit IL and compile it inside the code. Actually, even in 4.0 it is the most efficient option. But given my incompetence in that direction, I will give you the (slightly) easier to understand solution. Here we sacrifice a little speed for the readability of code:
    public static class ReflectionExtensions
{
/// <summary>
/// Get the expression of a value getter for a property. Compile the expression to execute or combine it with other expressions.
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static Expression<Func<object, object>> GetValueGetter(this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter(typeof(object), "i");
var convertObj = Expression.TypeAs(instance, propertyInfo.DeclaringType);
var property = Expression.Property(convertObj, propertyInfo);
var convert = Expression.Convert(property, typeof(object));
return (Expression<Func<object, object>>)Expression.Lambda(convert, instance);
}

/// <summary>
/// Get the expression of a value setter for a property. Compile the expression to execute or combine it with other expressions.
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static Expression<Action<object, object>> GetValueSetter(this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter(typeof(object), "i");
var argument = Expression.Parameter(typeof(object), "a");
var convertObj = Expression.TypeAs(instance, propertyInfo.DeclaringType);
var convert = Expression.Convert(argument, propertyInfo.PropertyType);
var setterCall = Expression.Call(convertObj,propertyInfo.GetSetMethod(),convert);
return (Expression<Action<object, object>>)Expression.Lambda(setterCall, instance, argument);
}

/// <summary>
/// Get the default value of a type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object GetDefaultValue(this Type type)
{
return type.IsValueType ? New.Instance(type) : null;
}
}

/// <summary>
/// Class used to get instances of a type
/// </summary>
public static class New
{
private static ConcurrentDictionary<Type, Func<object>> _dict = new ConcurrentDictionary<Type, Func<object>>();

public static object Instance(Type type)
{
Func<object> func;
if (!_dict.TryGetValue(type, out func))
{
func = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
_dict[type] = func;
}
return func();
}
}

The rest of the article will be about explaining what these extension methods are doing. How fast were they? 300ms! 3.3 times faster. How did we do that?

Well, first of all let's get the New class out of the way. In this simple version it just creates instances of a type that has a parameterless constructor. In the case that I had, using simple objects to transfer information, I only needed that. What is does is create a lambda expression that represents the parameterless constructor of a type, compiles it and caches it. Even a simple thing like this is faster than Activator.GetInstance(type). Not by much, about 10%, but still. Anyway, we are only using this to delete the value of a property (by setting it to its default value), which is not really in the scope of our test. However, being a simple expression build, it shows you the things to come.

Now for the GetValueGetter and GetValueSetter methods. I will humanly read you the GetValueGetter method. You can correlate it with the code quite easily. Basically it says this:
  • the expression has one parameter, of type object
  • we will attempt to safely convert it (as) into the declaring type (the object the property belongs to)
  • we will access a property of an object of the declaring type
  • which we then convert to object so that the resulting expression returns object not the specific type of the property
  • transform it all into a lambda expression and return it

The major difficulty, for me at least, was to grasp that there is no object (there is no spoon), but only a lambda expression that receives a parameter of type object and returns another object. The expression would be compiled and then applied on an actual instance.

And that's that. The object that does the serialization and transformation to SqlParameters and gets/sets the values of the wrapped object is more complicated and I will probably not write a blog entry about it, but think about the concept a little: an object that receives another object as the constructor and works like a dictionary. The keys and values of the dictionary are filled by the property names and values of the original object, while any change in the values of the dictionary will be set to the properties of the object. It makes it very easy to access objects generically, controlling what accessors do, but without the need for PostSharp or T4 templating, real time, programmatic. The task of serialization is taken by the ISerializable interface, which also uses a type of dictionary, meaning the object can be passed around from web services to C# code and then to SQL via SqlParameters.