Chrome as default PDF reader

Let me start by venting a bit and expressing my deep displeasure with the latest Foxit reader 6 release. I originally installed Foxit as a lightweight replacement for Adobe reader, but the latest release lacks the main advantage earlier versions had – quick instantaneous PDF access. A colleague of mine recommended using Chrome’s built in PDF reader as a default reader instead since I’m already using Chrome either way. As you might have experienced when opening PDFs from the web, it’s lightning fast in Chrome. This post isn’t just about how to set up Google Chrome as your default PDF reader, which is rather straightforward; I’ll gladly refer you to How-To Geek for help with that. However, once you have done so you might notice some undesirable behavior which differs from using a dedicated PDF reader.

PDF file with gray borders on the sides.

  • When you already have a browser window open, the PDF opens as a new tab in that browser. This might actually be considered a feature by some, but as I blogged before, I rather move away from application-specific tab management entirely.
  • The chrome ‘PDF window’ doesn’t retain its own size when opening PDFs, but shares it with regular browser usage. PDFs are generally not that wide, and maximizing the window results in gray borders on the sides.

After some hacking around I found a solution around this. By placing a custom executable (download here) in the same folder as chrome.exe and using this executable as the default application to open PDF files, both before mentioned issues are solved. Double clicking a PDF file results in a new chrome window, having the same size as the last PDF file you opened.

The chrome executable by default is located in: C:\Users\\AppData\Local\Google\Chrome\Application\

How it works

The executable simply calls the original chrome.exe, but additionally adds two command line arguments.

  • –user-data-dir: Specifies the user data directory, which is where the browser will look for all of its state.
  • –new-window: Launches URL in new browser window.

The user data directory besides other settings also seems to contain the last set window size. Passing any non existing path here results in a new directory being created for it under “C:\Users\\AppData\Local\Google\Chrome\Application\”, containing the settings which will be reused the next time the executable is called. In case you want to adjust the behavior (e.g. disable opening the PDFs in a new window) what follows is the C# source code for the executable. Originally I tried creating a shortcut and setting that as the default application to open PDFs, but the executable to which the shortcut points ends up being used instead, hence losing the command line arguments.

static void Main( string[] args )
{
	string chromeDir =
		new FileInfo( Assembly.GetEntryAssembly().Location ).DirectoryName;
	string chrome = Path.Combine( chromeDir, "chrome.exe" );
	string arguments =
		"\"" + args[ 0 ] + "\"" + " --user-data-dir=pdf_dir --new-window";

	var proc = new Process
	{
		StartInfo =
		{
			FileName = chrome,
			Arguments = arguments,
			WorkingDirectory = chromeDir
		}
	};

	proc.Start();
}

CamelCase vs underscores: Revisited

It has been 2 years since I published “CamelCase vs underscores: Scientific showdown”, and it still is easily the most visited article on this blog. Yesterday alone it got 2,614 views thanks to a forum post on Y Combinator, pretty much suppressing my normal visit rates entirely. What is it that makes it such a hot topic? Honestly, it doesn’t interest me that much anymore since there are many more important ways by which to make your code more readable; note it is code comprehension we are talking about here, not how fast you can write code! Before I outlined how the entire discussion could be made obsolete by moving away from a textual representation of code, and in my previous post I related software design principles as an act of communication to the cooperative principle in Linguistics. Nonetheless, given the immense interest this article seems to be getting I feel it’s my obligation to report on follow-up research of the previously discussed paper “To camelcase or under_score” by Binkley et al. (2009) (PDF).

In “An Eye Tracking Study on camelCase and under_score Identifier Syles” by Sharif and Maletic (2010) (PDF) the previous study is replicated but deviates from it in a few points:

  • Only programmers are used as subjects.
  • All of the subjects had experience with both styles and their preference of style was approximately split even among the groups.
  • Most of the subjects were historically trained in the underscore style. (The opposite was true in the study by Binkley et al.)
  • Eye tracking is used to measure fixation count and rate. Results from previous eye tracking studies in the domain of cognitive psychology imply that camel-cased identifiers should be more difficult to read compared to underscored identifiers.

No difference in accuracy was reported (as opposed to Binkley et al.), but on average, camel-cased identifiers took 932ms (20%) longer than underscored identifiers, in line with the 13,5% longer as reported by Binkley et al. The eye tracking results also give some insight into visual effort. Camel-cased identifiers require a higher average duration of fixations.

