More Nmoneys.Serialization

on Thursday, 21 August 2014
The release for packages supporting third party serialization libraries of Money instances has already been announced.
Straighforward as their usage might be, or useful the inline comments might be, what was missing was more detailed documentation available on the project homepage. No more.

Lazy summer blogging

Why is telling that one is blogging while on holiday even important? Because it is different this time. It is the first time in some years that I do not have a laptop with me.
The documentation was indeed written online using an iPad Air Wifi with a bluetooth Microsoft Wedge keyboard, and so is this post (using Posts) and I have to say I am pretty pleased so far.
Writing on this smaller keyboard takes some time to get used to and my hands often reach out where the "normal" key would be, but it is night and day as what can be achieved with the on-screen keyboard.
Of course, being a keyboard thought for Windows (and not iOS) and given the lack of customization that Apple's OS offers there are a few oddities. Despite choosing the right keyboard layout (using Win + Space) there are some keys that are "missplaced"; most important are asterisk and curly braces. So one has to revert to clumsy copy and pasting or just play a little game of "find the right key combination". That is probably only a problem for programmers akin to the curly brace cult, as for emails and "normal" writters the Wedge is a wonderful complement with its ingenious stand/keyboard cover and overall portability and feeling of the keys.

NMoneys.Serialization.*

on Wednesday, 6 August 2014

I have already touched the subject of NMoneys serialization in the context of a third party serialization library.
Even a custom converter was released as a Nuget package. But real world experience taught me it is not enough.

A new model

I have always been hesitant on the policy to adopt when depending on third party libraries in my packages: shall I fix it to a known version? Fix the upper limit to the next semantic version and hope for the best? Update the minimum version every now and then?
Quite a few questions and few definitive answers.

In this particular case (serialization using a Json.NET converter), I chose to break with the past and deliver the custom converters and everything else as source code and remove the dependency to the serialization framework from my package.
Is this the way to go? It definitely has its advantages, but time will tell.

New horizons

A side effect of the decision is allowing the user of the package to tweak the serialization process or remove the artifacts that won’t be used.
It also gives me the opportunity to supply the same code for Json.NET and RavenDB (that uses an internalized version of the former) just by switching namespaces during the build process.

Value Added

on Tuesday, 24 June 2014

Tools are important in the daily work of a developer (as they are in any other handcraft). The better tools one have the less effort should be needed, with the added plus of getting a lot more done and unlocking scenarios that, without them, would be close to impossible.

A good example of such a tool is ReSharper. I am not going to discover it, of course; they already have people (evangelists) whose day to day job is praising and showing off its greatness (it may sound cynic, but it is not, it is an awesome product).
It sounds weird (and possibly wrong), but I am an addict and without it, I am half of a coder. That is why it surprises me the negative reactions that it can cause to an extent as to really and truly jump through hoops to turn a perfectly good text editor into an IDE-oid with insane command line trickery (read the whole series, it is an eye opener).

Blown Away

For example, the other day I was playing TDD ping-pong (Write a test, red; some code, green; more red and green and clean the mess every now and then) with an intern in my company and we were refactoring a loop and there was some code with a break statement.
I selected the code, including the break and, reluctantly, extracted the method, just to observe in awe that R# extracted the boolean-returning method, and added the break afterwards.
I run to show some colleagues and we agreed: it comes with a cost (it is not cheap for my company to keep up upgrading), but it is worth every penny.

And now, go and improve performance already before I switch to Notepad++ Winking smile

Departures. Springpad

on Friday, 30 May 2014

Not even a year ago I wrote about Catch notes closing up and leaving me hung up to dry.

And today I was “greeted” with an email, saying that my chosen replacement (Springpad) is also saying its farewells.

Seriously? Again?

Yup, time to grab my virtual note baggage and move it to somewhere else again.

The Contenders

They are pretty much the same as they were one year ago:

  • Simplenote. Seems clean, light and multiplatform. There is no migration from Springpad, but it can be a fun pet project
  • Memit. “Fellow” Danes that lack an Android client (although they claim it’s on its way) but they offer a clear migration path from Springpad.

