Quick Links

Letzte Änderungen

    22.12.2021 - Bierbrauen - Christmas Gadget 2021

    Encodo wagt sich an die Königsdisziplin der Lebensmittelherstellung...

    Video vom Abfüllprozess

    16.6.2021 - Grill in Winti 2021

    Encodo got together for the first time since March 2020 for a team event outdoors in the relatively cool spring of 2021.

    1.6.2020 - Reinforcements! (3)

    We are happy to welcome Bardhi Jusufi to our team!

    7.3.2020 - Quino 2020 Roadmap

    Now that Quino 8.x is out the door, we can look forward to Quino 9.

    Quino 8 is a very solid and stable release that has already been test-integrated into many of our current products running on Quino. We don't anticipate any more low-level API changes, though there will be follow-up bug-fix releases.

    There are a few larger-scale changes improvements and enhancement, outlined below (and noted in the roadmap).

    Ready for Change

    With this release, we've got more coverage than ever. Excluding only generated code (e.g. *Metadata.cs and *.Class.css in the model assemblies), we ended up with a respectable 81% test coverage. Quino has almost 10,000 tests comprising about 51k LOC and covering 82k LOC, Many, many of these are integration and scenario tests. With this level of test coverage, we feel comfortable with refactoring to improve usability and performance.


    One of the primary near-term goals is to improve Quino's documentation story. The aim is to take a new developer through the common tasks of working with a solution based on Quino.

    Some of this documentation is currently still out-of-date or will change as we improve the corresponding components. For example:

    • Anything that refers to Nant is no longer relevant
    • Some of the quino tool documentation will no longer be relevant after 8.1 (see tools-related issue in the issue tracker)
    • The data documentation is still very much a work-in-progress

    Search and Index

    The latest table of contents is much more comprehensive than before and we're still improving it.

    We don't have an integrated search for the conceptual documentation yet, but you can use Google's site-specific search. For example, search for configuration with the following search text "configuration site:docs.encodo.ch". The top results are:

    Which is pretty decent, overall.


    Several of our upcoming products using Quino (two are so new that they're not yet listed) are replacing legacy products that are highly dependent on a central database that defines the application domain. That is, the model is in the database or in a model description that is not initiallly a Quino model.

    Instead of defining the model in C# code manually and then building the database from that (the standard approach with Quino), these products define the model with varying levels of automation and import and then use the existing database.

    The following list shows the various ways that we're building Quino models, in addition to the standard approach of defining them in C#:

    • Import a model from Microsoft Dynamics CRM
    • Import a model from a legacy DSL like the Atlas modeling language
    • Import a model from the database schema itself, using Quino's schema-import/migration support
    • Map a model in C# to an existing database schema, using Quino's new support for mapping schemas

    This allows customers with existing databases to relatively quickly and easily produce a Quino model that gets them access to the plethora of features available to Quino applications (e.g. ORM, schema-check and -migration, generated GUI for desktop or web, and so on).

    18.2.2020 - When [NotNull] is null

    I prefer to be very explicit about nullability of references, wherever possible. Happily, most modern languages support this feature non-nullable references natively (e.g. TypeScript, Swift, Rust, Kotlin).

    As of version 8, C# also supports non-nullable references, but we haven't migrated to using that enforcement yet. Instead, we've used the JetBrains nullability annotations for years.1

    Recently, I ended up with code that returned a null even though R# was convinced that the value could never be null.

    The following code looks like it could never produce a null value, but somehow it does.

    [NotNull] // The R# checker will verify that the method does not return null
    public DynamicString GetCaption()
      var result = GetDynamic() ?? GetString() ?? new DynamicString();
    private DynamicString GetDynamic() { ... }
    private string GetString() { ... }

    So, here we have a method GetCaption() whose result can never be null. It calls two methods that may return null, but then ensures that its own result can never be null by creating a new object if neither of those methods produces a string. The nullability checker in ReSharper is understandably happy with this.

    At runtime, though, a call to GetCaption() was returning null. How can this be?

    The Culprit: An Implicit Operator

    There is a bit of code missing that explains everything. A DynamicString declares implicit operators that allow the compiler to convert objects of that type to and from a string.

    public class DynamicString
      // ...Other stuff
      public static implicit operator string([CanBeNull] DynamicString dynamicString) => dynamicString?.Value;

    A DynamicString contains zero or more key/value pairs mapping a language code (e.g. "en") to a value. If the object has no translations, then it is equivalent to null when converted to a string. Therefore, a null or empty DynamicString converts to null.

    If we look at the original call, the compiler does the following:

    1. The call to GetDynamic() sets the type of the expression to DynamicString.
    2. The compiler can only apply the ?? operator if both sides are of the same type; otherwise, the code is in error.
    3. Since DynamicString can be coerced to string, the compiler decides on string for the type of the first coalesced expression.
    4. The next coalesce operator (??) triggers the same logic, coercing the right half (DynamicString) to the type it has in common with the left half (string, from before).
    5. Since the type of the expression must be string in the end, even if we fall back to the new DynamicString(), it is coerced to a string and thus, null.

    Essentially, what the compiler builds is:

    var result = 
      (string)GetDynamic() ?? 
      GetString() ?? 
      (string)new DynamicString();

    The R# nullability checker sees only that the final argument in the expression is a new expression and determines that the [NotNull] constraint has been satisfied. The compiler, on the other hand, executes the final cast to string, converting the empty DynamicString to null.

    The Fix: Avoid Implicit DynamicString-to-string Conversion

    To fix this issue, I avoided the ?? coalescing operator. Instead, I rewrote the code to return DynamicString wherever possible and to implicitly convert from string to DynamicString, where necessary (instead of in the other direction).

    public DynamicString GetCaption()
      var d = GetDynamic();
      if (d != null)
        return d;
      var s = GetString();
      if (s != null)
        return s; // Implicit conversion to DynamicString
      return GetDefault();


    The takeaway? Use features like implicit operators sparingly and only where absolutely necessary. A good rule of thumb is to define such operators only for structs which are values and can never be null.

    I think the convenience of being able to use a DynamicString as a string outweighs the drawbacks in this case, but YMMV.

    1. Java also has @NonNull and @Nullable annotations, although it's unclear which standard you're supposed to use.

    4.2.2020 - Configuring .NET Framework Assembly-binding Redirects

    After years of getting incrementally better at fixing binding redirects, I've finally taken the time to document my methodology for figuring out what to put into app.config or web.config files.

    The method described below works: when you get an exception because the runtime gets an unexpected version of an assembly---e.g. "The located assembly’s manifest definition does not match the assembly reference"---this technique lets you formulate a binding-redirect that will fix it. You'll then move on to the next binding issue, until you've taken care of them all and your code runs again.

    Automatic Binding Redirects

    If you have an executable, you can usually get Visual Studio (or MSBuild) to regenerate your binding redirects for you. Just delete them all out of the app.config or web.config and Rebuild All. You should see a warning appear that you can double-click to generate binding redirects.

    If, however, this doesn't work, then you're on your own for discovering which version you actually have in your application. You need to know the version or you can't write the redirect. You can't just take any number: it has to match exactly.

    Testing Assemblies

    Where the automatic generation of binding redirects doesn't work is for unit-test assemblies.

    My most recent experience was when I upgraded Quino-Windows to use the latest Quino-Standard. The Quino-Windows test assemblies were suddenly no longer able to load the PostgreSql driver. The Quino.Data.PostgreSql assembly targets .NET Standard 2.0. The testing assemblies in Quino-Windows target .NET Framework.

    After the latest upgrade, many tests failed with the following error message:

    Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

    This is the version that it was looking for. It will either be the version required by the loading assembly (npgsql in this case) or the version already specified in the app.config (that is almost certainly out of date).

    Which File Was Loaded?

    To find out the file version that your application actually uses, you have to figure out which assembly .NET loaded. A good first place to look is in the output folder for your executable assembly (the testing assembly in this case).

    If, for whatever reason, you can't find the assembly in the output folder---or it's not clear which file is being loaded---you can tease the information out of the exception itself.

    1. From the exception settings, make sure that the debugger will stop on a System.IO.FileLoadException
    2. Debug your test
    3. The debugger should break on the exception

    Click "View Details" to show the QuickWatch window for the exception. There's a property called FusionLog that contains more information.

    The log is quite detailed and shows you the configuration file that was used to calculate the redirect as well as the file that it loaded.

    Which Version Is It?

    With the path to the assembly in hand, it's time to get the assembly version.

    Showing the file properties will most likely not show you the assembly version. For third-party assemblies (e.g. Quino), the file version is often the same as the assembly version (for pre-release versions, it's not). However, Microsoft loves to use a different file version than the assembly version. That means that you have to open the assembly in a tool that can dig that version out of the assembly manifest.

    The easiest way to get the version number is to use the free tool JetBrains DotPeek or use the AssemblyExplorer in JetBrains ReSharper or JetBrains Rider.

    You can see the three assemblies that I had to track down in the following screenshot.

    Writing Binding Redirects

    Armed with the actual versions and the public key-tokens, I was ready to create the app.config file for my testing assembly.

    And here it is in text/code form:

        <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <assemblyidentity name="System.Numerics.Vectors" publicKeyToken="B03F5F7F11D50A3A" culture="neutral">
            <bindingredirect oldVersion="" newVersion="">
     name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="B03F5F7F11D50A3A" culture="neutral">
            <bindingredirect oldVersion="" newVersion="">
     name="System.Threading.Tasks.Extensions" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral
            <bindingredirect oldVersion="" newVersion="">
    21.1.2020 - Looking for Developers in 2020

    2020 is shaping up to be a busy year...so we're looking for help from anyone who's got what it takes and who's interested in working on interesting projects with a great team.

    Please take a minute to check out the following job descriptions.

    If you are interested, please don't hesitate to apply from the pages linked above. If you know of someone who might be interested, we'd appreciate it if you could let them know that we're looking for them.


    6.12.2019 - Bees and Honey 2019

    Encodo spent part of this year learning about bees and honey. We met several times throughout the spring and summer to take care of the bees, gather honey, extract it from the honeycomb, fill it into jars, make labels and, finally, pack it all up and send it out to our customers for the end-of-year present. We hope they enjoy it over the holidays!

    In addition to the pictures below, we made several videos throughout the process:




    27.11.2019 - Networking Event 2019.2: End-to-End Web Testing

    Richi presented the requirements for and history of end-to-end testing, from Selenium to the more modern, flexible and fast solutions we use at Encodo, like Cypress and TestCafé.

    14.11.2019 - Improving NUnit integration with testing harnesses

    imageThese days nobody who's anybody in the software-development world is writing software without tests. Just writing them doesn't help make the software better, though. You also need to be able to execute tests -- reliably and quickly and repeatably.

    That said, you'll have to get yourself a test runner, which is a different tool from the compiler or the runtime. That is, just because your tests compile (satisfy all of the language rules) and could be executed doesn't mean that you're done writing them yet.

    Testing framework requirements

    Every testing framework has its own rules for how the test runner selects methods for execution as tests. The standard configuration options are:

    • Which classes should be considered as test fixtures?
    • Which methods are considered tests?
    • Where do parameters for these methods come from?
    • Is there startup/teardown code to execute for the test or fixture?

    Each testing framework will offer different ways of configuring your code so that the test runner can find and execute setup/test/teardown code. To write NUnit tests, you decorate classes, methods and parameters with C# attributes.

    The standard scenario is relatively easy to execute -- run all methods with a Test attribute in a class with a TestFixture attribute on it.

    Test-runner Requirements

    There are legitimate questions for which even the best specification does not provide answers.

    When you consider multiple base classes and generic type arguments, each of which may also have NUnit attributes, things get a bit less clear. In that case, not only do you have to know what NUnit offers as possibilities but also whether the test runner that you're using also understands and implements the NUnit specification in the same way. Not only that, but there are legitimate questions for which even the best specification does not provide answers.

    At Encodo, we use Visual Studio 2015 with ReSharper 9.2 and we use the ReSharper test runner. We're still looking into using the built-in VS test runner -- the continuous-testing integration in the editor is intriguing1 -- but it's quite weak when compared to the ReSharper one.

    So, not only do we have to consider what the NUnit documentation says is possible, but we must also know what how the R# test runner interprets the NUnit attributes and what is supported.

    Getting More Complicated

    Where is there room for misunderstanding? A few examples,

    • What if there's a TestFixture attribute on an abstract class?
    • How about a TestFixture attribute on a class with generic parameters?
    • Ok, how about a non-abstract class with Tests but no TestFixture attribute?
    • And, finally, a non-abstract class with Tests but no TestFixture attribute, but there are non-abstract descendants that do have a TestFixture attribute?

    In our case, the answer to these questions depends on which version of R# you're using. Even though it feels like you configured everything correctly and it logically should work, the test runner sometimes disagrees.

    • Sometimes it shows your tests as expected, but refuses to run them (Inconclusive FTW!)
    • Or other times, it obstinately includes generic base classes that cannot be instantiated into the session, then complains that you didn't execute them. When you try to delete them, it brings them right back on the next build. When you try to run them -- perhaps not noticing that it's those damned base classes -- then it complains that it can't instantiate them. Look of disapproval.

    Throw the TeamCity test runner into the mix -- which is ostensibly the same as that from R# but still subtly different -- and you'll have even more fun.

    Improving Integration with the R# Test Runner

    At any rate, now that you know the general issue, I'd like to share how the ground rules we've come up with that avoid all of the issues described above. The text below comes from the issue I created for the impending release of Quino 2.


    • Windows 8.1 Enterprise
    • Visual Studio 2015
    • ReSharper 9.2

    Expected behavior

    Non-leaf-node base classes should never appear as nodes in test runners. A user should be able to run tests in descendants directly from a fixture or test in the base class.

    Observed behavior

    Non-leaf-node base classes are shown in the R# test runner in both versions 9 and 10. A user must navigate to the descendant to run a test. The user can no longer run all descendants or a single descendant directly from the test.


    Relatively recently, in order to better test a misbehaving test runner and accurately report issues to JetBrains, I standardized all tests to the same pattern:

    • Do not use abstract anywhere (the base classes don't technically need it)
    • Use the TestFixture attribute only on leaf nodes

    This worked just fine with ReSharper 8.x but causes strange behavior in both R# 9.x and 10.x. We discovered recently that not only did the test runner act strangely (something that they might fix), but also that the unit-testing integration in the files themselves behaved differently when the base class is abstract (something JetBrains is unlikely to fix).

    You can see that R# treats a non-abstract class with tests as a testable entity, even when it doesn't actually have a TestFixture attribute and even expects a generic type parameter in order to instantiate.

    Here it's not working well in either the source file or the test runner. In the source file, you can see that it offers to run tests in a category, but not the tests from actual descendants. If you try to run or debug anything from this menu, it shows the fixture with a question-mark icon and marks any tests it manages to display as inconclusive. This is not surprising, since the test fixture may not be abstract, but does require a type parameter in order to be instantiated.


    Here it looks and acts correctly:


    I've reported this issue to JetBrains, but our testing structure either isn't very common or it hasn't made it to their core test cases, because neither 9 nor 10 handles them as well as the 8.x runner did.

    Now that we're also using TeamCity a lot more to not only execute tests but also to collect coverage results, we'll capitulate and just change our patterns to whatever makes R#/TeamCity the happiest.


    • Make all testing base classes that include at least one {{Test}} or {{Category}} attribute {{abstract}}. Base classes that do not have any testing attributes do not need to be made abstract.

    Once more to recap our ground rules for making tests:

    • Include TestFixture only on leafs (classes with no descendants)
    • You can put Category or Test attributes anywhere in the hierarchy, but need to declare the class as abstract.
    • Base classes that have no testing attributes do not need to be abstract
    • If you feel you need to execute tests in both a base class and one of its descendants, then you're probably doing something wrong. Make two descendants of the base class instead.

    When you make the change, you can see the improvement immediately.


    1. ReSharper 10.0 also offers continuous integration, but our experiments with the EAP builds and the first RTM build left us underwhelmed and we downgraded to 9.2 until JetBrains manages to release a stable 10.x.