When interested into the details of the studies, don’t forget to read the papers yourself. I linked to them for your convenience, but if the links break you can easily find them by looking up their titles on Google Scholar.

It seems in general the subject has gotten more attention over the past 2 years in research. You can find relevant resources yourself by checking out the ‘Citing Documents’ of the discussed papers, but here are a few interesting ones:

Learning from Linguistics

Don’t worry about the title, this is a post about software design. This week I started following a Coursera course, Think Again: How to Reason and Argue. In it, the cooperative principle and its constituting maxims are presented which describe how people ideally should interact with each other. I realized the maxims apply to software design as well; after all, programming is a cooperative process, at least if you want your code to be usable by others. At the very minimum all of the maxims apply to the comments and documentation, them being language. Sometimes a direct relation to the existing design principles we follow can be drawn.

Maxim of Quantity

  1. Make your contribution as informative as is required (for the current
    purposes of the exchange).
  2. Do not make your contribution more informative than is required.

Point 1 boils down to stating everything relevant to the current situation without leaving out any important details.

public class Machine
{
	bool _enabled;
	public void Enable() { _enabled = true; }
	public void Disable() { _enabled = false; }
}

This code leaves out important information, namely the state of the machine. This should be publicly visible.

public class Machine
{
	public bool Enabled { get; private set; }
	public void Enable() { _enabled = true; }
	public void Disable() { _enabled = false; }
}

Point 2 states you should only show the relevant information. This reflects the concept of information hiding which states internal logic should be encapsulated and only a stable interface should be exposed.

Maxim of Quality

  1. Do not say what you believe to be false.
  2. Do not say that for which you lack adequate evidence.

Point 1 simply states, “do not lie”. Now you might wonder how to lie when programming, but the following is an all too common example.

try
{
	DangerousOperation();
}
catch ( Exception ) {}

Obviously this exception hasn’t been handled. Testing your software gives you the necessary evidence that your code works for the provided use cases, addressing point 2.

Maxim of Relation

  • Be relevant!

Within linguistics, being irrelevant can for example mean changing the subject when answering a question. Although possibly a long stretch, the Seperation of Concerns principle states a computer program should be separated into distinct features overlapping as little as possible. The notion of cohesion refers to the degree to which elements of a module belong together. High cohesion relates to being relevant, letting a module only perform those tasks related to each other.

Maxim of Manner

  1. Avoid obscurity of expression.
  2. Avoid ambiguity.
  3. Be brief.
  4. Be orderly.

Being brief means conveying something as concise as possible. Well, for starters don’t repeat yourself! Your interfaces/APIs should be unambiguous and as clear as possible. There are many examples of this, but here’s two.

class Controller { ... }        // Obscure.
public int GetWeight() { ... }  // Ambiguous.

Lastly, be orderly. Don’t place everything in one namespace, and code consistently. Follow the conventions in your current work environment, as this will lead to the least surprises.

Programming is very much a linguistic act and thus we could probably learn a thing or two from linguistics and social sciences in general.

Programs must be written for people to read, and only incidentally for machines to execute. – Abelson & Sussman, Structure and Interpretation of Computer Programs

Rethinking tabs: scalable window management


Tabbed Document Interfaces
(TDIs) have become mainstream nowadays. Did you ever stop and wonder why? Which problem has been solved by introducing them? In this post I will shortly take you through their history, explain why I feel tabs don’t solve the fundamental problem, and why Activity-Based Computing (ABC) might be a more appropriate solution.

History

Tabs aren’t as recent as most people think. They gained mainstream success once tabbed browsing was introduced (and no, Opera wasn’t the first web browser to do so), but early environments already supported them. Smalltalk (from Xerox PARC) was a programming language, but its windowed GUI is what eventually inspired windowing environments for personal computers.

Windows in Smalltalk

Although not exactly tabs as we know them today, I found it important to show what most likely has been the inspiration for them. Since the tabs are always positioned at the top left of the window, you can imagine quickly running out of horizontal screen space if you were to outline them next to each other. In this sense you can argue these aren’t tabs at all, but just plain windows. This changed when UniPress’s Gosling Emacs moved the tab to the right hand side of the window. Since tabs take up a lot less space vertically, outlining them underneath each other doesn’t take up as much space as outlining them horizontally.

UniPress Gosling Emacs

