So, Farewell Then Google Reader
Your feed
Has expired
Like Bloglines,
Which you killed
Off
I guessGoogle Reader was 7 1/2
Now
We'll just have to use
Something else
Instead
(With apologies to E.J.Thribb)
.net dregs from my mental teacup
So, Farewell Then Google Reader
Your feed
Has expired
Like Bloglines,
Which you killed
Off
I guessGoogle Reader was 7 1/2
Now
We'll just have to use
Something else
Instead
As any .Net UI developer will tell you, INotifyPropertyChanged is a fundamental part of 'binding' an object to a UI control. Without it binding is essentially one-way: changes in the control change the object, but if this has a ripple effect on other properties, or properties are changed by other 'below the UI' processes, the UI can't know to repaint. This is essentially an implementation of the Observer pattern[1].
Unfortunately it's not for free - you have to implement it yourself - and that's where the problems start. So much has been written on the pain of implementing INotifyPropertyChanged (INPC for short) that I need not repeat it all here. It's generated so many questions on StackOverflow you'd think it's due its own StackExchange site by now.
The principal complaints are around all the boilerplate code and magic strings required to implement, so for the sake of completeness I'll summarize some of the solutions available:
An object that implements INotifyPropertyChanged must raise the PropertyChanged event only on the thread that was originally used to construct any registered subscribers for that event
Now there's a problem[2].
Clearly this is something that's just not possible to check for at runtime, so your design has to cater for this. Passing objects that might have been bound to business logic that might mutate them? UI thread please. Adding an item into a collection that might be ObservableCollection? UI thread please. Doing some calculations in the background to pass back to an object that may have been bound? Marshal via UI thread please. And so on. And don't even get me started on what you do if you have two (or more) 'UI' threads[3].
This is a horrible, horrible creeping plague of uncertainty that spreads through your UI, where the validity of an operation can't be determined at the callsite, but must also take into account the underlying type of an object (violating polymorphism), where that object came from (violating encapsulation), and what thread is being used to process the call (violating all that is sacred). These are aspects that we just can't model or visualize well with current tooling, at least not at design time, and none of the solutions above will save you here.
So there you go. INotifyPropertyChanged: far, far worse than you imagined.
[1] ok, any use of .net events could be argued is Observer, but the intent here is the relevant bit: the object is explicitly signalling that it's changed state.
[2] Actually I've over-simplified, because you can have whole chains of objects listening to each other, and if any one of them is listened to by an object with some type of thread-affinity, that's the constraint you have to consider.
[3] Don’t try this at home. There are any number of lessons you’ll learn the hard way.
public static class NotUsed{
public static void DefinatelyNotUsed(this TContext context, Action thing)
where TContext : DataContext
{
}
}
... then you'll also have to pull in System.Data.Linq to get the 'importing' assembly to compile.$blah.Catalogs | Get-Member Get-Member : No object has been specified to the get-member cmdlet.
Get-Member -inputObject:$blah.Catalogs TypeName: BlahNamespace.BlahCollection Name MemberType Definition ---- ---------- ---------- Add Method System.Void Add(Microsoft.SqlServer.Management.IntegrationSer... Clear Method System.Void Clear()
"A DAC is a database lifecycle management and productivity tool that enables declarative database development to simplify deployment and management. A developer can author a database in SQL Server Data Tool database project and then build the database into a DACPAC for handoff to a DBA"
http://msdn.microsoft.com/en-us/library/ee210546.aspx
var localTime = DateTime.Now;
var utcTime = localTime.ToUniversalTime();
localTime.Dump("Local Time");
utcTime.Dump("UTC time");
utcTime.Kind.Dump("UTC Kind");
utcTime.ToString("yyyy-MM-ddTHH:mm:ss K").Dump("Expected XML");
XmlConvert.ToString(utcTime).Dump("Actual XML from XML Convert");
| Local Time | 23/10/2012 11:11:11 AM |
|---|---|
| UTC time | 23/10/2012 3:11:11 AM |
| UTC Kind | UTC |
| Expected XML | 2012-10-23T03:11:11 Z |
| Actual XML from XML Convert | 2012-10-23T03:11:11.0773940+08:00 |