One of the features is Razor compilation on build, enabling catching more errors at design time and improved startup time. This however broke one of my apps.
After updating the app to 2.1, navigating to a Razor view met me with the following error:
Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException: One or more compilation failures occurred: (0,0): Error RZ3007: Targeted tag name cannot be null or whitespace. at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorViewCompiler.CompileAndEmit(String relativePath) at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorViewCompiler.OnCacheMiss(String normalizedPath) --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorPageFactoryProvider.CreateFactory(String relativePath) at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.CreateCacheResult(HashSet`1 expirationTokens, String relativePath, Boolean isMainPage) at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.OnCacheMiss(ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey) at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.LocatePageFromViewLocations(ActionContext actionContext, String pageName, Boolean isMainPage) at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.FindView(ActionContext context, String viewName, Boolean isMainPage) at Microsoft.AspNetCore.Mvc.ViewEngines.CompositeViewEngine.FindView(ActionContext context, String viewName, Boolean isMainPage) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.FindView(ActionContext actionContext, ViewResult viewResult) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result) at Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) at MediaServer.Startup.<>c__DisplayClass5_0.<<Configure>b__0>d.MoveNext() in /Users/sankra/projects/MediaServer/MediaServer/Startup.cs:line 104 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware:Error: An unhandled exception has occurred while executing the request.
While working on a particular project built with a multi-stage Dockerfile I got this error:
Step 13/19 : RUN dotnet test "./DashboardServerTests/DashboardServerTests.csproj" -c Release --no-restore ---> Running in ac850e55464c Build started, please wait... /usr/share/dotnet/sdk/2.0.3/Sdks/Microsoft.NET.Sdk/build/Microsoft.PackageDependencyResolution.targets(323,5): error : Assets file '/Users/sankra/projects/DashboardServer/Grafana/obj/project.assets.json' not found. Run a NuGet package restore to generate this file. [/source/Grafana/Grafana.csproj]
Lately. I’ve written multiple web applications with ASP.Net Core. Together with C# newfound cross-platformness, this stack is a joy to work with.
I user Docker to run the applications, some in Azure, some on on-premise Linux boxes. This has thought me a couple of things. Firstly, the app should be built from within a container using a multi-stage
This happened a while ago, but might be relevant again in the future.
I created a website using ASP.Net Core and ran it through a Docker Container.
$ docker run kitchen-responsible
Worked perfectly for a long time, but after updating a nuget package it started to fail with:
Error: An assembly specified in the application dependencies manifest (KitchenResponsibleService.deps.json) was not found: package: 'Microsoft.AspNetCore.Antiforgery', version: '2.0.1' path: 'lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll' This assembly was expected to be in the local runtime store as the application was published using the following target manifest files: aspnetcore-store-2.0.3.xml
I needed a method in C# to get the number of milliseconds since the start of Unix time.
Unix time (also known as POSIX time or UNIX Epoch time) is a system for describing a point in time, defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, minus the number of leap seconds that have taken place since then.
This is the
DateTime extension method I came up with:
I needed a method in C# to split a list or an array into multiple parts for batch processing. This is the
IEnumerable extension method I came up with:
Comics Downloader is a dotnet script that will download comics from comics.io. It will start with a specified strip and continue until all strips are downloaded for the given comic. It can also optionally combine them into a .cbz-file, a comic archive.
View the source on GitHub.
I’m updating my Golden Ratio Calculator app to be ready for iPhone X.
The app is built using Xamarin Forms. After updating the packages and building the solution, I tried running it on my iPhone 7 with iOS 11. This error was the result:
Xamarin.iOS: Fatal error: failed to load the class 'ObjCRuntime.Runtime'
After getting zero hits on Google, I deleted the
obj folders and rebuilt the app.
Success, as if by magic.
The old adage from the IT Crowd still holds true.
Azure Blob Storage is persistent cloud data storage for any kind of unstructured data. Slack Profilebot uses this service to store a whitelist of users with incomplete profiles that should not be reminded to update their profiles. Every user is represented by a file containing that user’s id. This is complete overkill, I know, but it served a purpose. It taught me both how to use and test Blob Storage.
I’m creating a new Xamarin Forms app using a PCL-project for shared code and an iOS project for the iOS specific details. After a short hiatus, I upgraded to Visual Studio for Mac version 7.0.1 for a nice morning of coding. No such luck, the iOS project would not build.
In a large Slack team, it’s important that user profiles are completed enough for the users to recognise each other. Profilebot is a simple bot used for validating Slack user profiles. It is written in C# and it’s easy to extend for all your profile checking needs. It runs out of the box either as a console app (Windows) or a Windows service.
See the source on GitHub.
We’ve lately rewritten our build systems at work using scriptcs. Scripts with C# as the language with full access to the rest of .Net. Aka PowerShell as it should have been. This rewrite has been awesome for several reasons:
- Ease of use: Since we’re a C# shop, writing the build system in scriptcs is both convenient and time saving. I still remember TFS 2012 XAML based builds with dread.
- Flexibility: The build system is build server agnostic, the same script can be used on Team City, TFS, locally or on any other server
- Ownership: The build system is now so trivial that every team can easily understand and extend the system when needed. The build system becomes part of the product, not something the other guys do.
- Server or local? Same, same: The same scripts are used locally and on the server. The previous XAML based builds were an opaque mess.
After releasing a new version of Golden Ratio Calculator, I decided to compile my XAML code to increase performance. I followed this guide from Xamarin and triggered compilation of all XAML in the assembly by adding the following to my
The 2014 book Writing High-Performance .NET Code contains tips on coding effective C#, above and beyond the Zen of Performance. It made me consider the usage of value types,
struct instead of
struct for small structures, we achieve less memory usage, better memory locality and fewer garbage collections. Arrays of structs have good memory locality, utilising the CPU caches and improving performance due to more cache hits.
Everybody loves Mads and Dustin. The line was forming even 30 minutes before the session. The first session of the day.
A big year. Began talking publicly about C# 6, released and open sourced Roslyn, released .Net Core libraries and runtime as OSS on GitHub. OSS all the things!
Visual Studio 2015
The C# stack in Visual Studio 2015 has been completely rebuilt. Everything is a little bit better. And shinier. The IDE has stolen most of ReSharper best features and made them available out of the box. This is a good thing and I’m writing these words wearing a ReSharper t-shirt.
Code actions will show previews before you complete them. An improvement over ReSharper’s implementation. Potential conflicts that would come as result of the actions are visualized. Modal dialogues are also used less.Refactoring preview in action.
Anyone can build code analyzers, and they can even be shipped together with the code the should analyze. For instance, ship analyzers for ImmutableArrays together with Immutable Collections nuget packages.
Static usings simplify access to static members. Console WriteLine can be called as WriteLine with using static System.Console.
Immutable types are awesome. Auto properties can now be readonly, same as with normal member variables. Only declare getters and you’re set. They can even be initialized directly.
Expression bodied members can skip the return statement and curly brackets, using the lambda arrow instead. Makes for more readable code when dealing with small methods. Thanks for the inspiration F#!Simplify all the things!
String.Format can be converted to an interpolated string. Prefix the string with an $ and write your format string. Expressions can be used, not just values.
nameof(whatever) gives you the name of the variable. Useful when creating argument exceptions or in databinding.
Null conditional checks can be written with ?., an inline null check. It even supports indexers. No more foo == null boilerplate!
Object initializers can now initialize to an index, not only members.Focus on the important bits, less cruft.
The team became smarter with time, an await can now be used inside catch and finally blocks. It just works!
Exception filtering is supported using the when keyword. Less logic in the catch block.
Edit and continue is back and works even if you use new language features. You can code freely while stopped at a breakpoint, even create new types. Visual Studio 2015 still gives you Intellisense and the code actions and refactorings works!
Lambdas and LINQ can be used in the watch and immediate windows. Impressive, the language is even useful during debugging.
The C# Essentials is a useful extension, helping you use the new languate features.
Future stuffA playground without equipment.
C# interactive window will be back with full Intellisense. Xamarin and Swift, you’re not alone! Not as feature rich as the Playgrounds of other languages, yet at least. Roadmap is available on GitHub. Though a REPL is still useful without visualizations.
The design notes of C# 7 is on Github. They’re issues tagged as Design Notes. Modern languages have greater potential to help the programmers being more productive and less error prone, such as nullability tracking or tuple types.I love the new open Microsoft.
A code-aware library is a library that provides guidance on correct use through embedded tooling and operates on the user’s code in real time.
This is the spiritual successor to FXCop. The most useful rules are already available on nuget.The future is here.
The analyzers are also run inside the preview window.Real preview!
By installing the C# essentials extension, an analyzer with a code fix project template is available. The boiler plate is a type name checker which checks that all types start with upper case letters. It also supplies an action to camel case the names. Such a project can be debugged, starting a new session of Visual Studio 2015.
Your first decision is what languages the analyzer should support. I recommend C#, off course.
The AnalysisContext contains the state of the analyzer, will be huge. You can write your code at debug time to better understand the content. Thanks edit and continue. “It now actually works”.It's just code :)
For code fixes, a CodeFixContent context is provided. Using async operations to prevent blocking the UI thread.
Roslyn syntax tree visualizer will help with the code generation in the fixes. The Roslyn syntax APIs are immutable.
If your action do not appear in Visual Studio 2015, delete the ComponentModelCache (MEF cache) to force a refresh.
XAML is the way for creating UIs for Windows 10 apps. Both for C#, C++ and other good languages. No special project types for mobile or table, only Universal App. Microsoft is all in. Even the Windows start menu is built using XAML.XAML is the way.
Controls are updated to give a more uniform look and feel across the different devices. And creating experiences native to each device.
Your views will still ned to be created separately for each platform, but the same controls can most likely be used.
Responsive view development is easer than before. XAML has its equivalent of media queries, visual state triggers. The designer will help you in the futures, but it’s not done yet.
Relative Layout is back using RelativePanel. Enabling complex layouts without losing scaling support or using multiple different layout panels. Also, more panels means less performance.It's nice to have an alternative.
XAML performance is better in Windows 10. Coding the Windows shell using XAML showcased a lot of slow paths.
Compiled bindings are more performant than the regular bindings which uses reflection internally. And you get compiler errors when the binding name is wrong! And you can wire up event handlers without going through commands. And you can step through your bindings in the debugger.Yes!
Composable 3D Transforms can give fancy effects with very little XAML. Use it sparingly.Just because you can, doesn't mean you have to.
XAML can be used as custom window chrome. No more crazy Win32 hacking.Remember to stand out from the crowd. Or don't.
InkCanvas makes ink based applications easier, but not necessarily more useful.Or write it on a piece of paper.
The new Edge browser is the new XAML WebView. If all your customers takes advantage of the free Windows 10 upgrade… For everybody else, there is still CEF (Chromium Extension Framework).
Debugging the visual tree is available in Visual Studio 2015 without third party tools. Values can be changed and the results seen during runtime. Perfect for rapid UI prototyping.Snoop, you are no longer needed.
Debugging is hard, time consuming less fun than writing the program correctly the first time. Thus, I’ve never tried debugging myself. For my readers:
You can start debugging a process directly by using “Step Into” before a process has started. Useful if you don’t know where a programs entry point is.
Return values of methods are now visible in the Locals window. No more local variables created just for debugging purposes.
When you have multiple method calls on a line, you can “Step Into Specific” to choose which method to step into. A timesaver if there ever was one.
Using the Call Stack, you can select a point in the program and “Run to Cursors” to step into that point.
WPF now has its own debugger visualizer. It’s easy writing your own visualizers for your own data structures.
Use the DebuggeDisplay attribute to change your class’ visualization in the debugger. No more unneeded ToString declarations.
Pinning values during debugging also makes them available after debugging has finished. The debugger helps even when it’s not running.
Visual Studio 2015’s debugger now supports lambda expressions, both in the watch windows and in edit and continue. Hello LINQ!
Breakpoints with configured Actions are powerful and can now be created without opening a modal dialog. Progress. Automatic continuation enables advanced logging without littering your code with temporary logging statements.
Break when thrown now has a search box, making it easier to break at the source of exceptions without breaking the F5 key.
Other goodies:Profiling is awesome Timings are awesome My favourite feature of the future Who would want this?
Continued innovation without breaking existing stuff is one of the major drivers to increase the modularity of the .Net ecosystem. Modular and Optimized is the mantra, making the frameworks useful in our cross-platform future.
The .Net Framework 4.6 if the compatible in-place replacement for .Net 4, 4.5, 4.5.1 and 4.5.2. WPF is the UI stack for classic desktop apps. Still. .Net 4.6 and WPF contains many performance and reliability fixes. Should now render properly on retina screens.One of these will soon be legacy.
WPF tooling in Visual Studio 2015 is much improved. It contains Blend, UI profiling and diagnostics tools, and a UI Debugger. Less need for third party tools, and no more excuses for not doing memory and performance profiling.
Good stuff. Desktop apps might be legacy, but also 90% of all apps running on Windows on a day to day basis. They will live on for a long time yet. Windows 10 will be the next Windows XP, a baseline which we can build upon in the future.
Roslyn is now open source, using the compiler as a service has never been easier.
.Net Native is used in universal apps when compiled in Release mode. The compilation gets another step, the VC++ compiler. Thus you get native performance, and managed productivity. Faster startup, less memory usage, better performance.
Microsoft continues its partnership with Xamarin and Xamarin’s tooling is neatly integrated in Visual Studio. Even the iOS and Android visual designers. You still have the choice between Portable Class Libraries or Shared Libraries for your cross-platform common code.Nothing like a Mac in a Microsoft conference.
ASP.Net 5.0 is cloud-ready and the micro-services book has been read. Smaller footprint and more modular implementation. Nuget is used to import the different functionality. You need only what you use. Since .Net Core 5 can be run in-app, side by side with other versions of .Net, you need this .Net version to get the full feature set.
As with all other modern things, dependencies are defined in a .json-file, enabling collaboration with non Visual Studio users.
.Net Core 5 on Linux is deployed side by side with your application. XCopy deploy FTW, also for a framework. No UI-stack. Yet.
Porting .Net Core 5 to Linux and OS X took 6 months.The Apple logo show by a .Net application running on Ubuntu.
I'm writing my next game, Icarus - Escape from Crete, using Xamarin iOS together with SpriteKit. The combination works great and SpriteKit turns out to be a well thought out API. My only gripe so far is that I haven't found an existing way for tiling a sprite texture, that is fill the entire sprite using a smaller texture.
The grass below is just a small image, repeated to fill the entire green meadow.
The grass is created from this simple tile
using an extension method on
Using CoreGraphics, an image of the proper size is created and the texture is tiled. Next the image is rendered and a
SKTexture is created from the result.
Here's the example from Icarus:
This method has two disadvantages though.
- It's slow. Create the needed nodes during game loading, not during gameplay.
- The resulting image is flipped. Remedy this by either using a flipped image as the tile, or flip the Y-axis on the
SKSpriteNodeafter the texture is applied:
grass.YScale = -1f;I use the former.
Even with the disadvantages, the method was useful in Icarus. Maybe it's useful for you too 😃
I needed a way to get a color between two colors given a ratio while working on the 1.1 version of Golden Ratio Calculator. I use it to show a color between blue and gold, then gold and silver, and lastly between silver and blue.
The start and end colors are represented as arrays of RGB ratios, but this is easy to work with.
Either get the RGB-ratios from a UIColor:
Or create the array directly:
UIAlertView has been deprecated by Apple from iOS8. From now on, UIAlertController is the way to go.
UIAlertController is surely an improvement, but given the asynchronous nature of displaying alerts to the user, I wanted to use the API together with async and await.
Below is a screenshot of what I wanted to accomplish:
A simple menu with two options and a Cancel-button.
By using a TaskCompletionSource, I can accomplish this using async and await.
TaskCompletionSource can be used to map an external asynchronous operation onto a normal C# Task. We can then use this task as we would any other.
In this case, the result of this task is the Enum
CustomerFeeling with values corresponding to the users happiness. Thus,
ShowRatingDialogAsync can be used like this:
The choice of the user can be awaited and
UIAlertController now fits in perfectly with the rest of the C# code.
FermiContainer gains features, but while doing so becomes even more simple. How is this possible? Let me tell you:
Automatic resolving of constructor arguments
Through constructor injection, the dependencies known to the container are automatically resolved. No attributes or XML configuration are needed.
Default container instance
Easier to extend
The Services dictionary is now protected so FermiContainer is easily extendable.
C# expressions makes FermiContainer very performant.
Available as source through NuGet
PM> Install-Package FermiContainer.Sources
What the world needs most is more IoC containers in the .Net space.
So I created FermiContianer, the simples IoC container imaginable.
It supports registering implementations of interface using either a default constructor or a factory method.
Resolve gives you a new instance each time.
Singleton will return the same instance.
PM> Install-Package FermiContainer
If FermiContainer ever becomes too simple for your needs, I recommend LightInject.
I've lately been evaluating CefSharp to use as an embedded browser in an old Windows Forms project.
The examples are great and the packages from nuget are easy to use, but I ran into an annoying issue. The content of the loaded page was sometimes grey. Nothing but grey. However, when I resized the embedded browser window, the page appeared. Just as it should. What is going on here?
The browser-control was added to the Form in a normal fashion:
The appearance of the page content after resize was a clue. Perhaps the content was loaded correctly, but the control was too small to show it? Curious that DockStyle.Fill didn't do the trick as it usually does, but worth a try:
Now the browser always has the correct size and all is well, or rather, as well as can be while working with Windows Forms...
Scan a book
Buy it if you want
View all scanned books
My new app Book Scanner, also known as Book Barcode Scanner is now available worldwide on the App Store.
Book Scanner scans ISBN-barcodes and finds the books on iBooks. The app remembers your scanned books and you can buy them on iBooks at your convenience. Scanning book barcodes is faster than a manual search and the it's very useful in bookstores and other places with a lot of books.
Book Scanner is available free on the App Store and is of course written in C# using the Xamarin stack. I've learned a lot while writing this app, and I will share some of it here on this blog.
tl;dr: AsyncMethodCaller is used to call methods asynchronously. Execution will continue with other methods after the asynchronous call completes. Use this if you cannot use async and await to easily make testable asynchronous calls. Very useful in ViewModels.
C# has over its lifetime accumulated many asynchronous programming models:
Before async and await, background workers have long been a preferred method for making asynchronous calls and creating non-blocking UIs in MVVM ViewModels. This is a simple example:
Unfortunately, this practice has a couple of obvious deficiencies:
- Testing the correctness of the asynchronous execution is not straight forward and often involve inheriting from the View Model
- The code is verbose and the program flow can be hard to follow
- Multiple BackgroundWorkers might be needed if different asynchronous operations are to be supported
The obvious solution is using async and await from C# 5. C# 5 does not support Windows XP however, making this solution unattainable for many organizations.
Therefore I created AsyncMethodCaller. AsyncMethodCaller is used to call methods asynchronously and continue with other methods after execution completes. If you cannot use async and await, it makes asynchronous calls easy to understand and test.
The example from before can now be rewritten, with unit tests!
AsyncMethodCaller thus gives you the following advantages:
- The asynchronous code is isolated from the ViewModel-logic
- The code can be tested without inheritance, using tests before, under and after the asynchronous call
- Program flow is easy to follow
- Only one AsyncMethodCaller is needed
PM> Install-Package AsyncMethodCaller
Consider the following code:
Run this test today and it will pass, but it has one obvious flaw. Can you spot it?
The test will fail on the same day once a year, on the person’s birthday.
“But Runar”, you say, “this only happens once a year and the test can be corrected in a couple of minutes.”
That is true, but remember that this test does not live alone. In any non trivial product where the development organization has practiced some kind of automated testing, it will be one of 10,000s. In a product of with 50,000 tests, 5 tests will fail daily if the failure rate is as low as 0.01%. An unacceptable waste of time.
A unit test is defined in The Art of Unit Testing as a test that:
- Is automated and repeatable.
- Is easy to implement.
- Remains for future use once it’s written.
- Is runnable by everyone.
- Is run at the push of a button.
- Runs quickly.
The test is automated, but it is not a proper unit test given the criteria above. The persons age is dependent on the current date, and thus its result will vary.
Luckily, making the test more robust is easy using the D in the SOLID principles: Dependency Inversion. Extract the needed date and time operations behind an interface, make the dependency on that interface explicit and inject the dependency where it is needed.
The example below shows a suggestion for such an interface, IClock. Using a stub, the test will always pass regardless of the current date. I’ve used a manual stub here, but it can just easily be created using a framework like Moq.
A unit test should never depend on externalities that you do not control. Time is a prime example, and it should be encapsulated in a suitable abstraction. The IClock-interface is a proposal, another solution is using a mature time-framework such as Noda Time where this abstraction is already available.
The code for this post can be found on Github.
If you have a class using a method from one or more interfaces, you can use Moq to fake the behavior of the methods from the interface. Your code can still work with the class directly.
What is Moq
Moq is a powerful mocking library for C#.
Moq is designed to be a very practical, unobtrusive and straight-forward way to quickly setup dependencies for your tests.
It is very useful for faking implementations of interfaces so that you don't need to litter your tests with implementations that you don't need.
The code below shows a class,
MyClass, which calls a method on a complex object internally. We do not want to test the
ComplexClass class here, only the behavior of the
How to test the behavior of MyClass's
Verify method? Use Moq to setup the implementation.
Verify_ComplexObjectIsValid_ShouldNotThrowException test method fails because the
complexClassobject has not been set up with the needed dependencies.
Verify_ComplexObjectIsValid_ShouldReallyNotThrowException test method, Moq fakes the behavior of the
ComplexClass.Verify method and sets up an expectation that this method should be called. Now we just verify that no exception is being thrown and that this method is called.
The behavior of MyClass was successfully tested without need of coupling the test with ComplexClass's internal logic.
Paul Stovell shares his experiences of six years of using WPF and is not happy with its evolution.
You might enjoy working with WPF. You might think XAML is a beautiful, terse, fun to write language. That's how I felt in 2006, and if the platform is still enjoyable for you, that's great. It's going to be around for a long time, since there's really no alternative yet. But for me, I'm glad my WPF days are behind me, and that my full time job now is now ASP.NET-focused.
The System.Configuration-namespace contains the classes for working with an applications configuration. Using the API, you can work with the configuration on a higher level than the XML it is represented by. This includes both editing and saving.
The snippet above shows a trivial example of opening and saving a configuration. Configuration’s Save-method uses the XmlUtilWriter class internally. However, this will also format the XML according to its own rules with no options of customization. In my case, line-breaks where aggressively inserted and the resulting XML was ugly and far to narrow for my liking.
Being not too keen on doing the serialization manually, I remember that the XDocument formatting generally looks OK. My solution was to read and save the XML using XDocument immediately after saving the configuration:
Not the cleanest of solutions, but the resulting XML looks much better.
Referencing a .N2.0 assembly from my .Net 4.0 client profile application today I encountered this error:
Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
What is this additional configuration information? Addto the app.config-file. Example:
For more information, see this excellent post.
Ngen.exe (Native Image Generator) is used to compile assemblies ahead-of-time (AOT) instead of the usual just-in-time (JIT) compiling. Running Ngen after an installation allows your application to enjoy faster loading times at the expense of a slower installation, a worthwhile tradeoff in many cases. How do you run Ngen at the end of a MSI installation using WiX? The answer is by using a Custom Action.
First add a new Custom Action project to the solution containing your WiX projects:
Note that I have chosen the 3.5 framework in order to get the Custom Action to play nice with WiX 3.5. You can still use this task to compile 4.0 assemblies.
Now add a reference to your new Custom Action from the WiX project:
After renaming the class and doing a bit of coding, we are left with this:
Inside our RunNgen class we have the OnInstallation method marked with the CustomAction attribute. This is the method that will be called from the WiX-project.
Inside the GetNgenProcess method we have a couple of points of interest. First, the ngenPath specifies the path to the Ngen executable. assemblyPath contains the path to our main executable. IDIR and EXECUTABLE are both properties coming from the WiX project, more about them later. The argument passed to ngen.exe, install “[assemblyPath]”, instructs Ngen to generate native images for the executable and its dependencies and lastly install the images in the native image cache.
We are not interested in showing the user the gory details from the Ngen process, thus we redirect the standard output and do not show the console.
The standard output is captured in our StreamReader and logged to file at the end of the process.
Now IDIR and EXECUTABLE needs to be specified within the product tag in our WiX project:
“a_directory_id” is the id of the directory containing our installation and “name_of_executable” is the name of the main executable.
In order to inform WiX of the Ngen action, we specify the follow after the Product tag:
You should recognize “OnInstallation” as the name of the Custom Action method. SourceFile specifies the path to the assembly containing the custom action. The added “CA” at the end of the assembly name specifies that this is indeed a Custom Action.
To call the Ngen action, add the following to the InstallSequence:
And there you have it! The Custom Action we have created can be used by any WiX project and can easily be further tweaked if other usage scenarios arise. One example could be an application containing multiple executables.
If you need to debug your actions, the Debugger.Launch() method can be called from the Custom Action. Just remember to remove it before shipping…