Don Hopkins presents having more than 10 windows open under HyperTIES, which is an Emacs based authoring tool. The tabs might not behave as they do today, but they solve a similar problem: allowing to have many documents open simultaneously and easily switching between them.

The problem

Having many documents open and switching between them is the task of a window manager, not specific applications. The definition of a window manager according to dictionary.com is:

A part of a window system which arranges windows on a screen. It is responsible for moving and resizing windows, and other such functions common to all applications.

When an application lets the operating system’s window manager handle all its individual windows separately, it has a single document interface (SDI). This approach quickly resulted in cluttered taskbars, which is why multiple document interfaces (MDIs) and tabbed document interfaces (TDIs) became popular. Limitations of the window manager forced applications to address problems which should have been addressed by window managers in the first place. Consequently, many applications are reinventing the wheel.

Remember that taskbar at the bottom of your screen (usually)? Remember what it used to do before it got all modernized and fancy new features were added? When you’d maximize all of your windows you basically had a tabbed interface with the tabs at the bottom. To exemplify I turned off some of the features in my current Windows 7 setup in order to make it resemble what it looked like in Windows 95, as also visualized in the website I have open.

Taskbars

All TDIs and MDIs are doing is moving the problem to a different location. They hide the clutter, only for it to reappear once the application has to manage many open documents itself. This can be useful when the open documents are related to each other, as is often the case in an integrated development environment (IDE), but this definitely isn’t the case for every application. Ironically web browsers are a prime example of applications which often manage unrelated open ‘documents’.

Imagine a desktop where every application decides for itself where to place the ‘close’ button or how to resize it’s window. The exact same thing is currently going on with document management.

Existing solutions

The problem should be handled by the window manager. Applications don’t need to re-implement the same functionality over and over again. This is in line with a principle in software development called ‘Don’t Repeat Yourself’ (DRY) which I hold in high regard. Additionally the same look and feel can be provided across applications. Some steps have been taken towards this end, of which I’ll discuss a few here.

The windows 7 taskbar allows you to group windows together based on the application they belong to. In the screenshot below explorer windows are grouped together in one icon on the taskbar. Usually you know in which application you have a certain document open, so you can easily find it by performing just one extra step.

Windows 7 Taskbar

The problem I see here is the same as mentioned earlier: this simply moves the problem to a different location, and again, documents open in one application aren’t necessarily related to each other contextually. Additionally, even when the taskbar isn’t full, you still need to go through this extra step. (Note: you can configure to only group windows when the taskbar is full.)

Some modern window managers allow you to group windows together manually.

Allowing you to manually organize windows at least gives you the flexibility to create your own context as you see fit, but unfortunately again these approaches don’t scale well.

… which of course begs the question, do they have to scale that well?

I prefer turning this question on its head and looking at it from an opportunistic angle.

Scaling window management

What if window management would be more scalable?

First, some food for thought. Yes, more questions …

  • What is your main reason for closing a window?
  • Why do you organize files?
  • What is your main reason for not deleting a file?
  • In what way do you organize windows?
  • How does file management relate to window management?

A lot of effort goes into setting up the working environment for a particular activity. Wouldn’t it be nice if you were able to ‘store’ this setup and retrieve (or even reuse) it at a later time, just as you are able to store (and reuse) files?

Perhaps the real problem isn’t how we access windows, but how we store them. In order to store and organize these different configurations of windows I proposed using a time line in my thesis.

Laevo Time Line

This is inspired by Activity-Based Computing (ABC) which I wrote about previously, which states that activity should be the central computational unit instead of files and applications. In the context of window management activity can be seen as all the windows needed to achieve a certain goal. It’s up to you to decide what makes up a relevant context, organizing work as you like.

Taking this to the extreme: assume closing a window would be the same as deleting a file. Would you actually ever have to know about the underlying file system again? Window management and file management could become one and the same thing.

Activity-Based Computing

As I’ve mentioned before, I’ve been quite busy, hence the lack of posts over the past few months. A big portion of my time went into developing a prototype user interface for my thesis titled “Managing Activities in Time and Space in an Activity-Based Computing System”. No worries if you don’t have a clue what that means, as I’ll try to do my best to explain the concept in at least 80 pages less than my thesis. In future posts I will disclose the actual prototype and will work towards a stable beta release. Until then – for the curious – you can already access the open source project, but I still need to add instructions on how to compile it in the readme.

