Saturday, March 28, 2009

Biggest crap ever! Windows Vista

  • Frequent Bluescreens
  • Applications that stop working one day to the next
  • WLAN stops connecting to any network one day to the next even after replacing hardware
  • 5 reinstalls in 1 year with absolutely nothing but 3 games installed
  • Biggest mess in configuration dialogs ever
  • Tons of stupid questions
  • Inconsistencies in what files are in a directory

Thanks Microsoft for the biggest crap a computer has ever seen. Windows Vista.

Friday, March 13, 2009

Code Comments with svcutil

Unfortunately svcutil does not create comments from your XML annotations in your XSD or service WSDL. The more complex your data model gets the more the more you will miss this feature.

Well, you can be helped now.

Injecting Code into .NET Assemblies

What you need for this kind of surgery is:
1.) Reflector
2.) Reflexil (Reflector plugin)
3.) Your DLL or custom Assembly to call some code
4.) 10 Minutes time

The patient:
svcutil.exe (C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\svcutil.exe)

The enhancement:
svcutilImportCommentExtension

Primary Mission Goal:
Pimp svcutil to create nice code comments in my DataContracts from my annotations in XSD ( /dconly Option )
Secondary Mission Goal:
Pimp svcutil to create nice code comments in my WCF proxies from my WCF Service WSDL


1.) Copy the patient

2.) Start Reflector and
a.) Open the copy of svcutil.exe
b.) Open the DLL

3.) Right click on svcutil and select "Go to entry Point".

4.) Click on Main(string[] args) in "return (int) runtime.Run();"



5.) Click on ExecuteToolMode in "return this.ExecuteToolMode(toolMode, inputModule);"

6.) Click on ImportDataContracts in "this.ImportDataContracts(inputModule);"



7.) Click on ImportDataContracts in "module.ImportDataContracts();"

8.) Click on "Tools - Reflexil 0.9"

9.) Right click Line 7 "Call .... WriteConversionErrors" and select "Create New"
Choose
Opcode: ldstr
Operand Type: string
Operand: Calling svcutil extension....

Finish with selecting "Insert before selection"

10.) Right click Line 7 which now contains our "ldstr..." and select "Create New"
Choose
Opcode: Call
Operand Type: Method Reference
Operand: svcutilImportCommentExtension - svcutilImportCommentExtension.dll - ContractGenTest - CommentWriter - Hello(System.String) : System.Void



Finish with selecting "Insert after selection"

11.) Right click Line 8 which now contains our "call Hello(..)." and select "Create New"
Choose
Opcode: ldarg.0
Operand Type: None
Operand:

Finish with selecting "Insert after selection"

12.) Right click Line 9 which now contains our "ldarg.0" and select "Create New"
Choose
Opcode: ldfld
Operand Type: Field Reference
Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - schemas : System.Xml.XmlSchemaSet

13.) Right click Line 10 which now contains our "ldfld schemas" and select "Create New"
Choose
Opcode: ldarg.0
Operand Type: None
Operand:

Finish with selecting "Insert after selection"

14.) Right click Line 11 which now contains our "ldarg.0" and select "Create New"
Choose
Opcode: ldfld
Operand Type: Field Reference
Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - codeCompileUnit : System.CodeDom.CodeCompileUnit

Finish with selecting "Insert after selection"

15.) Right click Line 12 which now contains our "ldfld codeCompileUnit" and select "Create New"
Choose
Opcode: Call
Operand Type: Method Reference
Operand: svcutilImportCommentExtension - svcutilImportCommentExtension.dll - ContractGenTest - CommentWriter - WriteComments(System.Xml.Schema.SchemaSet,System.CodeDom.CodeCompileUnit)


Finish with selecting "Insert after selection"

This is how ImportDataContracts should look like now....

(Note that the Dissambler part should still display the unchanged code as we did not save it yet. This screenshot is taken from a already modified version...)

Now click on the symbol "svcutil.exe" in the reflector and select "Save as". You will now get a warning that svcutil is a signed assembly. Select "Remove Strong Name - Remove Strong Name and update referencing assemblies" and both windows. Now select "Save as" again and replace the file.

Now when you call svcutil you should get....



and have some nice comments in your code collected from all your

<xs:annotation>
<xs:documentation>.....</xs:documentation>


tags.


