Quick Links

Letzte Änderungen

    19.7.2018 - Introduction to Munjari (Changed)

    Munjari provides tools that will allow almost anyone to put their ideas online. This non-technical introduction is a great place to learn more.

    19.7.2018 - Brochure (Changed)

    A summary of Encodo and its services.

    19.7.2018 - Location map (Changed)

    A map of the Encodo office in Winterthur and surrounding areas.

    19.7.2018 - Metadata in Software Development (Changed)

    A short introduction to the use of metadata in software development.

    19.7.2018 - Quickinfo "Quino" (Changed)

    A short introduction to Quino—Encodo's C# Framework.

    16.7.2018 - Which type should you register in an IOC container? (Changed)

    Use Case

    I just ran into an issue recently where a concrete implementation registered as a singleton was suddenly not registered as a singleton because of architectural changes.

    The changes involved creating mini-applications within a main application, each of which has its own IOC. Instead of creating controllers using the main application, I was now creating controllers with the mini-application instead (to support multi-tenancy, of which more in an upcoming post).

    Silent Replacement of Singleton with Transient

    Controllers are, by their nature, transient; a new controller is created to handle each incoming request.

    In the original architecture, the concrete singleton was injected into the controller and all controller instances used the same shared instance. In the new architecture, the registration was not present in the mini-application (at first), which led to a (relatively) subtle bug: a transient and freshly created instance was injected into each new controller.

    In cases where the singleton is a stateless algorithm, this wouldn't be a logical problem at all. At the very worst, you're over-allocating---but you probably wouldn't notice that, either. In this case, the singleton was a settings object, configured at application startup. The configured object was still in the main application's IOC, but not registered in the mini-application's IOC.

    Because the singleton was registered on a concrete type rather than an interface, the semantic error occurred silently instead of throwing a lifestyle-mismatch or unregistered-interface exception.

    A Straightforward Fix

    This is only one of the reasons that I recommend using interfaces as the anchoring type of an IOC registration.

    To fix the issue, I did exactly this: I extracted an interface from the class and used the interface everywhere (except for the implementing type of the registration). Re-running the test caused an immediate exception rather than a strange data bug (which resulted because the default configuration in the concrete type was just correct enough to allow it to limp to a result).

    To show an example, instead of the following,

    application.RegisterSingle<ApiSettings>()
    

    I used,

    application.RegisterSingle<IApiSettings, ApiSettings>()
    

    This still didn't fix the crash because the mini-application doesn't get that registration automatically.

    I also can't use the same registration as above because that would just create a new unconfigured ApiSettings in each mini-application (the same as I had before, but now as a singleton). To go that route, I would have to replicate the configuration-loading for the ApiSettings as well. And I don't want to do that.

    Instead, I just injected the IApiSettings from the main application to the component responsible for creating the mini-application and registered the object as a singleton directly, as shown below.

    public class MiniApplicationFactory
    {
      public MiniApplicationFactory([NotNull] IApiSettings apiSettings)
      {
        if (apiSettings = null) { throw new ArgumentNullException(nameof(apiSettings(); }
    
        _apiSettings = apiSettings;
      }
    
      IApplication CreateApplication()
      {
        return new Application().UseRegisterSingle(_apiSettings);
      }
    
      [NotNull]
      private readonly IApiSettings _apiSettings;
    }
    

    On a side note, whereas C# syntax has become more concise and powerful from version to version, I still think it has a way to go in terms of terseness for such simple objects. For such things, Kotlin and TypeScript nicely illustrate what such a syntax could look like.1

    Other Drawbacks

    I mentioned above that this is only "one" of the reasons I don't like registering concrete singletons. The other two reasons are:

    1. Complicates replacement: If the registered type is a concrete instance, then any replacement must inherit from this instance. The base class has to be constructed more carefully in order to allow for all foreseeable customizations. With an interface, the implementor is completely free to either use the existing class as a base or to re-implement the interface entirely.
    2. Limits Mocking: Related to the first reason is that mocking is limited in its ability to override non-virtual methods. Even without a mocking library, you're just as hard-pressed to work around unwanted behavior in a hand-coded mock as you are with an actual replacement (as described above). Such limitations are non-existent with interfaces.


    1. I'm still waiting for C# to clean up a bit more of this syntax for me. The [NotNull] should be a language feature checked by the compiler so that the ArgumentNullException is no longer needed. On top of that, I'd like to see parameter properties, as in TypeScript (this is where you can prefix a constructor parameter with a keyword to declare and initialize it as a property). With a few more C#-language iterations that included non-nullable reference types and parameter properties, the example could look like the code below:

      public class MiniApplicationFactory
      {
      public MiniApplicationFactory(private IApiSettings apiSettings)
      {
      }
      
      IApplication CreateApplication()
      {
        return new Application().UseRegistereSingle(apiSettings);
      }
      }
      

    4.7.2018 - Learning Quino: a roadmap for documentation and tutorials (Changed)

    In recent articles, we outlined a roadmap to .NET Standard and .NET Core and a roadmap for deployment and debugging. These two roadmaps taken together illustrate our plans to extend as much of Quino as possible to other platforms (.NET Standard/Core) and to make development with Quino as convenient as possible (getting/upgrading/debugging).

    To round it off, we've made good progress on another vital piece of any framework: documentation.

    Introducing docs.encodo.ch

    We recently set up a new server to host Quino documentation. There, you can find documentation for current releases. Going forward, we'll also retain documentation for any past releases.

    We're generating our documentation with DocFX, which is the same system that powers Microsoft's own documentation web site. We've integrated documentation-generation as a build step in Quino's nightly build on TeamCity, so it's updated every night (Zürich time) 1.

    The documentation includes conceptual documentation which provides an overview/tutorials/FAQ for basic concepts in Quino. The API Reference includes comprehensive documentation about the types and methods available in Quino.

    Next Steps

    While we're happy to announce that we have publicly available documentation for Quino, we're aware that we've got work to do. The next steps are:

    Even though there's still work to do, this is a big step in the right direction. We're very happy to have found DocFX, which is a very comprehensive, fast and nice-looking solution to generating documentation for .NET code.2

    --


    1. If the build succeeds, naturally. :-)

    2. We used to use Sandcastle many years ago, but dropped support because it took forever to generate documentation, required its own solution file, didn't look very nice out-of-the-box, wasn't so easily customized and didn't have a very good search (which also didn't work without an IIS running it).

    4.7.2018 - Delivering Quino: a roadmap for deployment (Changed)

    In a recent article, we outlined a roadmap to .NET Standard and .NET Core. We've made really good progress on that front: we have a branch of Quino-Standard that targets .NET Standard for class libraries and .NET Core for utilities and tests. So far, we've smoke-tested these packages with Quino-WebApi. Our next steps there are to convert Quino-WebApi to .NET Standard and .NET Core as well. We'll let you know when it's ready, but progress is steady and promising.

    With so much progress on several fronts, we want to address how we get Quino from our servers to our customers and users.

    Getting Quino

    Currently, we provide access to a private fileshare for customers. They download the NuGet packages for the release they want. They copy these to a local folder and bind it as a NuGet source for their installations.

    In order to make a build available to customers, we have to publish that build by deploying it and copying the files to our file share. This process has been streamlined considerably so that it really just involves telling our CI server (TeamCity) to deploy a new release (official or pre-). From there, we download the ZIP and copy it to the fileshare.

    Encodo developers don't have to use the fileshare because we can pull packages directly from TeamCity as soon as they're available. This is a much more comfortable experience and feels much more like working with nuget.org directly.

    Debugging Quino

    The debugging story with external code in .NET is much better than it used to be (spoiler: it was almost impossible, even with Microsoft sources), but it's not as smooth as it should be. This is mostly because NuGet started out as a packaging mechanism for binary dependencies published by vendors with proprietary/commerical products. It's only in recent year(s) that packages are predominantly open-source.

    In fact, debugging with third-party sources – even without NuGet involved – has never been easy with .NET/Visual Studio.

    Currently, all Quino developers must download the sources separately (also available from TeamCity or the file-share) in order to use source-level debugging.

    Binding these sources to the debugger is relatively straightforward but cumbersome. Binding these sources to ReSharper is even more cumbersome and somewhat unreliable, to boot. I've created the issue Add an option to let the user search for external sources explicitly (as with the VS debugger) when navigating in the hopes that this will improve in a future version. JetBrains has already fixed one of my issues in this are (Navigate to interface/enum/non-method symbol in Nuget-package assembly does not use external sources), so I'm hopeful that they'll appreciate this suggestion, as well.

    The use case I cited in the issue above is,

    Developers using NuGet packages that include sources or for which sources are available want to set breakpoints in third-party source code. Ideally, a developer would be able to use R# to navigate through these sources (e.g. via F12) to drill down into the code and set a breakpoint that will actually be triggered in the debugger.

    As it is, navigation in these sources is so spotty that you often end up in decompiled code and are forced to use the file-explorer in Windows to find the file and then drag/drop it to Visual Studio where you can set a breakpoint that will work.

    The gist of the solution I propose is to have R# ask the user where missing sources are before decompiling (as the Visual Studio debugger does).

    Nuget Protocol v3 to the rescue?

    There is hope on the horizon, though: Nuget is going to address the debugging/symbols/sources workflow in an upcoming release. The overview is at NuGet Package Debugging & Symbols Improvements and the issue is Improve NuGet package debugging and symbols experience.

    Once this feature lands, Visual Studio will offer seamless support for debugging packages hosted on nuget.org. Since we're using TeamCity to host our packages, we need JetBrains to [Add support for NuGet Server API v3|https://youtrack.jetbrains.com/issue/TW-47289] in order to benefit from the improved experience. Currently, our customers are out of luck even if JetBrains releases simultaneously (because our TeamCity is not available publicly).

    Quino goes public?

    I've created an issue for Quino, Make Quino Nuget packages available publicly to track our progress in providing Quino packages to our customers in a more convenient way that also benefits from improvements to the debugging workflow with Nuget Packages.

    If we published Quino packages to NuGet (or MyGet, which allows private packages), then we would have the benefit of the latest Nuget protocol/improvements for both ourselves and our customers as soon as it's available. Alternatively, we could also proxy our TeamCity feed publicly. We're still considering our options there.

    As you can see, we're always thinking about the development experience for both our developers and our customers. We're fine-tuning on several fronts to make developing and debugging with Quino a seamless experience for all developers on all platforms.

    We'll keep you posted.

    25.6.2018 - v4.1.3: Fixes for search layouts, languages, reconnects, descendant relations (Changed)

    The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

    Highlights

    • Fixed reconnect for ADO database connections (QNO-5776)
    • Fixed occasional startup crash when generating data (QNO-5768)
    • Improved search-layout / search-class generation (QNO-5767)
    • Restored support / example for toggling data languages in the UI (QNO-5764)
    • Fixed save for relations with descendant endpoints (QNO-5753)

    Breaking changes

    • None
    25.6.2018 - v4.1: Layouts, captions, multiple requests-per-connection (Changed)

    The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

    Highlights

    Breaking changes

    • Usages of {{RunWinform}} should be updated to {{RunMetaWinform}}. The method {{RunWinform}} is now defined with a function parameter that expects an {{IApplication}} parameter instead of an {{IDataSession}} parameter. The change was made to allow applications more flexibility in configuring startup for applications with multiple main forms (QNO-4922) while still re-using as much shared code in Quino as possible. {{RunMetaWinform}} extends the {{RunWinform}} support to create and configure an {{IDataSession}} per form.
    25.6.2018 - Quino Roadmap (Changed)

    Quino Roadmap

    This document is about the future of Quino. See the release notes for the past.

    5.1 — June 2018

    • Isolation of Windows/Winforms/WPF code to Quino-Windows

    5.2 — July 2018

    • Improvements to the metadata-building API
    • Standardize namespaces, projects and dependencies
    • Move extension methods to components
    • Improve documentation

    6.0 — August 2018

    • Finalize .NET Standard 2.0 support
    • Finalize multi-platform support

    7.0 — Early 2019

    • No features planned yet