UPDATE: Since writing this post, I’ve released an installer for the Alpha version of this prototype, called Laevo.

It came to me as a surprise, that the very same idea I had for my thesis was already being discussed in the 80s, in the early days of Human-Computer Interaction (HCI) over at Xerox PARC. It came to me as a bigger surprise that even though several research departments have been researching the subject over a course of more than 30 years (including a research group over at Apple Computer), the concept still hasn’t caught on in mainstream computing. Activity-Based Computing (ABC) is a new computing paradigm which attempts to address some of the problems with the current paradigm.

Applications: what a terrible term. What a terrible concept. Applications have little to do with the tasks that people are attempting to accomplish. Look. We don’t do word processing; we write letters, or memos, or reports, or notes to ourselves. – Donald A. Norman

Computers are inherently application and document oriented. This is all good and well for simple tasks, such as using a text editor to write a certain document, but is that still a realistic scenario? Computers nowadays make up a big portion of our daily lives. We don’t just write a paper; we look up information on the internet, translate words, use a dictionary, email with contacts for further information, import images, keep track of the deadline when the work needs to be finished, share a draft version, wait for feedback, and later have to reopen our entire working context again to make amendments. A lot of tasks users need to carry out require the use of several applications and documents, simultaneously. Furthermore, we don’t work on just one task at a time. Interruptions can cause us to suspend work on one task and open up other documents/applications required to continue work on another.

Gaaah! I believe this portrays the problem pretty well. Most likely your desktop never looks this bad, but that’s because you tend to close windows you believe you no longer need, exactly to avoid this kind of situation. But at what cost? Think back for a second how often the following thought went through your head: “If only I hadn’t closed that before.”. We lose a lot of time re-initializing a working context which we already set up before, be it one hour, one day, or a month ago. But that’s not all. Computing has become ubiquitous. We don’t just use one device, but several. We don’t keep documents to ourselves either, we share them. Managing applications and documents has become a task in it’s own right; a repetitive, distracting, possibly unnecessary task. I hate unnecessary repetition.

Proponents of Activity-Based Computing feel a lot of this overhead can be eliminated by using activity as the basic computational unit, instead of the file or application. Activity, as defined in activity theory, is seen as “a system of human “doing” whereby a subject works on an object in order to obtain a desired outcome.” This takes into account the entire setting in which the activity takes place; the tools used, the people you communicate and share resources with, the rules governing the community and how work on the activity is divided between people. Activity being a computational unit implies you can open, close, save and manage activities, not too dissimilar as to how you use files now. “The end-user is directly supported by computational activities which can be initiated, suspended, stored, resumed, and shared on any computing device in the infrastructure at any point in time, handed over to other persons, or shared among several persons.”

Humans perform plenty of activities, and thus within existing ABC systems the question arised how to manage them. The concept I explored in my thesis was to provide an overview of activities in time and space, showing when work was done on them and their inner relationships. I argue it is a worthwhile path to explore using a calendar not only to plan your activities, but also to use them. My prototype works towards this integration of activities as a computational unit managed on a calendar. Since the start of this month I started work as a research assistant at the IT University of Copenhagen where I will be researching how ABC can be used by software developers, specifically in software companies with distributed teams, following agile software development. Exciting times are ahead!

Conditional project or library reference in Visual Studio

In case you were wondering why you haven’t heard from me in a while, I’ve been busy, which isn’t really of much importance unless you know me on a personal level. What is relevant is that I recently graduated with a master in Game and Media Technology and am now in the process of making the project which I have been working on for my thesis open source. I’m very anxious to announce it, so you’ll read a lot more about it in the near future.

The project uses two of my other open source libraries, located in separate repositories. Adding these projects to the solution and referencing them as project references has the advantage of easier debugging and facilitates making changes to them. However, I do not want to force anyone interested in making changes to the main project to having to download the other repositories as well. Therefore I opted to use DLL references. This has one major downside. Whenever I do make changes to one of the dependent libraries, I need to manually copy the newly compiled DLLs to the main project. Wouldn’t it be easy to use two separate solution files, one with project references, and one with DLL references?