Sweet.

If you do the same for ImportServiceContracts() function you will be even able to create fully documented WCF proxies....

Just make sure you this time you call

CommentWriter.WriteComments(WsdlImporter importer, CodeCompileUnit compileUnit)

using the

Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - wsdlImporter: System.ServiceModel.Description

instead of the SchemaSet.

This is how ImportServiceContracts should look like after your surgery...



To bad comments don't get exported in WCF WSDL's? Well think again and get WCFExtras. A very nice WCF Extension to get XMLComments into WCF WSDL's as well as a working flat WSDL and support for Soap Headers.

Mission accomplished

Tuesday, March 3, 2009

Using Precompiled XSLT in .NET

Using XSLT in .NET

If you specify a file using

XSLCompiledTranform.Load(string filename)

the first thing XSLCompiledTranform is going to do is to emit/compile a set of unloadable DynamicMethods.

Although this is going really fast this overhead costs around 50 - 200ms. So if total time for your conversion is around that time, using precompiled XSLT's can really improve things quite a bit. We use this scenario to do high performance yet standard translations in WCF-Services.

To precompile your XSLT's you have 2 options:

The XSLTCompiler XSLTC.exe

First option is shipped with .NET 3.5 there and is a tool called XSLTC.exe which is basically a wrapper around the static XSLCompiledTransform.CompileToType() function. There is an excellent article by Anton Lapounov. It even gives you some tips to speed things further up using ngen.


I previously stated that XSLTC.exe can only compile one XSLT per assembly, but Andrew proved me wrong.
I tried:

XSLTC.exe *.xslt

which won't work but if you take a closer look at the options

xsltc [options] [/class:] [[/class:] ...]


XSLTC.exe /out:MyXSLT.dll a.xslt b.xslt c.xslt

should compile the XSLT's into a single assembly.

IronXSLT

Second option for this job is called IronXSLT. It is a Visual Studio plug in, that allows you to create a XSLT Library Project. You simply add your XSLT's to the project and after you build the solution they will be compiled into one DLL assembly. I installed it and it works fine with Visual Studio 2008 SP1. After you installed it you have a new project type called XSLT - XSLT Library. To configure it right click it in the solution explorer and select "Properties".

The problem. Unfortunately it seems that its creator Oleg Tkachenko has abandoned his project and no download is working anymore on the projects website.

I found one of the last working IronXSLT downloads here . I will try to contact Oleg in order to get the source published somewhere.

Performance Comparison

Attached to the already above mentioned article of Anton Lapounov there is some test code attached.

I ran a couple of test and got the following results:

using XSLTranform class

XSLTranform
.Load(string filename)


Load time: 35,86 ms
Load time: 1,533 ms
Load time: 1,450 ms
Load time: 1,441 ms
Load time: 1,504 ms
------------------------
Transform time: 51,94 ms
Transform time: 51,29 ms
Transform time: 49,46 ms
Transform time: 51,10 ms
Transform time: 48,77 ms

using XSLCompiledTranform loading tranformation from file

XSLCompiledTranform
.Load(string filename)


Load time: 51,86 ms

Load time: 2,640 ms
Load time: 2,556 ms
Load time: 2,704 ms
Load time: 2,644 ms
------------------------
Transform time: 56,89 ms
Transform time: 1,909 ms
Transform time: 1,680 ms
Transform time: 4,948 ms
Transform time: 1,427 ms

using XSLCompiledTranform loading XSLTC precompiled Transformation

XSLCompiledTranform.Load(type T)

Load time: 5,252 ms
Load time: 0,057 ms
Load time: 0,034 ms
Load time: 0,061 ms
Load time: 0,031 ms
------------------------
Transform time: 8,936 ms
Transform time: 2,302 ms
Transform time: 1,545 ms
Transform time: 1,457 ms
Transform time: 1,505 ms

using XSLCompiledTranform loading XSLTC precompiled and ngen'd Transformation

XSLCompiledTranform
.Load(type T)

Load time: 4,596 ms
Load time: 0,052 ms
Load time: 0,035 ms
Load time: 0,032 ms
Load time: 0,031 ms
------------------------
Transform time: 2,917 ms
Transform time: 2,446 ms
Transform time: 1,584 ms
Transform time: 1,457 ms
Transform time: 1,472 ms