Originally posted by Stuart Leeks on November 17th 2009 here.
Sometimes enumerations in .NET just don’t cut it. In the end they’re just a numeric value to which a piece of string metadata is attached to some of the values. Consider the following enumerations:
public enum OfficeLocationNames
{
London,
Edinburgh,
Redmond
}
public enum OfficeLocationCodes
{
LON,
EDI,
RED
}
What are these enumerations actually trying to say? I see these and think that there are three office locations, London, Edinburgh and Redmond, and each has a name and a three letter code, i.e. one type of thing, an office location, with two pieces of descriptive information about that thing, name and code. But using enumerations has forced us to define two things, when it’s really one. So what solutions are there?
Here’s one solution I like. I’m sure there are more, so feel free to suggest variations or completely different patterns in the comments. First off I define an interface, IOfficeLocation, to specify what makes up an office location:
public interface IOfficeLocation
{
string Code { get; }
string Name { get; }
double Latitude { get; }
double Longitude { get; }
}
I’ve taken the liberty of adding two more pieces of descriptive information to the office location too, latitude and longitude, just to prove the point. Note that this is immutable, i.e. you can’t change the values once they’ve been created.
Next, I define the OfficeLocations static class that will be our container for the three possible office locations. Inside this class I define the OfficeLocation class, which is a concrete implementation of the IOfficeLocation interface. Again, this class is immutable, and importantly it’s a private class to the OfficeLocations static class. This ensures that only the OfficeLocations class can construct instances of the OfficeLocation class. Finally I define the three office locations as static read-only fields of the OfficeLocations class, all using the IOfficeLocation interface, but constructed from the private OfficeLocation class.
public static class OfficeLocations
{
private class OfficeLocation : IOfficeLocation
{
private readonly string code;
public OfficeLocation(string code, string name, double latitude, double longitude)
{
this.code = code;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
}
private readonly string name;
private readonly double latitude;
private readonly double longitude;
public string Code
{
get { return code; }
}
public string Name
{
get { return name; }
}
public double Latitude
{
get { return latitude; }
}
public double Longitude
{
get { return longitude; }
}
}
public static readonly IOfficeLocation London = new OfficeLocation("LON", "London", 0d, 0d);
public static readonly IOfficeLocation Edinburgh = new OfficeLocation("EDI", "Edinburgh", 0d, 0d);
public static readonly IOfficeLocation Redmond = new OfficeLocation("MAN", "Manchester", 0d, 0d);
}
Using the OfficeLocations class is very similar to an enumeration, and because there is only ever one instance of London, Edinburgh and Redmond I can test for equality without needing to override the Equals method in the OfficeLocation class. I also like the fact that I cannot do more than or less than comparisons against office locations. It doesn’t make sense, to see if London is more than Edinburgh, does it? However, if it did I could implement IComparable on OfficeLocation and then I could make those comparisons.
public bool IsInUnitedKingdom(IOfficeLocation location)
{
return (location == OfficeLocations.London) || (location == OfficeLocations.Edinburgh);
}
So, as usual, comments are always welcome. Are there any variations on this theme? Or perhaps issues with this implementation? Surely not!
Originally posted by Rupert Benbrook on 4 February 2009
here.
On the 12th November 2009 our very own Josh Twist was awarded System Developer of the Year in the British Computer Society (BCS) and Computing magazine’s annual UK IT Industries awards. He fought his way past eight other finalists all of whom are professionals leading the way in the UK IT industry.
David Clarke, Chief Executive Officer of BCS, The Chartered Institute for IT, said: “This year’s Awards have been exceptional. I was delighted to take part in the judging day and witness firsthand the quality of the winners and medallists. To qualify as a finalist is terrific, to win is an absolutely fantastic achievement, and I offer my heartfelt congratulations to all those took part. They not only provide examples of best practice but also demonstrate how IT is enabling today’s information society from entertainment to healthcare, manufacturing to retail.”
Robin Booth, Publishing Director of Computing comments: “Computing is very proud to join forces with BCS to create such prestigious awards and celebrate UK innovation and best practice. Today IT drives business and this year’s deserving winners signify the importance and value that technology brings to business, society and the economy.”
The UK IT Industry Awards see a new venture between BCS and Computing, merging the BCS IT Industry Awards and the Computing Awards for Excellence to create one platform for the entire profession to celebrate best practice, innovation and excellence.
Congratulations Josh and thank you for all of your hard work from all the team.
Karl posted an interesting article recently INotifyPropertyChanged – How to remove the Property Name String Code Smell.
It'a nice implementation and the resulting code certainly looks a whole better. As Karl notes the biggest problem this approach faces is one with performance.
Notably, the proposed implementation is a lot slower when there are listeners wired up to the INotifyPropertyChanged plumbing.
The performance could be improved by caching the StackTrace based on an accompanying static key for each property, e.g.
private static readonly object _namePropertyKey = new object();
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged(_namePropertyKey);
}
}
However, this is probably just as prone to runtime errors in case somebody uses the wrong key with the wrong property.
With respect to the importance of performance then Karl is right to note that your users can only type so fast. But in some models and viewmodels, say containing a few hundred points that will be represented on a chart. That hit in performance could REALLY hurt.
My approach to this problem is to leave the smelly string where it is and automate the testing process using the Automatic Class Tester. This will automaticaly test that your properties are wired up appropriately and, if your class implements INotifyPropertyChanged it will also check that the appropriate PropertyChanged string name is fired.
Originally posted by Josh Twist on 2nd August 2009 here.
There are a bunch of IValueConverters that WPF probably should ship with... MultiplyConverter, AdditionConverter etc. Rather oddly it does ship with one: The BooleanToVisibilityConverter:
However, I'm not a huge fan of the implementation as it gives me little control over what true and false actually map to. For example, should false be Collapsed or Visible? What if I want to invert? For these reasons I always craft my own (I really must start a codeplex project at some point to keep all these converters). Here it is:
public class BoolToVisibilityConverter : MarkupExtension, IValueConverter
{
public BoolToVisibilityConverter()
{
TrueValue = Visibility.Visible;
FalseValue = Visibility.Collapsed;
}
public Visibility TrueValue { get; set; }
public Visibility FalseValue { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool val = System.Convert.ToBoolean(value);
return val ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return TrueValue.Equals(value) ? true : false;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
As discussed in a previous post, I've used my Converters as MarkupExtensions tip but I've also made the TrueValue and FalseValue completely configurable so there's a clear route for both inversion and choice between Collapsed and Hidden. In fact, you could even have True==Collapsed and False==Hidden if you liked - not sure what you'd use that for though. Note that we set sensible defaults in the constructor.
Here's how to use it:
Or, my preferred way:
Happy converting.
Originally posted by Josh Twist on 12 October 2009 here.
The ADC team is pleased to announce a new workshop.
For existing customers, if you would like take advantage of this service within your organisation, please contact your ADC. If you are not currently engaged with Application Development Consulting and are interested in this service, please contact ADCinfo@microsoft.com.
|
ADC Workshop |
Silverlight Development Ramp-up Workshop |
|
Date & Time |
Tuesday 24th and Wednesday 25th November 2009 |
|
Level |
200 |
|
Abstract |
Developers continue to face the challenge of writing applications that provide a compelling user experience whilst still being simple to maintain and deploy. Silverlight looks to address this challenge by bringing the rich user experience traditionally seen on the desktop to the web. Silverlight allows you to develop Rich Internet Applications using your .NET language of choice whilst providing a platform that works seamlessly cross-browser, cross-platform and cross-device. This workshop, hosted in our Reading offices, immerses .NET developers in Silverlight architecture, development, and deployment for 2 days, supervised by an ADC specialising in Silverlight. Particular focus will be given to developing Line of Business (LOB) applications using Silverlight. By the end of the session attendees will be armed with the key building blocks that will enable them to start developing Rich Internet Applications on the Silverlight platform. |
|
Intended Audience |
Anybody who is wondering if Silverlight is right for them, or considering using Silverlight for an upcoming project. Although not essential, attendees will benefit from a background in .NET development. |
Silverlight 3 supports a very cool 'deployment model' where you can run the Silverlight Application 'out-of-browser' (OOB) and kick it off from your start menu. It even works offline. This is the future, get to like it.
However, because the plug-in is no longer hosted in your page you lose all those juicy settings and, perhaps worst of all, you initialization parameters aren't available when the app runs OOB. This is frustrating because a lot of people pass in settings from their host web-application's web.config file using this very mechanism.
However, it only takes a little bit of code to work around this scenario by caching the initParams in isolated storage whenever the applicaiton is run in-browser. Here's some code that does just that:
private void Application_Startup(object sender, StartupEventArgs e)
{
var mp = new MainPage();
this.RootVisual = mp;
IDictionary<string, string> initParams = LoadInitParams(e);
// this just adds the init params to the MainPage for demo purposes only
foreach (var kv in initParams)
{
mp.LayoutRoot.Children.Add(new TextBlock { Text = kv.Key, FontStyle = FontStyles.Italic });
mp.LayoutRoot.Children.Add(new TextBlock { Text = kv.Value, Margin = new Thickness(5,0,0,0) });
}
}
private static IDictionary<string, string> LoadInitParams(StartupEventArgs e)
{
IDictionary<string, string> initParams;
// if running out of browser retrieve 'initParams' from cache
if (Application.Current.IsRunningOutOfBrowser)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("initParams.txt", System.IO.FileMode.Open, isf))
{
DataContractSerializer ser = new DataContractSerializer(typeof(Dictionary<string, string>));
initParams = (Dictionary<string, string>)ser.ReadObject(stream);
}
}
// otherwise write initParams to cache
else
{
initParams = e.InitParams;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("initParams.txt", System.IO.FileMode.Create, isf))
{
DataContractSerializer ser = new DataContractSerializer(typeof(Dictionary<string, string>));
ser.WriteObject(stream, initParams);
}
}
return initParams;
}
Easy peasy.
One recommendation here though is that you probably want a layer of indirection between Initalization Parameters and your 'silverlight configuration' in this case. The reason for this is the initParams will only get updated when you run the app in-browser. It's possible that your user will never run the app in-browser again. And even if the XAP gets updated your new parameters may never be seen, unless the app runs in-browser. So I'd recommend storing a static and constant URL in your initParameters that specifies an XML file (or web service) on the web server that contains your silverlight configuration.
You can then download this at will, even out-of-browser, whenever the network is available.
Originally posted by Josh Twist on 21 October 2009 here.
I wrote this largely to get the commands right in my own head – as a result, this is more a list of commands and some semblance of a sequence you can run them in. If you’ve never used these tools before this will get you out of the gate on WinDbg and the debugger extension SOS.dll.
If you’re looking for scenario's and walkthroughs I can’t stress enough that Tess Ferrandez is the go-to-guy for this and does a much better job; including a superb hands-on lab and crash walkthroughs on her Blog. All the commands I've listed are also documented here
At the end I’ve put three quick sequences together – looking at an web site, reviewing an exception and getting the IL for a particular method.
Symbols
Before beginning confirm you’ve setup your symbols and know where sos.dll is:
1) setup debug symbol and path – the easiest way is to configure a local store (for example c:\symbols) and use the public symbol server – create an environment variable _NT_SYMBOL_PATH and set it to SRV*c:\symbols*http://msdl.microsoft.com/download/symbols. If you have symbols in multiple places, add these locations separated by ‘;’. Note, if you’re using windows 7, windows symbols for your version are already installed to c:\windows\symbols.
If you set your symbol path to use the public server, or a symbols server, anything that requires you to resolve function names will cause the symbols to be downloaded – so some functions will take a few seconds to run, until you’ve built up your cache. WinDBG will set its status to busy while this happens.
2) If you’re debugging a 32 bit process or memory dump, copy the sos.dll from C:\Windows\Microsoft.NET\Framework\v2.0.50727 to the local directory for your windbg install (typically c:\program files[(x64)]\Debugging Tools for Windows). For 64 bit – use the framework64 version. It isn’t mandatory to copy the file here but makes .load a little quicker to run.
Attach to a running process
Pretty straight forwards – open windbg, hit F6, choose the process to connect to. You’ll be asked if you want to save the workspace – select no. Assuming we attached successfully, type ‘g’ – the debugger command for go. To break into the process again, hit ctrl-break. If all you have is a dump, open the dump from the file menu (open Crash Dump) – all of the following will work if a full user dump was taken (rather than a mini dump).
While the process is running, if any exceptions are being caught in the application, you’ll get ‘CLR exception - code e0434f4d (first chance)’ appearing in the console. See ‘Breaking When an Exception is thrown’ if you want to break on these.
If you get an error, typically ‘request not supported’. check you’re using the right ‘bitness’ of debugger for the process you’re connecting to or the right chip architecture for WinDbg (eg, IA64, x64, x86). You may also have to run windbg elevated.
Load SOS.Dll
Ctrl-Break into the process and load the SOS.dll by typing:
.Load sos.
If you didn’t copy sos into the same directory as windbg you’ll have to specify the full path. Note the command is prefixed with a ‘.’. You’ll get a message if sos can’t be found. If you get a x08004005 error when calling any of the following commands, make sure you’ve copied the right version (either x64 or x86) into your WinDbg directory.
Two other commands that will be of use here:
.sympath <path to symbols> // use to set or get the path to symbols.
.reload // force a reload of any symbols
If the symbols are wrong often you’ll get a warning telling you to check them, and you’ll also get hex instead of the missing function names when resolving call stacks.
Help!
SOS – it’s a debugger extension, so it’s commands are prefixed by ‘!’. Get started by calling:
!Help.
If you get the message ‘no export help found’ then sos hasn’t been loaded – just try and reload it using .reload sos.
What’s currently running?
When you break into the process you’ll end up sitting on a specific thread, which is identified by the number to the left of the command prompt. You can get the native call stack for the thread you’re currently on using the WinDbg command:
kb
Any hex in the output where you can see names and check you’ve got the right symbols. You can get the managed call stack for the current thread using an SOS extension:
!CLRStack
if there’s no managed call stack, well, you’ll get an error telling you this. Otherwise you’ll get the managed stack for the current thread. Use –p and –l to return parameter and local variable information. Use –a to return both.
Get a list of the managed threads in the process using:
!Threads
From this you can get a list of ThreadIds (the column on the far left is the id to use with the next commands) and whether or not they’re gc enabled (true means managed code, false means unsafe code), how many locks are open for that thread, it’s apartment model and finally any exceptions. This last column will also indicate which one of the threads is the Finalizer. If a thread holds an exception, you’ll find the address at the far right. In all fairness, it’s a good place to start any exploration.
To jump onto a different thread use the ‘~’ to identify you’re issuing a thread command, then the command. For example:
~<<thread id>> s // switch context to the thread id, eg ~27 s // switch to thread id 27
~* e kb // for all threads in the process, execute kb (dump the stack)
~* e !CLRStack // you probably get the idea, but for completeness: for all threads, evaluate !clrstack
WinDbg allows to to shell out – you might be interested in parsing some of the output using the windows Batch command - FIND. The following evaluates all threads to see what has the given function on their stack:
.shell -i - -ci "~* e !clrstack" FIND “<<FunctionName>>” for example .shell -i - -ci "~* e !clrstack" FIND “DoStuff”
Note the syntax above is sensitive, the dash after ‘–i’ is not a typo.
Finally – you can get all the objects associated with a set of calls:
!DumpStackObjects
this will, er, Dump all the objects within the bounds of the current stack. If, for example you’ve got a function calling out to Sql – this will help you get the Command object associated with that call stack if you’ve switched to that thread.
Allocations
Get the allocations for this program using:
!dumpheap –stat
This will dump the types of objects and their sizes on the heap. The stat switch says give me the summary. The 4 columns in the output are Method Table, number of objects, total size and type. Typically you’ll see System.String and System.Object high on this list. This will also tell you which generation each object is currently in.
To get a look at any of these objects, for example, System.String we can ask for the address of all objects of a given type over a fixed size. For example:
!dumpheap –type System.String –min 200
This will return a table of results detailing the address, method table and size of the object. Following this is a second table with Method Table Count of Objects, Total Size and the class name. Getting the address of an object from the previous command means you can start to examine it and it’s fields. If that object is a string, frequently you’ll get xml or other goodies buried within the process.
!dumpobj <<address>>
Often a command might just return a pointer to that object, for example the following command which looks for handles with no parents (an increasing number of these may indicate a leak).
!gchandleleaks
You can resolve the address of the object using the WinDbg macro ‘poi’ (pointer of int):
!dumpobject poi(<<handle>>)
Once you’ve got the address of an object you can resolve what else might be referencing that object using:
!gcroot <<address of object>>
Here you’re looking either for explicit object references, or if objects are rooted in the domain (statics). It might also be useful to understand what the allocation graph is – call:
!traverseheap <<outputfile.log>>
This will produce a log file output that can be presented in the clr profiler available here and is very useful for evaluating object graphs, and viewing how objects are laid out in each heap. be warned though – even for process of a couple of 100Mb this can often take over an hour.
Some Commands You’re Gonna love
!aspxpages is one of a great place to start if you’re looking at a web process. It checks the heap for any existing HttpContext objects and attempts to resolve which thread either executed or is executing it, whether it’s still currently running and if the request completed or not, and how long it took and what the return code was – it’s a very quick indicator of health. Occasionally it will report that a thread is no longer running (it’s Id will be XXX) – this may not be the case – so have a look at !threads to see if there is a suspect that may be running that request.
!dumpdatatables - returns a table of addresses of objects that are data tables, nextRowID (rowcount) and number of columns. No of Cells = nextRowId * RowCount.
!dumpobject {address of columns} will return the column names allowing you to establish how much data is in datatables.
Is there a large amount of concurrency in our process?
!syncblk
A high number under ‘monitor held’ may indicate a contention problem.
Note that the number of monitors held = 1 for the owner + 2*waiting number of waiting threads.
Check the help file, but .Net 2.0 uses thin locks, so you might also want to run i syncblk returns nothing.
!DumpHeap -thinlock
Breaking when an Exception is Thrown
There are two ways to do this – the easiest is to use the debugger break into the process, select Debug –> Event Filters –> Enable CLR Exception. When an exception is thrown the debugger will break into the process and sit you on the thread that has the Exception. Call !Threads to which will return the type of exception and it’s address, you can then call:
!PrintException <<address>>
The second way is to use !StopOnException – see the help for this. I might come back an update this.
Possible Sequence of Events for troubleshooting a hanging web app
!aspxpages – look for requests that didn’t complete – find their thread id.
~<<threadid>> s – switch to that thread.
!clrstack get the command at the top of the stack
!DumpStackObjects – get the objects associated with this call stack.
Possible sequence of commands for getting the exception text:
Set filters to enable CLR Exception
g (go)
!threads to get the exception address and type
!PrintException <<address>> to get the exception text and any inner exception.
Get the IL for a method on the stack
!dumpstack – lists the return address for each call. Take the return address the line above the function you’re interested in – for example, I’d like to see DoStuff() so take the return address 000007ff00170223:
Child-SP RetAddr Call Site
000000000016e4f8 000007fefdc71203 ntdll!NtDelayExecution+0xa
000000000016e500 000007fef8de176d KERNELBASE!SleepEx+0xb3
000000000016e5a0 000007fef89a77b5 mscorwks!DllCanUnloadNowInternal+0xf37d
000000000016e620 000007fef8f8f2f9 mscorwks!CreateApplicationContext+0x391
000000000016e680 000007ff00170223 mscorwks!ReOpenMetaDataWithMemory+0x1ff59
000000000016e830 000007ff00170195 ExceptionalApplication!ExceptionalApplication.Program.DoStuff()+0x53
000000000016e880 000007fef8b5d502 ExceptionalApplication!ExceptionalApplication.Program.Main(System.String[])+0x25
We want the method descriptor, so call
!IP2MD 000007ff00170223
which returns the Method Descriptor:
0:000> !ip2md 000007ff00170223
MethodDesc: 000007ff000239b8
Method Name: ExceptionalApplication.Program.DoStuff()
Class: 000007ff00162230
MethodTable: 000007ff00023a48
mdToken: 06000002
Module: 000007ff000233d0
IsJitted: yes
CodeAddr: 000007ff001701d0
Now you can call !dumpil <<MethodDescriptor>> which get’s you the IL:
!dumpil 000007ff000239b8
That’s it for this post – I’d definitely encourage you to look at Tess’s blog and DumpAnalysis.Org for more.
Enjoy!
Originally posted by Ryan Simpson on 8 October 2009 here.
I often get asked about the Naming Conventions I adhere to when writing code (C#, naturally).
It made sense to share these in a blog post so I can refer to it in future.
Some of these guidelines (well, one, the underscore on private fields) are negotiable as a matter of style. However, the public stuff is non-negotiable. For this is how .NET APIs should be and failure to adhere to this reflects badly on your code. No, no, no.
I thought a good way to present this would be an example class demonstrating the rules and some comments to help, so here goes:
using System;
// Namespaces are PascalCased
namespace TheJoyOfCode.NamingConventions
{
// Class names are PascalCased
public class ExampleClass
{
// All public fields, including constants are PascalCased
public static const string PiAsAString = "3.14";
// All private fields are camelCased with an underscore [1]
private readonly string _privateMember;
// All protected members are PascalCased
protected int ProtectedField = 12;
// All internal members are PascalCased
internal int InternalField = 13;
// All private methods are PascalCased
// *** NOTE - All parameters are camelCased
private double Multiply(double valueA, double valueB)
{
// local variables (scoped within a method) are camelCased (no underscore)
double result = valueA * valueB;
return result;
}
// All private Properties are PascalCased
// *** NOTE - Acronyms of 2 characters are UPPERCASED (e.g. UI, IO)
private string UIElementName { get; }
// All (public and private) properties are PascalCased
// *** NOTE - Acronyms longer than 2 characters are PascalCased (e.g. Html, Xml)
public int HtmlLength { get; set; }
// All public methods are PascalCased
// *** NOTE - All parameters are camelCased
// *** NOTE - Abbreviations are not treated as Acronyms (so _Id_entification is Id, not ID).
private void AlignObjectById(string id, Alignment alignment)
{
throw new NotImplementedException();
}
// Nested classes are PascalCased, even Private ones
private class NestedClass : IDisposable
{
public void Dispose()
{
throw new NotImplementedException();
}
}
}
// Enums are PascalCased and not plural (unless marked [Flags] in which case the name should be plural)
public enum Alignment
{
// Enum members are PascalCased
Top,
Bottom,
Left,
Right,
}
}
// [1] - Note the underscore isn't as recommended by StyleCop but since it applies only to private members, can be considered a matter of style and one that I personally use.
... and as for #region blocks I do not use regions and I don't negotiate with terrorists either.
Originally posted by Josh Twist on 8 September 2009 here.
Note – this article is based on Workflow 4 Beta 1, some things will change for Beta 2]
First off let me apologise for the length of this post. If you just want the code, skip to the bottom.
I don’t know about you but some words just don’t seem to make their way into my skull very easily, and correlation is one of them. It doesn’t matter how many times I say it in my head, even really slowly “c-o-r-r-e-l-a-t-i-o-n”, it still makes little sense.
So, in the spirit of sharing I thought I’d post what I know about correlation (in as far as it’s used in Workflow 4), and add in some code to cement the subject. First off though I thought I’d pop upstairs and look at the dictionary definition of correlation so here goes…
- Correlate – have a relationship or connection in which one thing affects or depends on another
- Correlation – connection, association, link, tie-in, tie-up, relationship, interrelationship, interdependence, interconnection, interaction
Thanks to the “Concise Oxford English Dictionary” for the former definition, and the “Oxford Paperback Thesaurus” for the latter. I hope they won’t mind me using their definitions here but if they do then someone else wrote this article, it wasn’t me, honest. As an aside, the “Concise OED” is a bit of an oxymoron if you see the physical size of it, but then again if you saw the full OED then you’d realise why this was called the concise version. Anyhow, enough English language for now!
So, how does correlation apply to a workflow then?
In the old days (well, pre Workflow 4), the common way to deal with a workflow instance was to know it’s instance ID which was a GUID. You had a workflow definition (i.e. some XML or a coded workflow), and when you created an instance of that workflow definition you had a workflow instance, and it was uniquely identifiable by its workflow instance ID. Simple.
If I wanted to do anything with a WF 3.x workflow, all I needed to know was it’s GUID and I could load it up, send messages to it, find it in the persistence database and so on. When I created a workflow instance I could optionally choose to assign my own GUID to it rather than having the system generate one for me. Life was good.
Now, lets say you were exposing a workflow as a service. You might have a few operations defined on that service and want to call these in whatever order suited you. You’ll define the first operation (which effectively kicks off the workflow), then subsequent operations will be called on the same instance of the workflow. In traditional programming you would maybe implement an interface something like the following…
[ServiceContract]
public interface IStudent
{
[OperationContract]
Guid EnrollStudent(string name, DateTime dob);
[OperationContract]
void AddExamResults(Guid studentId, string examName, int mark);
[OperationContract]
void Graduate(Guid studentId);
}
So the initial operation is EnrollStudent, and this returns the GUID of that student. Then some time later (days/weeks/months/years) you call AddExamResults and pass through the GUID in order to hook up the results with the right student. Finally at some point in the future the Graduate method is called (OK, maybe they flunked, but I’ll keep this simple). That’s all fairly easy to understand.
Now, if you were doing this in the workflow world things would be a little different. As of now (Workflow 4 Beta 1) you can’t do contract first workflow services, so you need to define the service contract within the workflow itself. Hopefully this limitation will be fixed by the time Beta 2 drops as I quite like contract first development these days.
In the service contract I defined above, the thing that identifies one student from another is the GUID returned from the initial EnrollStudent method. You can conceptually see that this key uniquely defines the student instance, and as long as you use that every time you want to ‘talk’ to that student instance then everything will be just fine.
Moving this service into the world of Workflow 4, we need some identifier that does the same job – it ties my requests to an instance of a workflow. Suppose I have two clients. The first calls EnrollStudent and this constructs an instance of my workflow and then returns the unique ID back to the caller. The second client can call EnrollStudent and will get a different ID and so now there will be two distinct workflow instances ‘running’ (they may be persisted to the database). Now when I get calls to the AddExamResults method I need to have these go to the appropriate workflow instance, and it’s correlation that does that. You don’t have to use GUIDs by the way – correlation in WF 4 allows you to define anything in the message as the correlation ‘handle’ – indeed you can use multiple items in the message as this handle which is very cool indeed. However for this example I’m using just one thing – a GUID.
So, finally, we have my definition of correlation as it applies to WF 4…
- Correlation – hooks messages to the workflows they are intended to reach
OK, so that’s a fairly poor definition and I don’t think the OED will be knocking on the door any time soon asking me to write for them, but hopefully you get the drift. Enough waffle though, lets get to some code. I’ll try to emulate the above service contract with WF 4, and use code to call that service.
Example – Defining the Workflow
In this example I’ll use code throughout – no XAML here folks! First off I need to define some data contracts for the arguments I’m passing in to the service methods. These mimic the parameters I’m passing to the service contract I outlined above…
[DataContract(Namespace = "http://www.morganskinner.com")]
public class EnrollStudentArgs
{
[DataMember]
public string Name { get; set; }
[DataMember]
public DateTime DateOfBirth { get; set; }
}
[DataContract(Namespace="http://www.morganskinner.com")]
public class AddExamResultsArgs
{
[DataMember]
public Guid StudentId { get; set; }
[DataMember]
public string ExamName { get; set; }
[DataMember]
public int Mark { get; set; }
}
So here I have two data contracts, one for the EnrollStudent operation and another for the AddExamResults operation. I need to do it this way as there’s no way to define multiple arguments to the Receive activity at present (this will be coming in Beta 2). You would currently need to do this for every method that takes more than a single argument, and whilst it’s a bit of a pain to have to do it that’s just the way it is for now. Well actually that’s a bit of a lie, there is an activity that will do this in Beta 1 but some changes are afoot for Beta 2 so I decided to show you this method which works for now.
Now we need a workflow. For this example I’ve chosen to build the workflow up as follows…
- An initial call to the EnrollStudent operation is made. This kicks off a new workflow and passes in the EnrollStudentArgs, consisting of the Name and DateOfBirth. This data is stored away within the workflow and a new GUID returned to the caller.
- The workflow then sits in a loop, waiting for a call to AddExamResults or a call to Graduate.
- If AddExamResults is called the data is output to the console
- If Graduate is called then the loop will exit and the workflow will complete
So, the overall workflow will be defined roughly as follows …