The first problem you’ll encounter is project references aren’t stored in the .sln file but in the .csproj file, which makes sense really. Since the .csproj file is shared by both solutions, we’ll have to conditionally reference either our DLLs or our projects, depending on which solution the project is opened in. This is possible using MSBuild, but you will need to create a new project configuration. Setting the configuration of the project differently in one solution from the other allows you to differentiate between the two of them. The following is part of a .csproj file which conditionally loads a reference by checking whether the project configuration is set to ‘Debug With Project References’.

  <Choose>
    <When Condition="'$(Configuration)' == 'Debug With Project References'">
      <ItemGroup>
        <ProjectReference Include="..\SomeProject\SomeProject.csproj">
          <Project>{6CA7AB2C-2D8D-422A-9FD4-2992BE62720A}</Project>
          <Name>SomeProject</Name>
        </ProjectReference>
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <Reference Include="SomeProject">
          <HintPath>..\Libraries\SomeProject.dll</HintPath>
        </Reference>
      </ItemGroup>
    </Otherwise>
  </Choose>

You could very well stop here, but I wanted to resolve another issue as well. Unless you follow a really strict folder structure, and force everyone else who wants to open your solution to do the same, the path used to reference the project can vary between people. Remember we are using separate repositories here, and the referenced projects aren’t included in the repository of the main solution, so relative paths don’t necessarily work. It is possible to specify the paths in an external ‘configuration’ file, and importing it into the .csproj file. Additionally, as a fallback when the project can’t be found at the given path, it is also useful to load the DLL instead. This way you can choose to load one or more, but not necessarily all references as a project reference.

The configuration file (ProjectReferences.txt):

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="$(Configuration) == 'Debug With Project References'">
	<SomeProject>..\SomeProject</SomeProject>
  </PropertyGroup>
</Project>

Segment from the .csproj file:

  <Import Project="..\ProjectReferences.txt" />
  <Choose>
    <When Condition="Exists($(SomeProject))">
      <ItemGroup>
        <ProjectReference Include="$(SomeProject)\SomeProject.csproj">
          <Project>{6CA7AB2C-2D8D-422A-9FD4-2992BE62720A}</Project>
          <Name>SomeProject</Name>
        </ProjectReference>
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <Reference Include="SomeProject">
          <HintPath>..\Libraries\SomeProject.dll</HintPath>
        </Reference>
      </ItemGroup>
    </Otherwise>
  </Choose>

Notice the project configuration check now occurs in the configuration file. The ‘$(SomeProject)’ property is only set when using the ‘Debug With Project References’ configuration, thus in all other scenarios the DLL will be loaded instead since the ‘Exists()‘ check will fail.

One last issue remains. We still need to manually copy the latest compiled DLLs to the ‘Libraries’ folder when changes were made for the solution which uses them to work as expected. We can exploit the fact that we now have the relevant project paths available in the configuration file. Using a post build event you can call a script which parses the XML data, and copies the DLLs to the correct location. This script should be called conditionally, only for the solution which includes the project references, and ideally also only for a Release build. I used a small Ruby script which offers a lot more flexibility than a Batch script.

The post build event:

if "$(SolutionName)" == "SomeSolution With Project References" if "$(ConfigurationName)" == "Release" ruby $(SolutionDir)UpdateLibraryDlls.rb $(SolutionDir)

Don’t Repeat Yourself as a Lifestyle

Yesterday I saw a truly inspiring talk by Bret Victor where he explains his guiding principle in life and work.

“Ideas are very important to me. I think that bringing ideas into the world is one of the most important things that people do. […] Creators need an immediate connection with what they are creating.” – Bret Victor

It’s quite a lengthy talk, but the crux of it doesn’t boil down to just this principle. He goes on to describe why he follows this principle. What motivates him.

“When I see a violation of this principle, I don’t think of that as an opportunity. […] Ideas are very precious to me, and when I see ideas dying, it hurts; I see a tragedy. To me it feels like a moral wrong, it feels like an injustice, and if I think there is anything I can do about it, I feel it is my responsibility to do so; not opportunity, but responsibility.” – Bret Victor

Although Bret spends a great amount of time demonstrating some very imaginative interfaces, the bottom line of the talk isn’t about him showing off his principle, but meant to inspire you in finding your own, and why technology can play an important role in that.

“As a technologist you can recognize the wrong in the world. You can have a vision for what a better world could be, and you can dedicate yourself to fighting for a principle. Social activists typically fight by organizing, but you can fight by inventing.”

“I’m not saying you that you have to live this way. I’m not saying that you should live this way. What I’m saying is that you can, that this lifestyle is an option that’s available to you.” – Bret Victor

