Using Lucene – External Indexes
Lucene is a document indexing engine, that is its sole goal, and it does so beautifully. The interesting bit about using Lucene is that it probably wouldn’t be your main data store, but it is likely to be an important piece of your architecture.
The major shift in thinking with Lucene is that while indexing is relatively expensive, querying is free (well, not really, but you get my drift). Compare that to a relational database, where it is usually the inserts that are cheap, but queries are usually what cause us issues. RDBMS are also very good in giving us different views on top of our existing data, but the more you want from them, the more they have to do. We hit that query performance limit again. And we haven’t started talking about locking, transactions or concurrency yet.
Lucene doesn’t know how to do things you didn’t set it up to do. But what it does do, it does very fast.
Add to that the fact that in most applications, reads happen far more often than write, and you get a different constraint system. Because queries are expensive on the RDBMS, we try to make few of them, and we try to make a single query do most of the work. That isn’t necessarily the best strategy, but it is a very common one.
With Lucene, it is cheap to query, so it makes a lot more sense to perform several individual queries and process their results together to get the final result that you need. It may require somewhat more work (although there are things like Solr that would do it for you), but it is results in a far faster system performance overall.
In addition to that, since the Lucene index is important, but can always be re-created from source data (it may take some time, though), it doesn’t require all the ceremony associated with DB servers. Instead of buying an expensive server, get a few cheap ones. Lucene scale easily, after all. And since you only use Lucene for indexing, your actual DB querying pattern shift. Instead of making complex queries in the database, you make them in Lucene, and you only hit the DB with queries by primary key, which are the fastest possible way to get the data.
In effect, you outsourced your queries from the expensive machines to the cheap ones, and for a change, you actually got better performance overall
FluentPath: a fluent wrapper around System.IO
.NET is now more than eight years old, and some of its APIs got old with more grace than others. System.IO in particular has always been a little awkward. It’s mostly static method calls (Path.*, Directory.*, etc.) and some stateful classes (DirectoryInfo, FileInfo). In these APIs, paths are plain strings.
Since .NET v1, lots of good things happened to C#: lambda expressions, extension methods, optional parameters to name just a few. Outside of .NET, other interesting things happened as well. For example, you might have heard about this JavaScript library that had some success introducing a fluent API to handle the hierarchical structure of the HTML DOM. You know? jQuery.
Knowing all that, every time I need to use the stuff in System.IO, I cringe. So I thought I’d just build a more modern wrapper around it. I used a fluent API based on an essentially immutable Path type and an enumeration of such path objects. To achieve the fluent style, a healthy dose of lambda expressions is being used to act on the objects.
Without further ado, here’s an example of what you can do with the new API. In that example, I’m using a Media Center extension that wants all video files to be in their own folder. For that, I need a small tool that creates directories for each video file and moves the files in there. Here’s the code for it:
Path.Get(args[0])
.Select(p =>
p.Extension == ".avi" ||
p.Extension == ".m4v" ||
p.Extension == ".wmv" ||
p.Extension == ".mp4" ||
p.Extension == ".dvr-ms" ||
p.Extension == ".mpg" ||
p.Extension == ".mkv")
.CreateDirectory(p =>
p.Parent
.Combine(p.FileNameWithoutExtension))
.Previous()
.Move(p =>
p.Parent
.Combine(p.FileNameWithoutExtension)
.Combine(p.FileName));
This code creates a Path object pointing at the path pointed to by the first command line argument of my executable. It then selects all video files. After that, it creates directories that have the same names as each of the files, but without their extension. The result of that operation is the set of created directories. We can now get back to the previous set using the Previous method, and finally we can move each of the files in the set to the corresponding freshly created directory, whose name is the combination of the parent directory and the filename without extension.
The new fluent path library covers a fair part of what’s in System.IO in a single, convenient API. Check it out, I hope you’ll enjoy it. Suggestions are more than welcome. For example, should I make this its own project on CodePlex or is this informal style just OK? Anything missing that you’d like to see? Is there a specific example you’d like to see expressed with the new API? Bugs?
The code can be downloaded from here (this is under a new BSD license):
http://weblogs.asp.net/blogs/bleroy/Samples/FluentPath.zip
Mark Brown on Microsoft's Web Platform Installer
Accessing OLAP Server Data with ADO .NET
Welcome to our new partner, Pluralsight!
It’s a tough world out there for .NET developers and software teams. Just when you think you’ve mastered the latest technique, technology, or framework — along comes something new to rattle your cage.
How many developers conquered the Entity Framework after a long struggle, only to turn the next corner and bump into LINQ? Perhaps you spent months learning WPF and Silverlight 3, just to discover that .NET 4.0 and Silverlight 4 will RTM very soon. It never ends. You just adapt to the shock of the new, learn the necessary skills to thrive, and move on.
So we hope that today’s news is a big win for .NET developers and teams everywhere.
I’m delighted to announce that
InnerWorkings is adding Pluralsight to our list of trusted partners.
I’m sure many of you know Pluralsight well — we have always been most impressed by their combination of top tier instructors, premium video content, and active participation in the .NET community.
Empty announcements are just annoying, so I’ve got something else to add today….
I’m really pleased to announce that Pluralsight is kindly offering InnerWorkings users and affiliates 1 week of access to the Pluralsight On-Demand! .NET training library. And I should add that this exclusive offer is entirely free, gratis, libero, frei.
So don’t look a gift horse in the mouth — get on over to the InnerWorkings offer page on the Pluralsight website and sign up for your free .NET training today. Simply use the activation code 27-1-YHRA-KDST to unlock your access to the Pluralsight library and start learning new programming skills today. Enjoy!
VistaDB 4.0 Build 13 – Visual Studio 2010 RC Updated
Build #13
This build has a lot of minor changes from user tickets, but the major update is for Visual Studio 2010 RC.
Visual Studio 2010 RCVisual Studio 2010 RC now works. There were several changes in Visual Studio between beta 2 and the RC with respect to data providers and plugin installation. We have fixed these issues.
Hopefully the Visual Studio 2010 final release will not introduce any more surprises. Beta 2 has not been tested with this build, we do not intend to support it.
VistaDB 3 and 4 side by side in Visual Studio 2008There is a conflict that impacts Visual Studio 2008 side by side of our two data sources. Once VistaDB 4 has been installed Visual Studio 2008 still knows about VistaDB 3.x, but it will not show it for new connections from the Server Explorer (this will impact Strongly Typed Datasets that reference Server Explorer connections).
In order to fix this you will need to first uninstall VistaDB 4 prior to build 13.
Then run InstallDesigner for VistaDB 3 from the VistaDB 3 install path like this:
C:\Program Files (x86)\VistaDB 3\VisualStudio\InstallDesigner.exe ( 32 bit users will not have an x86 in the program files )
After running this command line tool you should see the VistaDB 3 entry in Visual Studio 2008 again.
Finally, install VistaDB 4 build 13 or higher and you will have two entries present.
Changes and FixesThere are a number of small changes from user tickets. Read through the list below if you are looking for something specific.
DeriveParametersFixed an issue where calling DeriveParameters on a stored proc with no parameters would fail. The fix is to just return nothing since there are no parameters.
Corrupted Database DetectionFixed an issue where calling Pack or Repair on a corrupted database with an invalid header would get stuck in a loop attempting to fix the problem.
Added some better corrupt header detection routines to prevent random data from allocating large structures internally. If the data for the structures is out of the expected bounds an exception is throw that the headers could not be loaded and are corrupt. Same if a header with a pagesize outside allowable ranges is detected, it is reported as corrupt.
IF EXISTSFixed an issue with Return not aborting IF EXISTS block when used within a stored proc. The RETURN sql function will not short circuit no matter what the containing batch method is to always bubble the top of the call chain.
VistaDB ConnectionStringBuilderVistaDBConnectionStringBuilder has a number of small corrections to handle bad string lookup behavior. Both of these behaviors are present in SQL Server, but we were either throwing VistaDBExceptions, or ignoring the invalid data. The internal comparer has also now been changed to be case insensitive.
If an invalid keyword is assigned an ArgumentException.
VistaDBConnectionStringBuilder csb = new VistaDBConnectionStringBuilder(); csb["bad keyword"] = "Off"; // Keyword does not exist
If an invalid parameter is passed to a valid keyword a FormatException is now thrown to match SQL Server behavior.
VistaDBConnectionStringBuilder csb = new VistaDBConnectionStringBuilder(); csb["transaction mode"] = 12345; // Should be ON OFF or IGNORE
The above change to VistaDBConnectionStringBuilder also fixes a bug in the Visual Studio connection string advanced editor dialog. It was complaining about not accepting a string on TransactionMode before, but the actual problem is that Visual Studio calls with a bad value first, and is expecting a certain exception before it will call again with the correct value.
GetSchemaChanged the behavior of GetSchema( string, string[]) so that an empty or null string object is treated as the generic GetSchema() call and will retrieve the list of collections using the SCHEMA_METADATACOLLECTIONS enum.
sp_columns()sp_columns fails to parse with a missing expected symbol '('. The symbol can be present, but the parser is not reading the parameter correctly.
This happened in a few functions (sp_columns, sp_indexes, getviews and sp_foreignKey) that use a generic Enumerator<T> that has a yield. You cannot reset a yield statement, so internally when the function calls FirstRow and tries to go back to the start of the enumerator it failed.
This was changed in 4.x to a generic in order to strongly type some internal structures. This issue has been fixed by implementing a castable generic enumerator that knows how to cast from the generic interface type to a concrete class during enumeration.
Entity Framework SamplesTwo new Entity Framework sample applications are included. Learning EF has a huge learning curve. These two samples were built to demonstrate simple concepts with an EF provider.
C:\Users\Public\Documents\VistaDB\Samples\Entity Framework\
EFDataBindingSample - Shows how to data bind against an EF model
EFSampleCRUD - Example create, retrieve, update, delete commands against an EF model
A named permission set in C#
Converting a PowerShell Script into a Module Part 2
Silverlight 4, MEF and the DeploymentCatalog ( again :-) )
Simplified INotifyPropertyChanged Implementation with WeakReference Support and Typed Property Access API
I've grown a bit tired of implementing INotifyPropertyChanged. I've tried ways to improve it before (like this "ViewModel" custom tool which even generates strong-typed event accessors).
But my fellow Clarius teammate Mariano thought it was overkill and didn't like that tool much. He mentioned an alternative approach also, which I didn't like too much because it relied on the consumer changing his typical interaction with the object events, but also because it has a substantial design flaw that causes handlers not to be called at all after a garbage collection happens. A very simple unit test will showcase this bug.
I also looked at the new WeakEvent Patterns page in MSDN but it's even worse in terms of implementing and exposing it to consumers.
So, with my ever growing love for lambdas and my strong-typed reflection approach (used by the first alternative too, btw), I thought I could do better :). Here's the result of that, which I think improves all the above choices.
Why you need weak reference supportThe importance of this cannot be understated. A delegate that you pass around has a strong reference to the instance that exposes it. This is the Target property on the delegate class. What this means is that even if the subscribing object goes out of scope and is ready to be collected, it will not be as long as the event source (the object exposing the PropertyChanged event, for example) holds a reference to it. And as long as the event subscription is there, the reference will be there too. That's why it is typically important to remove your reference once you're ready to "go" (i.e. on Dispose, you detach from the events you're listening). Needless to say, this is a repetitive, error-prone activity.
Another typical side-effect of this is that you cannot use anonymous delegates or lambdas if you need to unsubscribe, as you need to keep a reference to the originally subscribed lamdba in order to unsubscribe:
var target = new Foo(); target.PropertyChanged += (sender, args) => Console.WriteLine(args.PropertyName); // How do you unsubscribe now?? // This clearly doesn't work because even if the actual source is the same, // the delegate is still a brand-new one. target.PropertyChanged -= (sender, args) => Console.WriteLine(args.PropertyName); // So you need to keep the lambda around: PropertyChangedEventHandler handler = (sender, args) => Console.WriteLine(args.PropertyName); // Just so you can use that to subscribe/unsubscribe: target.PropertyChanged += handler; target.PropertyChanged -= handler; // So typically you're better off just adding a full instance method on your // consumer just so you have a clear pointer for unsubscribing: target.PropertyChanged += OnTargetPropertyChanged; // But now if you need contextual state in the event handler that exists // at subscription time, you need to promote that state to class fields // so that you can use that in the event handler this.someState = currentMethodState; // This is looking like .NET 1.0 already ;)The PropertyChangeManager way
I therefore decided to take a TDD approach to the issue with the following requirements:
- The programming model for consumers must not involve creating any new objects. They already have the object that will be raising property change events.
- The "old style" way of attaching to property changed events must still work, but add the weak reference support that's so badly needed. And this must be transparent to consumers.
- A new style should involve using lambdas to avoid property names as strings
- The new style should be trivial to implement for an author exposing INotifyPropertyChanged.
So I came up with these BDD-style test specifications:
- WhenSubscriberIsAlive_ThenNotifiesSubscriber
- WhenSubscriberIsNotAlive_ThenDoesNotNotifySubscriber
- WhenAddingPropertyChangedHandler_ThenNotifiesSubscriber
- WhenAddedPropertyChangedHandlerTargetIsNotAlive_ThenDoesNotNotify
- WhenRemovingPropertyChangedHandler_ThenDoesNotNotifySubscriberAnymore
These should cover all use cases.
Consuming PropertyChangeManager-enabled objectsThe fact that a given object is internally (remember requirement 1.) using this PropertyChangeManager is completely hidden from the consumer:
var source = new Foo();
source.SubscribeChanged(
x => x.Name,
foo => Console.WriteLine(foo.Name));
The first argument specifies which property you're interested in, and the second is an Action<Foo> in this case for the callback when the property changes. It can of course point to a class method:
source.SubscribeChanged(
x => x.Name,
this.OnRenamed);
Optionally, if unsubscribing from the event will be needed at some point, you can just keep a reference to the returned IDisposable object from the call to SubscribeChanged:
// this could be assigned to a field, for example.
IDisposable onRenameSubscription = source.SubscribeChanged(
x => x.Name,
foo => Console.WriteLine(foo.Name));
// at some later point (i.e. IDisposable.Dispose implementation of the consumer)
onRenameSubscription.Dispose();
// now the subscription is removed, even if I didn't keep the lambda around!
The source object still implements INotifyPropertyChanged, but now does so explicitly to support databinding infrastructure. The consumer can still cast the object to INotifyPropertyChanged if he wants to use the "unsafe" property name strings.
Implementing INotifyPropertyChanged with PropertyChangeManagerThe implementer defines a private field to hold a reference the manager:
public class Foo : INotifyPropertyChanged
{
private PropertyChangeManager<Foo> propertyChanges;
private string name;
private int value;
public Foo()
{
this.propertyChanges = new PropertyChangeManager<Foo>(this);
}
Note that the manager is generic and receives the type of the "change event source", in this case Foo.
Next, your properties need to be turned into "old-style" .NET properties with a backing field, because you need to add a call to the manager in the property setter:
public string Name
{
get { return name; }
set { name = value; this.propertyChanges.NotifyChanged(x => x.Name); }
}
Note that the call to the manager also leverages lambdas to avoid using strings.
In order to provide a custom implementation of the INotifyPropertyChanged.PropertyChanged event, you need to implement the interface explicitly and pass-through the implementation to the manager:
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add { this.propertyChanges.AddHandler(value); }
remove { this.propertyChanges.RemoveHandler(value); }
}
This is a restriction in the language, which prevents this event from being public. But it's not as bad as it sounds, as you want to encourage adoption of safer lambda-version subscription, which is the last bit to implement:
public IDisposable SubscribeChanged(Expression<Func<Foo, object>> propertyExpression, Action<Foo> callbackAction)
{
return this.propertyChanges.SubscribeChanged(propertyExpression, callbackAction);
}
How PropertyChangeManager works
The manager works by dismembering the received delegates into their actual target and method info, to be able to weakly reference the former, while remaining able to call the latter. It's a plain list internally, which is scavenged every time an action is performed in the manager (this could be optimized somehow to only happen on Notify, but it simplified the implementation a bit, and it's not like property change performance is a big issue in UIs anyway).
Here's the full source.
Some tooling such as a custom tool, item template, or code snippets would be nice, I'll try to provide those in the future.
Enjoy!
How to set the startup program for debugging a project for the entire team
You surely have set the startup application for a project countless times:
But that setting goes your user options file, the rest of the team doesn't get to reuse the setting. And what if you repave your machine or start working on a new virtual machine and just got the sources from source control? You have to re-set this value again and again.
Turns out that this setting goes to a file named after your project file plus the ".user" extension. This file is just a fragment of an MSBuild file, and would look something like:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe</StartProgram>
<StartArguments>/rootSuffix Exp</StartArguments>
</PropertyGroup>
</Project>
And because this just plain MSBuild properties, you can copy the entire PropertyGroup to your main project file, delete this .user, and check-in your change. From now on, everyone on the team will have this setting enabled, and you will have it too if you get a clean environment eventually :)
How to install Reactive Extensions for .NET 4.0 Beta 2 on VS2010 RC
- Get the .NET 4.0 Beta 2 download from MSDN.
- Open the downloaded .exe with 7zip (i.e. right-click on file, select 7-Zip > Open Archive)
- Navigate to the .rsrc\RCDATA\ "folder" and open the CABINET file:
- Extract the contained MSI, install and enjoy!
I thought I'd need to crack the MSI open with the good old Orca tool, but turns out I didn't have to!
Stay tuned, my Reactive Framework Extensions Generator will be soon updated to RC too :)
Enjoy!
How to quickly setup the best free Diff/Merge tool with VS 2010
First go get the tool. It's free and it rocks.
Next, save this XML to a file with a .vssettings extension:
<UserSettings>
<ApplicationIdentity version="10.0"/>
<Category name="Source Control_TeamFoundation" Category="{2A718788-A6D9-44C5-90EF-438BF5B06A74}" Package="{4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}" RegisteredName="Source Control_TeamFoundation" PackageName="Microsoft.VisualStudio.TeamFoundation.VersionControl.HatPackage, Microsoft.VisualStudio.TeamFoundation.VersionControl, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<PropertyValue name="UserTool1" extension=".*" operation="Compare" command="C:\Program Files (x86)\SourceGear\DiffMerge\DiffMerge.exe" arguments="/title1=%6 /title2=%7 %1 %2"/>
<PropertyValue name="UserTool2" extension=".*" operation="Merge" command="C:\Program Files (x86)\SourceGear\DiffMerge\DiffMerge.exe" arguments="/title1=%6 /title2=%8 /title3=%7 /result=%4 %1 %3 %2"/>
</Category>
</UserSettings>
Finally, go to Tools > Import and Export Settings in VS and import that file by clicking Browse on the third and final page.
What this does is set the great SourceGear DiffMerge tool as the diff and merge tool to use for all your files. I find it much more usable and smart than the built-in TFS one.
For the ultimate collection of settings for diff/merge tools in VS, see James' blog post.
Enjoy.
Software Development Productivity
Scott Bellware has an interesting series of posts where he discusses how to get back to productive development teams. As usual in his writing (IMO), in a rather verbose way he brings up quite a few good points. Please go ahead and read them. He links from the first entry to the next so you can follow the flow.
I agree with the analysis that unnatural organizational structures kill productivity, motivation and leadership. And I believe this is one of the reasons why even big companies turn to so-called "boutique development shops" (shameless plug there): by being small and very cohesive, these shops offer creativity and productivity levels that "mere big" ISVs can only dream of.
And it's not always only a matter of design principles, I'd add. Sometimes you need a specific area of expertise which you're better off outsourcing (i.e. Visual Studio extensibility, hardcore WCF, framework/runtime libraries, WPF/Silverlight/Blend UEX, etc.). Small shops of highly specialized professionals can save you tons of money and time. But your own dev team will certainly benefit from applying sound design principles for what matters most to your business: the business rules and logic.
How to transform old properties to automatic properties with a simple search and replace
Say you have a (typically autogenerated) class with properties like:
public partial class Project : IExtensibleDataObject
{
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
Now you can fire up the Find & Replace dialog in VS and enter the following "simple" expression in Find What:
\n:b*\{[:b\n]*get[:b\n]*\{[.:b\n]*.*[.:b\n]*\}[.:b\n]*set[:b\n]*\{[.:b\n]*.*[.:b\n]*\}[.:b\n]*\}
And use the following expression for the replace:
{ get; set; }
Don't forget to set the Use: Regular expressions option.
Running it will get you automatic properties for the entire file (or files):
public partial class Project : IExtensibleDataObject
{
public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get; set; }
[System.Runtime.Serialization.DataMemberAttribute()]
public int AffiliateId { get; set; }
[System.Runtime.Serialization.DataMemberAttribute()]
public Galleries.Domain.Model.Category[] Categories { get; set; }
Yeah, I know, that expression looks like crap ;)
How to get out of the GAC all the registered assemblies
You know how annoying the GAC shell extension makes it to access the actual assemblies:
Utterly useless.
Of course, you surely know that you can get to those elusive assemblies via the command-line and side-step the shell extension:
But, now you need to go to each assembly folder, then its version, and so the actual assemblies are scattered through various locations.
This one-liner powershell command will get them all out in a folder of your choosing for easy Reflector-ing (create the target before running it):
Get-ChildItem C:\Windows\assembly\GAC_MSIL -filter *.dll -recurse | Copy-Item -destination C:\GAC
Why Windows Media Center is dead
Windows Media Center (WMC) is based on a relatively simple (albeit awfully implemented) principle: you have ONE "server" PC holding and running your media, and then you associate any number of Media Center Extenders to it that are typically (except for the XBox 360) single-purpose devices that can only act as such and are fancy and silent enough to deserve a place in your living room.
I guess back in 2005, the entire model and most of Microsoft design decisions on this product may have be justifiable. 5 years later, none of them make any sense and IMO mean that WMC is currently a totally flawed, doomed and generally useless product for most common needs.
Why it (kind of) made sense back then- Hardware: In 2005, you wouldn't dare subject your family to the noise, ugliness, quirkiness, uex, power comsumption, and cost of a full-blown "Home Theater PC" (HTPC) or an XBox power sucker. The Media Center Extender model made sense because you couldn't buy a full PC that was silent and nice-looking enough for the price of an extender. (but the extenders weren't without limitations either, a good review of it at the time at the supersite)
- The user experience is quite cool (but the extenders' lower processing profile meant their UI rendering capabilities were significantly worse)
- Hardware: nowadays you can buy a full blown PC, small, silent and power-efficient for $199-$249. Why would you want a crippled, single-purpose device when you can have the full power of a desktop, with the capability to play back any weird format you can possibly throw at it, provided you just install the right codec. No more hardware limitations and being stuck with an obsolete device.
- Software: back then, the Media Center team invented their own markup language to accommodate disparate rendering capabilities between a full PC, the XBox and a crippled extender. Nowadays we have WPF and Silverlight, no need to learn a new UI markup language. The extenders UI is sluggish at best, compared with what's possible in a PC with WPF/Silverlight.
- OS: Windows 7 is a kick-ass operating system, with a ton of features. It's a snappy, sleek, touch-friendly, smart connected (i.e. "Play To"/DLNA, HomeGroup, etc. etc.) platform. And it runs great on the smallest chips out there (it gave new life an 'old' Dell Mini 9 I had, for example).
- Home Server: having all your media in a "plain" PC is risky. You need to take care of backups, redundancy, fault-tolerance, etc. Today, it's a no-brainer to buy a Windows Home Server and let it manage all this for you, automatically, transparently, and just dead easily.
This combination makes desktop media management software a viable alternative and can certainly power your living room and projector. I believe we're at the beginning of a revolution in smart homes and connected media, just because of this new synergy and convergence.
If I had to start a project like that right now, I'd make it so that:
- It runs full WPF on the HTPCs connected to every TV.
- It supports a centralized repository for the entire house (which could be a regular PC or a Windows Home Server-WHS)
- It has a built-in extensibility model based on some dependency injection technology (i.e. MEF), and *everything* including the core functionality is a plugin
- It leverages WHS to provide mostly the same UI over the internet by leveraging Silverlight (single programming model for both), so that I can access all the same content from everywhere, and automatically takes advantage of Smooth Streaming for videos.
- It integrates with home security cameras and provides those both in the home (i.e. monitor the baby upstairs on a PiP window) or via the web (i.e. watch my home while on vacations) leveraging Live Smooth Streaming.
- It empowers a huge plugin community that can create cool advanced features like face detection on photos and videos and security recordings, provide filtered views of those, map pictures with geocoding, provide a "home connection point" where a GPS could submit road trip info, etc. etc.
For now, I got my Dell Zino HD (shipping soon) and I'm looking forward to selling the assorted Frankenstein media setup I have right now.
The future looks bright for the smart home :)
How to mock extension methods
. without paying for a TypeMock Isolator license to do it ;-)
There's going to be no magic here. You have to explicitly design for testability. That's one of the things I like about mocking: if you can mock a dependency, then it means your design is loosely coupled (e.g. not tied to a particular implementation of that dependency), and you're not "cheating or taking any shortcuts. If a test can replace a dependency at test-time, your'll surely be able to replace the real implementation with something different when/if time comes to do so.
Extension methods are tricky because they are static methods, really just syntactic sugar for a "good" old static class with static methods (typically a "helper" of some sort. But what is special about them, is that they show up (provided you have the right usings/imports) in the target type API as if they were its own instance methods. This is significant, because it also means that it's very easy to pollute the target type API as you (and other referenced libraries) keep piling up these methods on it.
I therefore prefer an approach where you group your extensions under a single API, and access that API via a single extension method on the target type that becomes the entry point to your extensions. For example, say you have an IPerson interface, and you want to add secutity-related helper methods that you can use consistently from other logic or services. One way of adding a GetPermissions security helper extension method (that will get the rights of the user over a given resource, for example), would be to plug it right into IPerson as an extension method:
[Flags]
public enum Permissions
{
Read = 0,
Modify = 1,
Delete = 2,
FullControl = Read | Modify | Delete
}
public static class SecurityExtensions
{
public static Permissions GetPermissions(this IPerson person, Uri resource)
{
// get permissions for the given resource from somewhere
}
}
This would get you the API right on the IPerson object:
If you go overboard with this "extension in the root" approach, you might end up with an ugly looking assorted collection of helpers attached to the main class, such as what happened to the UML APIs in Visual Studio 2010. Look at the before and after we reference and import the assembly containing the extensions to IClass (the interface that represents a class in a UML Logical Class Diagram):
After referencing Microsoft.VisualStudio.Uml.Extensions.dll and adding the corresponding using/import:
(I pasted together four pages of intellisense for added effect, but you see the point, rigth?)
Extension InterfacesAnother alternative is to group extension methods that provide related functionality under what I'd extension interfaces. In our person example, we might find out that the security-related methods start growing, and we'd like to keep the main API clean, so we introduce the ISecurity extension interface, and provide an extension method that is the entry point to it:
public interface ISecurity
{
Permissions GetPermissions(Uri resource);
}
public static class SecurityExtensions
{
public static ISecurity Security(this IPerson person)
{
throw new NotImplementedException();
}
}
Now, the consumer of the IPerson object can see that there is security-related behavior available to him, but won't see what those are unless he needs to:
Typically, the SecurityExtensions class will instantiate a non-public implementation of ISecurity that does the real work, passing the person to work on as a constructor argument:
internal class Security : ISecurity
{
private IPerson person;
public Security(IPerson person)
{
this.person = person;
}
public Permissions GetPermissions(Uri resource)
{
// get the real permissions for the person
// field we have received, for the given resource
throw new NotImplementedException();
}
}
public static class SecurityExtensions
{
public static ISecurity Security(this IPerson person)
{
return new Security(person);
}
}
The attentive reader might have noticed that, being a regular interface, the extension interface now can expose properties where it makes sense, overcoming the lack of support for extension properties in C#. For example we could add a Roles property quite easily:
And because the extension interface is nothing more than a fluent interface in the end, you can use the trick I blogged about before to hide those pesky System.Object members:
Back to the testing subject, in order to test the Update method above, we'll need to replace the ISecurity implementation, right? Because we followed the extension interface design approach, we now have a single extension method to replace, the one that creates the default implementation of the ISecurity inteface. And if you look at that method, all it is being a factory for creating an implementation of ISecurity given an IPerson:
public static class SecurityExtensions
{
public static ISecurity Security(this IPerson person)
{
return new Security(person);
}
}
So for testing purposes we can just add an internal factory that will isolate the extension method behavior, and that we'll replace for testing purposes:
public static class SecurityExtensions
{
internal static Func<IPerson, ISecurity> SecurityFactory = person => new Security(person);
public static ISecurity Security(this IPerson person)
{
return SecurityFactory(person);
}
}
The test for the Update method above, which will have internals visibility enabled from the project under test, will simply replace the factory with one that returns a mock:
public void WhenPersonHasNoModifyPermission_ThenThrowsSecurityException()
{
var security = new Mock<ISecurity>();
security.Setup(x => x.GetPermissions(It.IsAny<Uri>())).Returns(Permissions.Read);
SecurityExtensions.SecurityFactory = person => security.Object;
var controller = new DocumentsController();
Assert.Throws<SecurityException>(() =>
controller.Update(new Mock<IPerson>().Object, new Uri("http://foo")));
}
And voila! We have just passed a test where the class under test uses an extension method:
public class DocumentsController
{
public void Update(IPerson person, Uri document)
{
if (!person.Security().GetPermissions(document).HasFlag(Permissions.Modify))
throw new SecurityException();
// ...
Also note that the intenal Security class that implements ISecurity can also be fully tested in isolation.
Happy moqing!
PS: remember the focus of this post is on mocking extension methods, not on how to design security for your domain ;-). Feel free to mentally replace ISecurity with IFoo, GetPermissions with DoSomething, etc., as needed.
Resetting Visual Studio Experimental Instance to its super-clean initial state
If you are doing Visual Studio extensibility (VSX) work, you are probably aware of the existence of the Visual Studio "Experimental" instance. This is basically an instance of VS that has its own isolated registry, settings, extensions, etc. This allows you to test your extensions to VS without polluting your main development environment.
Sometimes, the environment might get corrupted for whatever reason, or it might be that you just want to test your extension with a clean environment after messing with it for a while.
The Visual Studio SDK does come with a tool to reset the experimental instance, available from your Start menu with the name "Reset the Microsoft Visual Studio 2010 Experimental instance". That will not, however, give you the pristine environment you got the first time you start the experimental instance to test your first extension.
In order to get a super-clean environment, here's what you need to do:
- Close any running instance of VS Experimental.
- Delete the entire folder %LocalAppData%\Microsoft\VisualStudio\10.0Exp
- Run regedit.exe
- Delete the registry key HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0Exp
- Delete the registry key HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0Exp_Config
- Run the command "Reset the Microsoft Visual Studio 2010 Experimental instance" from your start menu.
Now you'll have a fully restored environment. Also, any existing extensions you have in your main environment will be copied over to the experimental instance, with one caveat: you'll have to manually enable them from the Extension Manager UI from a running experimental instance to get them running.
If you've been doing VSX work in previous versions of VS, you'll sure appreciate the drastically simplified install/reset experience enabled by the new deployment mechanism in VS2010 via Extension Manager and VSIX files. If you have not, then this doesn't sound so scary anymore, does it? ;-)
Happy extending!