I’ve simplified it a bit as in the workflow there are actually many more activities, but hopefully this image conveys the main structure. I’ll build the code up step by step and explain what the bits are as I go along.
The first thing you’ll need to define are some variables and the initial Receive activity…
// Correlation handle to link the initial receive to the subsequent send
Variable<CorrelationHandle> enrollHandle = new Variable<CorrelationHandle>();
// Arguments received from the initial call to EnrollStudent
Variable<EnrollStudentArgs> enrollArgs = new Variable<EnrollStudentArgs>();
// The generated student Id
Variable<Guid> studentId = new Variable<Guid>();
// The namespace I'm using for all of the contracts etc
string ns = "http://www.morganskinner.com";
// This Receive activity kicks off the whole workflow
Receive receive = new Receive
{
CanCreateInstance = true,
CorrelatesWith = enrollHandle,
OperationName = "EnrollStudent",
ServiceContractName = XName.Get("IStudent", ns),
Value = new OutArgument<EnrollStudentArgs>(enrollArgs)
};
The CorrelationHandle is used to link the initial Receive and the subsequent SendReply together. Here I’ve also defined that the output value from the Receive should be stored away in a variable called enrollArgs. This variable will be globally scoped in the workflow (not that it needs to be – I could have defined it locally). I’ve also defined the studentId variable which will be used to store the unique Id created by the code. In a real solution you might just pass this Guid up from the client in the initial call – however that would have been less for me to demonstrate so I chose this method instead.
What we have defined is now nearly enough to so the first stage of the workflow – the initial Receive, the computation of the Guid and the SendReply to pass this Guid back to the client. I say nearly enough – there is one more thing we need to define up front but I’m going to gloss over that just for a moment and show the workflow up to this point…
return new Sequence
{
Variables = { enrollHandle, enrollArgs, studentId },
Activities =
{
receive,
new WriteLine { Text = "Assigning a unique GUID" },
new Assign<Guid>
{
To = new OutArgument<Guid>(studentId),
Value=new InArgument<Guid> (Guid.NewGuid())
},
new WriteLine { Text = new InArgument<string>(env=>
string.Format("GUID assigned was '{0}'", studentId.Get(env)))} ,
new SendReply
{
CorrelatesWith = enrollHandle,
Value = new InArgument<Guid>(studentId),
Request=receive,
AdditionalCorrelations = {{ "StudentIdQuery", operationHandle}},
CorrelationQuery = new CorrelationQuery
{
SelectAdditional = { studentIdOutputQuery }
}
}
}
}
So here I’ve defined a Sequence, and inside it are the receive activity we’ve defined earlier (this cannot be defined inline as the SendReply activity needs a reference to it). I’ve added some WriteLine activities so that we can see what the workflow is up to, and then defined the SendReply which is where it all gets a bit hectic.
The first three properties are fairly simple – CorrelatesWith defines a correlation handle link between the SendReply and the earlier Receive. The Value is simply what we want to return from the SendReply, and Request=receive links this SendReply with the earlier Request activity.
Now, if you remember the API I wanted to expose, I want to return a Guid from the initial call and use this same Guid on subsequent calls to identify the workflow instance that should process that call. That’s what the AdditionalCorrelations and CorrelationQuery properties are defined for. What I’m defining here is a query that will strip out the return value (i.e. the Guid) and associate this with another correlation handle – in this case the operationHandle.
So, in order to get this to compile I need to define the following before defining the Sequence shown above…
// The correlation handle defined after the initial receive/send pair
Variable<CorrelationHandle> operationHandle =
new Variable<CorrelationHandle>();
// Define a message context
XPathMessageContext messageContext = new XPathMessageContext();
messageContext.AddNamespace("local", ns);
// This query retrieves the output argument sent from the SendReply
MessageQuerySet studentIdOutputQuery = new MessageQuerySet
{
{ "StudentId", new XPathMessageQuery("sm:body()/ser:guid", messageContext) }
};
studentIdOutputQuery.Name = "StudentIdQuery";
Here I’ve defined the second correlation handle which will be used by the subsequent calls from the client (AddExamResults and Graduate). Then I’ve defined the message context which is used when defining the XPathMessageQuery objects that are used within the MessageQuerySet. I’ve defined a namespace prefix of “local” to refer to the namespace of my classes – we’ll need this again later in the example when retrieving values passed up from the client.
The MessageQuerySet object is used to define which bits are stripped from the message. In this case I have just one named value - “StudentId”, and this comes from the rather cryptic “sm:body()/ser:guid” XPath statement.
Now I’m not here to give you a lesson in XPath (and indeed you wouldn’t want one from me either!). If like me you think that XPath is akin to Voodoo Magic then I wouldn’t blame you.
The sm:body()/ser:guid implies that I’m looking throughout the ‘body’ of the message message for the ‘guid’ element from the ‘ser’ namespace and returning that. If you look at the actual data returned from the SendReply activity on the wire you would see something like the following (I captured this using the most excellent Fiddler2 tool)…
HTTP/1.1 200 OK
Content-Length: 203
Content-Type: text/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 04 Sep 2009 09:15:52 GMT
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
ddafc236-bec4-4745-bc6d-882f5ab3b051
</guid>
</s:Body>
</s:Envelope>
Here you can probably infer that we’re using ‘ser’ as a prefix for the Serialization namespace. It makes sense now, but I don’t much like magic prefixes – there are a bunch that are currently defined and used within the framework but are not currently documented. The documentaton should be sorted before WF 4 is released. If you’re interested these constants currently live on the XPathMessageContext class.
With all that defined we’re at the point where we should have a working Receive and SendReply (and of course a few other activities). Now it gets even more interesting.
Now I want to be able to call either the AddExamResults or the Graduate methods. These both pass the Guid along on the wire, but the former also passes other information too. In order to get to the right workflow instance I therefore need to extract the student Id from these calls and match it up to my earlier extract.
For this to work I’ll need another couple of message query sets…
// Retrieve the AddExamResultsArgs.StudentId passed to AddExamResults
MessageQuerySet studentIdQuery = new MessageQuerySet
{
{ "StudentId",
new XPathMessageQuery
("sm:body()/local:AddExamResultsArgs/local:StudentId",
messageContext) }
};
// And this one retrieves the value passed in to the Graduate method
MessageQuerySet graduateId = new MessageQuerySet
{
{ "StudentId", new XPathMessageQuery("sm:body()/ser:guid",
messageContext) }
};
The first message query set defines the XPath that will strip out the value of the StudentId property from the AddExamResultsArgs class. You’ll see that I’ve included the ‘local’ namespace prefix for both of these elements – it’s necessary, you won’t get anywhere without it.
The second message query set is used for the call to the Graduate method – here I’m just passing up a simple Guid and so need to strip just that Guid out of the message.
With a couple more variables defined (a boolean flag ‘finished’ and a variable to record the exam results) and two more receive activities we’re pretty much sorted…
// A variable used to hold the exam results just added
Variable<AddExamResultsArgs> examResultArgs =
new Variable<AddExamResultsArgs> ( ) ;
// Flag indicating that we're done
Variable<bool> finished = new Variable<bool> { Default = false };
// This recieve activity waits for the AddExamResults operation to be called
Receive receiveAdd = new Receive
{
OperationName = "AddExamResults",
ServiceContractName = XName.Get("IStudent", ns),
Value = new OutArgument<AddExamResultsArgs>(examResultArgs),
CorrelatesWith = operationHandle,
CorrelationQuery = new CorrelationQuery
{
Select = studentIdQuery
}
};
// And this activity waits for the Graduate operation to be called
Receive receiveStop = new Receive
{
OperationName = "Graduate",
ServiceContractName = XName.Get("IStudent", ns),
CorrelatesWith = operationHandle,
CorrelationQuery = new CorrelationQuery
{
Select = graduateId
},
Value = new OutArgument<Guid>(studentId)
};
In the above I’ve defined the other receive operations that my workflow will process. These again need to define their operation names and the name of the service contract to which they belong, and the only other tricky part is to define the correlation information. The AddExamResults operation is passed an argument of the AddExamResultsArgs type, so I need to strip out the AddExamResultsArgs.StudentId in order to correlate this message with the workflow. That’s just what the CorrelatesWith and CorrelationQuery are doing.
The second operation is just passed a Guid, so again I’m using a query that will retrieve the Guid passed to the Graduate operation.
Finally we get to the rest of the workflow…
return new Sequence
{
Variables = { enrollHandle, enrollArgs, studentId,
finished, operationHandle }, …
new While
{
Condition = ValueExpression.Create<bool>
( env => !finished.Get(env)),
Body = new Pick
{
Branches =
{
new PickBranch
{
Variables = {examResultArgs},
Trigger = receiveAdd,
Action = new WriteLine
{
Text = new InArgument<string>
(env=>string.Format
("Student '{0}' received '{2}' in '{1}'",
examResultArgs.Get(env).StudentId,
examResultArgs.Get(env).ExamName,
examResultArgs.Get(env).Mark)
)
}
},
new PickBranch
{
Trigger = receiveStop,
Action = new Sequence
{
Activities =
{
new Assign<bool>
{
To = new OutArgument<bool>(finished),
Value = new InArgument<bool>(true)
},
new WriteLine { Text = new InArgument<string>
(env=>string.Format("Student {0} Graduated",
studentId.Get(env)))}
}
}
}
}
}
}
}
Here I’ve defined the While loop, and within it a Pick activity which is similar to the Listen from WF 3.x. It has any number of child branches and will wait until one of the branches completes. In this case my branches are awaiting calls to WCF methods that I’ve defined by using Receive activities.
The first branch schedules the Receive activity that awaits a call on the AddExamResults method (and writes this data out to the console when it arrives), and the second branch waits for the Graduate call to be made and then sets the boolean ‘finished’ flag so that the workflow completes.
Example – Hosting the Workflow
Now we have a workflow we need to host it. Again I’m just using code rather than XAML to show you all the stuff you need.
// Define the base address for the service
// Note - use the full name of the PC rather than localhost here
string serviceBaseAddress = "http://dev10-vpc:8080/StudentService";
using (WorkflowServiceHost host =
new WorkflowServiceHost(GetStudentWorkflow(),
new Uri(serviceBaseAddress)))
{
// Define the service namespace
string ns = "http://www.morganskinner.com";
// And add the endpoint
host.AddServiceEndpoint(XName.Get("IStudent", ns),
new BasicHttpBinding(),
serviceBaseAddress);
ServiceMetadataBehavior smb =
host.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If none, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
// Setup properties of the service metadata behavior
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
// And set it
host.Description.Behaviors.Add(smb);
// Now open for business...
host.Open();
Console.WriteLine("StudentService is ready.");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Press <enter> to exit.");
Console.ResetColor();
Console.ReadLine();
host.Close();
}
Here I’ve defined the base address for the service to include the physical name of the machine I’m running on (dev10-vpc). If you use ‘localhost’ it will still work fine, however Fiddler2 won’t be able to pickup the traffic and display it for you.
I then construct a WorkflowServiceHost and add an appropriate endpoint to it. After that I’ve defined a metadata behaviour to permit clients to get the service metadata over Http (I could have added a metadata endpoint/binding instead). After that it’s just a case of opening the service and waiting for calls. You don’t need a .config file as all of the configuration has been done in code.
The last (and you’ll be glad to know, easiest!) part is creating the client.
Example – Creating a client
Construction of the client is simple. Add a service reference to the service (in my instance http://dev10-vpc/StudentService) and then call it. I’ve deliberately used different client instances here to prove that
static void Main(string[] args)
{
Console.WriteLine("Press a key to connect to the student service");
Console.ReadLine();
Guid studentId;
using (StudentService.StudentClient client = new StudentService.StudentClient())
{
studentId = client.EnrollStudent(
new EnrollStudentArgs { Name = "Fred Bloggs",
DateOfBirth = new DateTime(1980, 09, 04) }).Value;
Console.WriteLine("Student Id returned was '{0}'", g);
}
Console.WriteLine("Now press a key to call the service again");
Console.ReadLine();
ReportExamResults(studentId, "Maths", 90);
ReportExamResults(studentId, "English", 80);
ReportExamResults(studentId, "Woodwork", 100);
Console.WriteLine("Now press a key to call the Graduate operation");
Console.ReadLine();
// And finally graduate...
using (StudentService.StudentClient client = new StudentService.StudentClient())
{
client.Graduate(studentId);
}
}
private static void ReportExamResults(Guid studentId, string examName, int mark)
{
using (StudentService.StudentClient client = new StudentService.StudentClient())
{
client.AddExamResults(new AddExamResultsArgs
{
StudentId = studentId,
ExamName = examName,
Mark = mark
});
}
}
So there you have it. A worked example of correlation in Workflow 4 Beta 1. If you want to download the code for this sample please click here.
Originally posted by Morgan Skinner on 09 September 2009
here.
oI have been exploring different new features that come with the .NET 4, beyond the most popular ones like dynamic types and covariance; I was interested in performance enhancements. For this reason I am going to publish a couple of blog entries were I explore these different features.
Memory mapped files may sounds alien to the managed code developer but it has been around for years, what is more, it is so intrinsic in the OS that practically any communication model that wants to share data uses it behind the scenes.
So what is it? A memory mapped file allows you to reserve a region of address space and commit physical storage to a region (hmmm, sounds like virtual memory, isn’t it?) but the main difference is that the physical storage comes from a file that is already on the disk instead of the memory manager. I will say that it has two main purposes:
· It is ideal to access a data file on disk without performing file I/O operations and from buffering the file’s content. This works great when you deal with large data files.
· You can use memory mapped files to allow multiple processes running on the same machine to share data with each other.
The memory mapped file is the most efficient way for multiple processes on a single machine to communicate with each other. What is more, if we check other IPC methods we can see the following architecture:

Impressive, isn’t it? Now you have the power of this technology available on the System.IO namespace (instead of using the Pinvoke approach).
Now let’s quickly explore how it works. We have two types of memory mapped files models, one model is using a custom file, this can be any file that the application accesses it and the other one using the page file that we are going to share it with the memory manager (this is the model that most of the technologies above use).
Let’s explore the custom file model. The first thing that we need to do is to create a FileStream to the file that we are going to use, this can be an existing file or a new file (keep in mind that you should open this file as shared, otherwise no other process will be able to access it!). With the stream in place, we can now create the memory mapped file. Let’s see an example:
MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateFromFile(
new FileStream(@"C:\temp\Map.mp", FileMode.Create), // Any stream will do it
"MyMemMapFile", // Name
1024 * 1024, // Size in bytes
MemoryMappedFileAccess.ReadWrite); // Access type
I have use one of the simplest constructor, we define the stream to use and we provide a name. The object needs to know the size of it in bytes and the type of access that we need. This will create the memory mapped file but to start using it we will need a map view. We can create one using the following syntax:
MemoryMappedViewAccessor FileMapView = MemoryMapped.CreateViewAccessor();
This map covers the file from the first byte until the end. If we need now to write or read information from it we just call the map view methods with the correct offset.
int Number = 1234;
FileMapView.Write(0, Number);
FileMapView.Write<Container>(4, ref MyContainer);
We can see that we can write built in types or custom types with the generic version. The good thing about the memory mapped files is persistence, as soon as you close it the contents will be dumped on the disk, this is a great scenario for sharing cached information between applications.
Now if we want to read from it, the other process needs also to create a memory mapped file, we can use the other static initialize that opens an existing one or creates one if it does not exist.
MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateOrOpen(
new FileStream(@"C:\temp\Map.mp", FileMode.Create), // Any stream will do it
"MyMemMapFile", // Name
1024 * 1024, // Size in bytes
MemoryMappedFileAccess.ReadWrite); // Access type
Create the map view and read it:
using (MemoryMappedViewAccessor FileMap = MemoryMapped.CreateViewAccessor())
{
Container NewContainer = new Container();
FileMap.Read<Container>(4, out NewContainer);
}
That’s it, really simple isn’t it? Now, there is a small drawback with this approach and is related to the size of the memory mapped file. If you don’t know in advance you will need to create a large file
“just in case”, this can be a very large file with a lot of wasted space, it would be nice to have the ability to reserve the space instead of committing all of it, isn’t it?
In order to solve this issue you can use the page file, this has the advantage of allowing you to commit data on the fly but introduces another issue: you don’t own the file and the map will last until the last handle is destroyed. But think about it, for certain scenarios this is absolutely valid.
Now if we revisit the sample we will need to change some initialization parameters, for this particular one I will use the full constructor so I can introduce some other features that are also applicable to the custom files one.
MemoryMappedFileSecurity CustomSecurity = new MemoryMappedFileSecurity();
MemoryMappedFile PagedMemoryMapped = MemoryMappedFile.CreateNew(
@"Salvador", // Name
1024 * 1024, // Size
MemoryMappedFileAccess.ReadWrite, // Access type
MemoryMappedFileOptions.DelayAllocatePages, // Pseudo reserve/commit
CustomSecurity, // You can customize the security
HandleInheritability.Inheritable); // Inherit to child process
The memory mapped file security allows you to customize who or which process can have access to the resource, this can be quite important when you want to protect sensitive information and you don’t want other processes changing the file map. You can explore that object and see all the different settings that you can change. The reference is here. If we explore the construction of the memory mapped file we can see that there is no stream, we just name the resource. This will create an association between a section of the file based on the size and the map name, this is how both processes will access the file. Note as well that I am setting the property “DelayAllocatePages”, this implements a pseudo reserve/commit model where we will use the space once is needed. Finally, the other interesting parameter is the handle inheritance model, this will allow to share this resource with a child process if is required.
The access to the file uses the same syntax as the previous example, remember that if you close the memory mapped file this will be non accessible, this issue catches many developer.
Finally, another interesting area is the creation of multiple map views, these can work on the same memory mapped file accessing different areas of the files. This will allow you to properly protect the content and allowing you to synchronize the access.

You can do this defining different offsets and lengths when you create your map view.
MemoryMappedViewAccessor WriteMap = MemoryMapped.CreateViewAccessor(0, 1024,
MemoryMappedFileAccess.ReadWrite);
MemoryMappedViewAccessor ReadMap = MemoryMapped.CreateViewAccessor(1025, 1024,
MemoryMappedFileAccess.Read);
Now you can enjoy the power of this high performance data sharing model on your applications when you compile them with .NET 4.0! Note that this blog is based on beta 1 information, I will check the post once is released.
Originally posted by Salvador Alvarez Patuel on 10 June 2009 here.
How do you know when a page is being rendered as the result of a Server.Transfer, rather than a Response.Redirect or the user browsing directly to a page?
Actually it’s quite easy, assuming you’re using the default ASP.NET pipeline. In reality the “thing” that is responsible for handling an HTTP request is aptly called an HttpHandler – that is, they implement the IHttpHandler interface. Of course, you can create your own handlers if you just want to return a document, or your own manually rendered content, or similar.
But... the Page class also implements IHttpHandler, and ASP.NET therefore uses some cleverness to work out which page should be rendered, and then uses an instance of that Page-derived class as the HttpHandler.
So the bottom line is that if you do a Server.Transfer, the HttpHandler for the request will be the page that was originally being rendered... Therefore, the following code when executed from within a page will display “true” if a Server.Transfer has occurred;
TransferredLabel.Text = (Context.Handler != this).ToString();
Easy huh? Try the attached if you want to see this in action.
Originally posted by Simon Ince on 13 July 2009 here.
The very first talk I gave on .NET was on custom attributes – some time way back in late 2000 or early 2001. At the time I was espousing the benefits of using custom attributes to add on details of unit tests and bug fixes.
There have been many additions to .NET since then and I spied a couple of *really* cool new attributes in .NET 4 the other day so had to share them.
Enter (drum roll please) :-
- [Optional]
- [DefaultParameterValue]
Yay!
These are (I believe) a real productivity boost, and will make your code much easier to read. I bet you have some code like the following hanging around, don’t you…
public class Thingy
{
public Thingy()
: this("Default", -1)
{
}
public Thingy(string name)
: this(name, -1)
{
}
public Thingy(string name, int whatever)
{
_name = name;
_whatever = whatever;
}
// Other code...
private string _name;
private int _whatever;
}Now there’s nothing desperately wrong with this, although I feel
that 3 constructors is a bit ugly, I’d rather just have one. And
what if I want to change the default value for the ‘whatever’ value
– there are two places it’s used in the code above and I’d need to
update both which is a bit on the fragile side.
With these swanky new attributes I can have just the one constructor…
public class Thingy
{
public Thingy([Optional, DefaultParameterValue("Default")] string name,
[Optional, DefaultParameterValue(-1)]int whatever)
{
}
}
Now that’s a whole lot better if you ask me! My defaults are in one place, I have only one constructor rather than three (obviously this works on methods too), and Intellisense and the C# environment understand the [Optional] attribute and present the appropriate stuff to me.
Now as if that wasn’t enough we’ve updated C# to support this without even having to write attributes (thanks to Wes Haggard for pointing this out to me)…
public class Thingy
{
public Thingy(string name = "Default",
int whatever = -1)
{
}
}
Ooh, how cool is that? All in all I’m very happy with this little addition to .NET and C#.
Originally posted by Morgan Skinner on 05 August 2009 here.
Polymorphism in any OO language is taken as a given – and people would be shouting about it a lot if a language didn’t support it. However, when you’re writing a service interface with WCF you might also want to permit some form of polymorphic behaviour at runtime.
I was working with a customer yesterday and they wanted to be able to extend their system by adding in custom commands. A command might be something like “Print customer record” or “Add customer to ringback queue”. Some of these commands could be executed locally on the client PC, however others might need to be sent up to the server.
On the day I came up with some suggestions but had a nagging doubt that what I’d created wasn’t as great as it could be. Now after a sleep and some more thinking I’ve realised the error of my ways.
The typical Command pattern espoused by the GOF is to have a command object that knows how to execute itself. So in .NET you might dodge up an ICommand interface as follows :-
public interface ICommand
{
void Execute();
}
Then you would create subclasses of this command object and be off on your merry way. Note that you could also use the ICommand interface that already exists in the framework – I’m a great one for reusing what’s already available and not re-inventing the wheel. That’s not really appropriate in this instance as I my commands will be remotely executed.
Now, what I want to do is have some commands executed on the server – for the sake of argument I’ll call these ‘Remote commands’. So when the Execute() method is called, what I actually want to call is a WCF service (and pass up something representing the command to the server). To do that I need to be able to pass up an arbitrary collection of arguments. I could use a dictionary but a discrete class feels better :-
/// <summary>
/// The command arguments class allows arbitrary commands to be executed
/// </summary>
[DataContract]
public class CommandArguments
{
}
And then I might need a derived class for adding a customer to a ringback queue…
[DataContract]
public class CustomerRingbackArguments : CommandArguments
{
/// <summary>
/// The ID of the customer we'll ring back
/// </summary>
[DataMember]
public int CustomerId { get; set; }
/// <summary>
/// The duration until we call them back
/// </summary>
[DataMember]
public TimeSpan RingbackWhen { get; set; }
/// <summary>
/// The reason for the call
/// </summary>
[DataMember]
public string Reason { get; set; }
}
So far so good. Now I need a service that I can call and pass these command arguments to…
/// <summary>
/// This service executes commands
/// </summary>
[ServiceContract]
public interface ICommandService
{
/// <summary>
/// Execute the command associated with the passed arguments
/// </summary>
/// <param name="arguments">Arguments to be used by the command when executed</param>
[OperationContract]
void Execute(CommandArguments arguments);
} Execute(CommandArguments arguments);
}
If I were then to code up the service and try to use it I would not be able to pass up an instance of my CustomerRingbackArguments class as WCF doesn’t know about the type. Typically in this case you would attribute up the service as shown below…
[ServiceContract]
[ServiceKnownType(typeof(CommandArguments))]
public interface ICommandService
The problem here though is that for every new CommandArguments derived class I would need to update this service contract. With a couple of command argument derived classes then that wouldn’t be too much of an issue, but what if I were to have 20 or 200 different command argument classes? That would start to make my interface look pretty awful. There is a better way – and one I only noticed today.
The ServiceKnownType attribute can be used to indirectly specify which types are used by the service contract. So, rather than attributing up your code you can define a static method (even on another class) which returns all types that the service interface should use in (de)serialisation.
To use it just choose another overload of the ServiceKnownType attribute :-
[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(CommandServiceHelper))]
public interface ICommandService
Now when WCF is looking for types it will call the static method GetKnownTypes on my CommandServiceHelper class. This method is defined as follows :-
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
All you need to do here is round up all of your CommandArguments derived classes and you’re away! Now you will also need some mechanism to determine just what happens on the server when you get a given CommandArguments derived class sent up to the server, but that’s typically going to be a simple type based lookup mechanism (aka dictionary). I’ll leave that up to you to sort out.
It just goes to prove yet again that old adage – every problem in computing can be solved by another level of indirection.
Originally posted by Morgan Skinner on 5 August 2009 here.
I had a fun day debugging some ASP.NET plus jQuery this week, and came across something I’ve known is possible for some time, but that I’ve never actually needed to do... and that was to ensure a bit of JavaScript ran once an UpdatePanel had refreshed as part of a partial render.
It turns out that this is easy; all you need to do is register your JavaScript code block with some methods on ScriptManager, rather than using the standard ClientScript methods.
For example, consider the HTML below (I’ve omitted the rest of the page including the script manager, but it is in the download);
<asp:Button
ID="ClickMeButton"
runat="server"
Text="Click Me to Refresh Below"
onclick="ClickMeButton_Click" />
<div style="background: black; color: White">
<asp:UpdatePanel
ID="MyUpdatePanel"
runat="server"
UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger
ControlID="ClickMeButton"
EventName="Click" />
</Triggers>
<ContentTemplate>
Last Updated:
<asp:Label
ID="UpdateTimeLabel"
runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div id="log">
</div>
Here we have a simple UpdatePanel, with a button that triggers the async postback. There is also an empty DIV with ID “log”.
In the server-side code of the button click event I have some code that looks a bit like this;
string time = DateTime.Now.ToLongTimeString();
ScriptManager.RegisterStartupScript(
UpdateTimeLabel,
typeof(Label),
"UpdateTimeLabelStartupScript",
CreateScript(time),
true);
The CreateScript function simply returns some JavaScript in a string that reads as follows (the {0} is replace with a time);
$('#log').append('Last Server Run: {0}<br />');
This uses jQuery to append a message to our “log” DIV.
There is also an alternative though; using the Sys.Application.add_load method to attach a page load script function, or creating a pageLoad JavaScript function that is a synonym for the same thing. I’ve done the latter;
function pageLoad() {
$('#log').append('pageLoad executed<br />');
}
This function is executed when the page initially renders and when every partial render completes. This means the content of my “log” DIV rapidly starts to look like this;
pageLoad executed
Last Run: 21:56:12
pageLoad executed
Last Run: 21:56:14
pageLoad executed
Last Run: 21:56:19
pageLoad executed
Easy huh?
I hope that adds some clarity to your options for executing script as the result of a partial postback. Check out the attached if you want to try it yourself.
Originally posted by Simon Ince on 29 July 2009 here.