Only this morning I realized what this principle could be for me.

The DRY (Don’t Repeat Yourself) principle states: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. – The Pragmatic Programmer

I’ve always held this fundamental software development principle in high regard, but just as the original intent of the statement wasn’t solely about preventing duplicate code I realize now I assign even more importance to it. For me it transcends software development.

I’m writing this while I’m on the train, on my way to work. I spend quite a lot of time on train travel, having to go from Belgium, to The Netherlands and to England. It’s mind-numbing having to take the same routes over and over again, week after week, but the ability to work or read while I do so helps me cope with that. Doing the same trips by car would drive me insane. It’s only one of the many indications in life which cause me to believe that repetition is a cause of dread.

Although I didn’t interpret it as such before, the past few years it has been my personal goal to attempt eliminating any form of repetition. Everything I feel strongly about revolves around eliminating the need to do the same things over and over again. From changing the way a community works by working towards a more constructive environment in which to have discussions so arguments no longer need to be repeated over and over again, to eliminating the need of ever having to write an unnecessary piece of code again. The thesis I am currently working on is inspired by the fact that people waste too much of their time managing and switching between different activity contexts. It’s repetitive work which could be solved by using an Activity-Based Computing system.

The wonderful thing about technology is that it’s a perfect enabler to attain that goal, but I realize now it is not only what defines me as a developer, but also as a person. Some people might call me lazy because I don’t like doing daily chores. They might be right, I rather work on things which prevent me from having to do something ever again. I like my work as much as I do because it’s non-repetitive by nature, unless you end up in a mindless work environment where you are considered to be nothing more than a Code Monkey.

I believe I found my personal guiding principle, what’s yours?

Null Checks for Event Handlers, an Aspect Solution

There is no denying events in C# are a great step forward from more traditional approaches where a lot of boilerplate code needed to be written. I choose C# events over Java’s solution to the Observer pattern any day.

… but, there is one pesky little issue I have with them. By design, it’s really easy to introduce bugs using them. How often have you encountered a NullReferenceException because you didn’t check whether an event handler was null prior to calling it? As a more experienced developer you might choose one out of the following two options.

1. Repeated null checks

Always check whether an event isn’t null prior to calling it. Additionally, you need to copy the event handler to a local variable, otherwise another thread might unsubscribe from the event causing the handler to be null again after you did the null check.

EventHandler handler = SomeEvent;
if ( handler != null )
{
    handler( ... );
}

2. Always subscribe one empty delegate

There might be a small cost of constantly having to call one extra function when the event is raised, but it solves the problem of having to do repeated null checks throughout the code while simultaneously solving the multi-threading issue.

public event EventHandler SomeEvent = delegate {};

The Aspect way

I prefer the second approach, and don’t see any reason why it shouldn’t be used by default, other than a smarter compiler which could take care of this in a ‘cleaner’ manner. That’s why over the weekend I’ve spent some time seeing how PostSharp could help solving this cross-cutting concern. I always love showing off the result prior to explaining how I got there. It’s usage is a one liner.

[assembly: InitializeEventHandlers( AttributeTargetTypes = "Laevo.*" )]
namespace Laevo { ... }

Adding this one attribute prevents you from having to worry about events throughout the entire namespace it applies to.

How does it work?

First of all, you will need PostSharp. That’s not necessarily a bad thing, because if you are fortunate enough to be allowed to use it, or you can simply decide for yourself to buy it, you will greatly appreciate it for more than just this one possible use case.

The InitializeEventHandlersAttribute is called an aspect which is applied on events. However, using a feature of PostSharp called ‘multicasting’, you are able to apply the attribute (MulticastAttribute) on higher level elements, allowing you to choose which one of the lower level elements the aspect should apply to. In the code above, the aspect is applied on an entire assembly, but the aspect knows it should only be applied to events, which is further narrowed down using the AttributeTargetTypes parameter to events within the namespace “Laevo”, and all sub-namespaces. In order to remind the developer that a certain part of his code is enhanced by an aspect, a visualization as follows is visible within Visual Studio.

The code is short enough to paste in its entirety now, but I’ll decompose it in a minute.

[AttributeUsage( AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Event )]
[MulticastAttributeUsage( MulticastTargets.Event, AllowMultiple = false )]
[AspectTypeDependency(
    AspectDependencyAction.Commute,
    typeof( InitializeEventHandlersAttribute ) )]