Not so much a contender

  • Evernote. 800 pound gorilla that can (and will) do everything, despite the fatness of their mobile clients. Springpad is practically pushing they ex-users to use their services. It is my last resort.
  • Google Keep. As much as I like Google services, Keep has not evolved as much as I’d like to suit my needs. Their lack of tagging, their the lack of an API to migrate my data and the fact they do not have an iOS app (!) trumps their minimalist web app and sleek Android app.
  • One Note. As much as I like their PC app I am unimpressed (mild, very mild) by their heavy web app, their big-ass Android app and the even beefier iPad app.

What has changed?

Something changed in one year. I do not use an Android tablet regularly anymore.
My main post-PC device is now an iPad Air, hence the increased value of a good iOS application above an Android client.
A good web app remains nonnegotiable, though.

If you know a good replacement that fits my needs, please, let me know:

  • Multiplatform: web app + iOS + Android (in that order of importance)
  • Able to tag and search within tags and content
  • Modest note taking habits. Link hoarding not needed (I have Pocket for that)

Would I consider paying?

After having to pack and move twice… would I consider paying for a service that I going to rarely use?
I don’t think so.
I would rather either change my note-taking habits or, why not? build my own for fun (and no profit).

By Example

on Sunday, 18 May 2014

Other than showcasing how monetary quantities can be formatted and showing off the data available for different currencies, one of the objectives of NMoneys.Web is showing code samples on how to accomplish common tasks.

Deviate from Reality

Code examples, like code comments, are always at risk to deviate from reality offered by code, given a forgetful developer fails to change samples and code when software evolves.

Unfortunately, there is no samples (or comments) compiler or tester so far… Or is there?

The Real Thing

What if we could serve .cs source files that get compiled (and, optionally, tested) so that we have totally living documentation?

Serving files with the .cs extension is disabled by default by ASP.NET, but it can be easily enabled and constrained to a path of the application:

<location path="Content/src">
    <system.webServer>
        <security>
            <requestFiltering>
                <fileExtensions>
                    <remove fileExtension=".cs" />
                    <add fileExtension=".cs" allowed="true" />
                </fileExtensions>
            </requestFiltering>
        </security>
    </system.webServer>
</location>

So, whenever a source file is requested (for example, from the quickstart), a real .cs file is served.

Real Things Get Compiled

What’s more, those source files that are served through IIS, can be compiled to verify their validity as C# code.

That can be achieved in an automated test and it is simple, although it involves more than one step:

  1. Add the .cs files that need to be compiled to the test project as links (so that there is no file duplication)
  2. Set the Build Action to Content
  3. Set the Copy to Output Directory to Copy Always

And with those steps, every time the test project is compiled, there will be a bunch of .cs files inside a folder hierarchy below the bin folder.

In order to compile them, I chose to use the compilation and code generation services of

CSharpCodeProvider, that can be wrapped in a function in order to call it from multiple tests:

private CompilerResults compile(bool inMemory, params DirectoryInfo[] directories)
{
    var provider = new CSharpCodeProvider();
    var parameters = new CompilerParameters();
    parameters.ReferencedAssemblies.Add("NMoneys.dll");
    parameters.ReferencedAssemblies.Add("NMoneys.Exchange.dll");
    parameters.ReferencedAssemblies.Add("NUnit.Framework.dll");
    parameters.ReferencedAssemblies.Add("System.Xml.dll");
    parameters.ReferencedAssemblies.Add("System.Core.dll");
    parameters.GenerateInMemory = inMemory;

    CompilerResults results = provider.CompileAssemblyFromFile(
        parameters,
        directories
            .SelectMany(d => d.EnumerateFiles("*.cs"))
            .Select(fi => fi.FullName)
            .ToArray());
    return results;
}

Tests make Wonderful Examples

That I am quite a fan of automated testing, quite a few people can confirm.
I am also a believer that well-written unit tests make one of the best documentations available and I put my money where my mouth was by writing the code samples for my two Codeproject articles I wrote some time ago as unit tests.

