Hibernating Rhinos

Zero friction databases

One click install NuGet Package and Console Applications

We started to provide NuGet packages for some of our profilers about 2 months ago. It’s provided you with a great one click install experience: all you have to do in order to start profiling your application is to install the NuGet package of the appropriate profiler and that’s it. The profiler application is opened up for you and your application is set up, all you left to do is to actually go to business and start profiling your application. This is a great on install experience, that we are proud to provide you with.

This is our currently provided NuGet packages:

But we did have one problem with it. It didn’t work well with non-web based applications. That’s because that the way to provide one click install experience with NuGet packages is by using a package named WebActivator. You can read more about the way that WebActivator works here, but in nutshell, it provided the package with a way to specify the method that should be run as part of the web application start process, by specifying an assembly attribute like the following one:

[assembly: WebActivator.PreApplicationStartMethod(typeof($rootnamespace$.App_Start.EntityFrameworkProfilerBootstrapper), "PreStart")]

But as I mentioned, this is works only with web-based projects. When you use with non-web based application, like a Console Application for example, things are starting to get weird. This is because that the WebActivor has a dependency on System.Web.dll which non-web projects not include a reference to it be default. Even more, the default template for Console Application in Visual Studio 2010 uses the .NET Framework Client Profile which does not include the System.Web.dll in it. So when you create a console application and install one of the profiler’s NuGet packages you get a mysterious compilation error:

The type or namespace name 'WebActivator' could not be found (are you missing a using directive or an assembly reference?)

This error is confusing because if you’ll take a look on the references of your project you will see a reference to the WebActivator. The missing assembly reference is actually the System.Web.dll. But in order to add a reference to System.Web you have to target the Full .Net Framework in your project. But those are not recommended steps to do, since that if you’ll do them your project will compile fine but you gained nothing from the use of WebActivator since the code that takes care to initialize the profiler (the PreStart method) does not execute. This break down the one click installs experience of the NuGet package for non-web projects.

So how are we going to solve this? Let’s take one problem by one. The first problem was that non-web projects (specifically those that even can’t use it, like projects that use the .Net Framework Client Profile) cannot compile because of the call to WebActivator. The solution for this is simple. We drop the call to WebActivator assembly attribute in non-web projects.

This is done by the Install.ps1 script included in the NuGet package. In order to determine whether the current project is a web project or not we determine if the web.config file exists on the target project. If it’s not, that’s a good indicator that this is not web project and the call to the WebActivator.PreApplicationStartMethod is removed by the scripts' code.

This is important step to eliminate the confusing compilation error, but we have a second problem: the initialization code is never run and this break the one click install experience that we so want to provide. What will be the solution for this? Well, a simple solution may be is to drop a call to the PreStart method of the profiler bootstrapper in the start code or your application.

But where is exactly the application’s start code? This can be vary depends on the current project type (WinForms or WPF for example) and the user’s actual code structure. Covering all the option of where is code can be can be very hard task to do. So what we decided to do is to cover just the simple case of a default console application. If you have a console application with a Program.cs file, we’ll drop a call to the App_Start.PreStart method in your Main method (assuming it exists).

This will cover the very basic case of when you just want to see how to work with the profiler by creating a console application and installing the profiler’s NuGet package. In this case it can be acceptable to edit the user’s code by the NuGet script. But this won’t interrupt you in more advances cases when you use other types of non-web projects like WinFroms or WPF application.

This is how the NuGet packages behaving right now. We think that this fairly elegant solution for what we can do with the NuGet package and we want to hear from you how this is working out for you!

Tags:

Posted By: Fitzchak Yitzchaki

Published at

Originally posted at

Comments

 Yngvar Johnsen
09/09/2011 08:41 AM by
Yngvar Johnsen

It also depends on the Microsoft.Web.Infrastructure assembly, which I believe is part of the MVC framework, meaning that you'll get the same problems using the NuGet package in a non-MVC web project, such as a WCF web service project, so rather than trying to detect whether it is a web project or not, perhaps the script could be less smart, and only be run when the user decides to remove dependencies to WebActivator?

Comments have been closed on this topic.