[Serializable]
public class InitializeEventHandlersAttribute : EventLevelAspect
{
	[NonSerialized]
	Action<object> _addEmptyEventHandler;

	[OnMethodEntryAdvice, MethodPointcut( "SelectConstructors" )]
	public void OnConstructorEntry( MethodExecutionArgs args )
	{
		_addEmptyEventHandler( args.Instance );
	}

	IEnumerable<ConstructorInfo> SelectConstructors( EventInfo target )
	{
		return target.DeclaringType.GetConstructors(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
	}

	public override void RuntimeInitialize( EventInfo eventInfo )
	{
		base.RuntimeInitialize( eventInfo );

		// Construct a suitable empty event handler.
		MethodInfo delegateInfo = DelegateHelper.MethodInfoFromDelegateType(
                    eventInfo.EventHandlerType );
		ParameterExpression[] parameters = delegateInfo.GetParameters().Select( p =>
                    Expression.Parameter( p.ParameterType ) ).ToArray();
		Delegate emptyDelegate = Expression.Lambda(
                    eventInfo.EventHandlerType, Expression.Empty(),
                    "EmptyDelegate", true, parameters ).Compile();

		// Create a delegate which adds the empty handler to an instance.
		_addEmptyEventHandler = instance => eventInfo.AddEventHandler( instance, emptyDelegate );
	}
}

The steps I followed to create this aspect are documented in the PostSharp 2.1 Documentation “Adding Behaviors to Members”.