So we can compile our code samples, how difficult could it be to run the tests they contain? Not much, to be honest.

  1. Add references to nunit.core.dll and nunit.core.interfaces.dll (that can be obtained from the NUnit.Runners packages (or from my version of it NUnit.Runners.lite)
  2. Call this method from multiple tests:
    private TestResult test(CompilerResults results)
    {
        CoreExtensions.Host.InitializeService();
        var package = new TestPackage(results.PathToAssembly);
        var builder = new TestSuiteBuilder();
        TestSuite suite = builder.Build(package);
        TestResult test = suite.Run(NullListener.NULL, TestFilter.Empty);
        return test;
    }
  3. Assert that are not failures in the result (the .IsFailure property)

NuDoq === ‘nearly awesome’

on Saturday, 19 April 2014

Documentation matters.
It takes a lot of time writing it and writing decent documentation it is an art in itself. Writing good documentation is a full-time gift.

Doc it like it’s 1999

I decided very early on boarding OSS that I would commit the time to write API documentation, regardless of my 3 tenets:

  • First directive is API design
  • Second directive is API design
  • When directives One and Two fail, documentation prevents total failure

Not only NMoneys comes with full-fledged XML documentation, some builds ago I included a .chm for old times’ sake.

But Mum does not (usually) feed me anymore

I even thought of a plan to not only compile the API documentation into .chm, but take advantage of the html generated and push it somewhere online.

And then, she passed by. Casually. Without giving herself importance. And I laid my eyes on her. Nudoq, from now on you have female gender in my vocabulary

Seriously rocking

I read about it while reviewing the project site of a random OSS library and it totally blew me off my socks. That is exactly what I had been looking for: good-looking, online documentation that takes no effort beyond documenting your code.

It works without you noticing. As long as you include XML comments in your code and push it to Nuget, chances are that she made your documentation available to everyone already.
She did that to NMoneys, check it out if you don’t believe your eyes.

nudoq.currency

All that glitters ain’t code

Unfortunately, it is not perfect.
I found myself some issues: failing to document inner classes, weird rendering and failing to refresh the documentation whenever a new version (or three) are pushed to the Nuget Gallery.

Something that worries me a bit, is that even though there is a Github organization for it, I cannot find a repository to clone and contribute to. There is a post in their feedback forums stating that it may be on its way, but it is from some time ago and it has not received much attention.

It would be a pity that it was not open sourced, since I am more than willing to contribute to such an awesome idea.
Please, let me work for you for free.

Searching Currencies

The main reason that NMoneys.Web was envisioned (apart from the learning experience) was to provide information about how the library displays monetary quantities in order for non-technical users to be able to spot mistakes or improvements.
Such requirement is fulfilled in the Currencies section

Snapshot/Detail

There are quite a few currencies (NMoneys supports, at the time of writing, 183) so I thought a tile-like layout would be suitable to display the most important information (codes, names and symbols).

currencies

For more detailed information it makes sense to have one of those evil modals (out-of-the-box Bootstrapper) and since there is some information, grouping in tabs looked like a good idea, sprinkling it with some tooltips.

detailtooltip

Finding one’s way… Or a currency

A very early “requirement” was the ability to filter/search currencies (it seems that Find in Page of your browser is not good enough Smile with tongue out).
After a couple of Google searches, I found that jquery.quicksearch (now pretty “forgotten”) and (the even older) jquery.highlight fitted the bill pretty nicely. A couple of train rides later, pseudo-free-text filtering plus highlighting was implemented on a shoestring with minimal coding:

$(function () {
    var $searchBox = $('#search-box');
    var snapshotSelector = '.snapshot';
    var $snapshots = $(snapshotSelector);
    var $titles = $('.initial');
    $searchBox.quicksearch(snapshotSelector,
        {
            'delay': 300,
            'onAfter': function () {
                var searchTerms = $searchBox.val();
                if (searchTerms) {
                    $snapshots.unhighlight().highlight(searchTerms);
                    $titles.hide();
                }
                else {
                    $snapshots.unhighlight();
                    $titles.show();
                }
            }
        });    
});

It’s not a SPA. It’s better than good. It’s… good enough.