  1. Create a new class, deriving from the relevant aspect class. Since I am creating an aspect which is applied on events, I used EventLevelAspect.
  2. Choose on which part of the code your aspect will have effect. This is called an ‘advice’. Although my aspect is applied on events, the solution I used is to add an empty event handler to the events by default. This is something which can be done from the constructor. Therefore I had to use an OnMethodEntryAdvice in order to add this code to the beginning of every constructor.
[OnMethodEntryAdvice, MethodPointcut( "SelectConstructors" )]
public void OnConstructorEntry( MethodExecutionArgs args )
{
	_addEmptyEventHandler( args.Instance );
}
  1. Choosing a ‘pointcut’ is required to determine where the code needs to be added. We’ve already established it needs to be added to the start of methods by using OnMethodEntryAdvice, but we haven’t established which methods it needs to be applied to yet. By using a MethodPointcut, this task is delegated to a separate method of which you pass the name. In my case, this method doesn’t do much more than returning all the constructors of the current type.
IEnumerable<ConstructorInfo> SelectConstructors( EventInfo target )
{
	return target.DeclaringType.GetConstructors(
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
}
  1. We are nearly done, although there is one part of the code I skipped over which is quite interesting nonetheless. The OnMethodEntryAdvice calls the delegate _addEmptyEventHandler(), but where did this come from? Overriding RuntimeInitialize gives you the chance to initialize objects which the advice will require for the specific element the aspect applies to. Using reflection to analyze the passed EventInfo object, a suitable empty event handler can be constructed using Expression Trees. This is required since we don’t have the luxury of using an equivalent to ‘delegate {}’. Finally a simple delegate is created which can add the empty delegate to the event of any given instance.
public override void RuntimeInitialize( EventInfo eventInfo )
{
	base.RuntimeInitialize( eventInfo );

	// Construct a suitable empty event handler.
	MethodInfo delegateInfo = DelegateHelper.MethodInfoFromDelegateType( eventInfo.EventHandlerType );
	ParameterExpression[] parameters = delegateInfo.GetParameters().Select( p => Expression.Parameter( p.ParameterType ) ).ToArray();
	Delegate emptyDelegate
		= Expression.Lambda( eventInfo.EventHandlerType, Expression.Empty(), "EmptyDelegate", true, parameters ).Compile();

	// Create a delegate which adds the empty handler to an instance.
	_addEmptyEventHandler = instance => eventInfo.AddEventHandler( instance, emptyDelegate );
}

… and all that just to eliminate ‘= delegate {}’? Yes, I can be quite stubborn sometimes. 🙂

UPDATE:

This code has since been slightly altered in order to also support events with generic parameters within generic types. Thank you Anupheaus, for reporting this issue! Be sure to check out the latest code on github. A discussion of the problem, and how to work around it can be found in my answer on Stack Overflow.

Aspects and Garbage Collection

Earlier today I wrote about an Assert method which can be used in unit tests to check whether or not an object is collected during Garbage Collection (GC). I wrote this method because I was suspicious about a certain PostSharp Aspect I just implemented. The aspect works great, and I’ll surely write about it later; however, since it’s an aspect which is meant to be applied on an entire assembly by using multicasting, I thought twice before calling it a day.

After being skeptical and writing unit tests to ensure my IsGarbageCollected() method was actually working as expected, I came to the unfortunate conclusion that my aspects were keeping my objects in memory!

It only makes sense really; why wouldn’t aspects be able to keep objects alive? It might not be the first thing you think about, but hopefully this post makes you aware of the hidden dangers. As an example I’ll show you a very basic aspect, and how to fix it.

[Serializable]
public class SampleAspect : IInstanceScopedAspect
{
	[NonSerialized]
	object _instance;

	public object CreateInstance( AdviceArgs adviceArgs )
	{
		_instance = adviceArgs.Instance;
		return MemberwiseClone();
	}

	public void RuntimeInitializeInstance()	{ }
}

As any other memory leak, it suffices to leave one reference lying around to an object, preventing the GC from collecting it. There are two mistakes in the previous code, can you find them?

The first one was most obvious to me. _instance is holding a reference to the object, keeping it alive. Luckily .NET offers us an easy solution, WeakReference. A WeakReference references an object while still allowing that object to be reclaimed by garbage collection.

[Serializable]
public class SampleAspect : IInstanceScopedAspect
{
	[NonSerialized]
	WeakReference _instance;

	public object CreateInstance( AdviceArgs adviceArgs )
	{
		_instance = new WeakReference( adviceArgs.Instance );
		return MemberwiseClone();
	}

	public void RuntimeInitializeInstance()	{ }
}

However, Gael was kind enough to quickly point out this wasn’t the real issue. PostSharp uses prototypes to initialize its aspects. An existing prototype object is cloned to create new aspects. The CreateInstance() method is called on the prototype object, and you are expected to return a new aspect. The real error in my code was I was setting _instance on the prototype, while I should be setting it on the cloned object instead. The prototype object is kept in memory by PostSharp, and as a result the last created object was also held in memory. Not a big issue, but the following implementation is a bit cleaner.

[Serializable]
public class SampleAspect : IInstanceScopedAspect
{
	[NonSerialized]
	object _instance;

	public object CreateInstance( AdviceArgs adviceArgs )
	{
		var newAspect = (InitializeEventHandlerAspect)MemberwiseClone();
		newAspect._instance = adviceArgs.Instance;

		return newAspect;
	}

	public void RuntimeInitializeInstance()	{ }
}

No need to use WeakReference any longer, although I imagine it might still be useful in other scenarios.

Garbage Collection Unit Test

Unit tests are useful in order to guarantee code works as it is expected to work. Today my spidey sense told me I might have caused a memory leak. Let’s not consider unmanaged code for now, but wouldn’t it be great if you could write a unit test to prove that a particular object can be garbage collected? I found some interesting ideas online, but no reusable solution. What follows is my attempt at an Assert method which can be used during unit testing.

object empty = new object();
AssertHelper.IsGarbageCollected( ref empty );

It works by using a WeakReference, which references an object while still allowing that object to be reclaimed by garbage collection. The object to test is passed using the ref keyword, which allows the Assert method to set it to null. This allows it to be garbage collected.

public static void IsGarbageCollected<TObject>( ref TObject @object )
	where TObject : class
{
	Action<TObject> emptyAction = o => { };
	IsGarbageCollected( ref @object, emptyAction );
}

public static void IsGarbageCollected<TObject>( ref TObject @object, Action<TObject> useObject )
	where TObject : class
{
	if ( typeof( TObject ) == typeof( string ) )
	{
		// Strings are copied by value, and don't leak anyhow.
		return;
	}

	int generation = GC.GetGeneration( @object );
	useObject( @object );
	WeakReference reference = new WeakReference( @object );
	@object = null;

	GC.Collect( generation, GCCollectionMode.Forced );
	GC.WaitForPendingFinalizers();

	Assert.IsFalse( reference.IsAlive );
}

As it turns out I did write a memory leak in the code I wanted to test. 😦 At least I know about it now! As usual, I added the total code and some unit tests to my FCL library.

WARNING: Due to differences when using the Release configuration (I assume compiler optimizations), some of these unit tests will fail. Be sure to run them in Debug!