• ProxyKit - Last release and EOL.

    23 Oct 2020

    I've just pushed version 2.3.4 of ProxyKit to nuget.org which I expect to be the final version.

    Read more...


  • AspNet Core 3.1 Nested Applications

    This is a follow up on a previous post about how to host multiple isolated ASP.NET core applications in a single process with with a single http listener/entry. The techniques used in that post used types and classes e.g. Microsoft.AspNetCore.Hosting.Internal.StartupLoader that have been made internal in ASP.NET Core 3.x and thus the approach is no longer viable.

    Instead we need to take a different approach that, while has some caveats, works well.

    Read more...


  • AspNet Core Nested Applications

    Given any application of a reasonable size, to reason about it and manage complexity one generally applies modular programming along clear and well defined boundaries. Recently I was seeking to do this with AspNet Core where I wanted to compose several independent applications, potentially developed by separate teams, within the one host.

    Nested Apps

    Out-of-the box this is achieved with middleware, however this still means there is a single dependency injection container whose service registration code gets large and leaky. Occasionally there were classes and configurations that clashed. While useful for a lot of scenarios, AspNetCore middleware wasn't giving me the isolation I desired: defined controllers, own static content, auth middleware settings, independent policy definition, focused service registration and more. Basically I want multiple StartUp classes representing the different applications and connect them to a path in a host application.

    Prior to AspNet Core this was easy to achieve with OWIN. Nested applications were just an AppFunc that you build and connected when wiring up an an app.MapPath("path", appFunc). With AspNet.Core we need to take another approach.

    Read more...


  • Commercial Suicide - Integration at the Database Level

    This post was originally authored by Jak Charlton in 2009 and is originally hosted at devlicio.us. That site appears to be inactive and regularly unavailable so, with permission, I'm re-publishing it here as I think it's a timeless piece.

    There are many ways you can commit commercial suicide, but there is possibly no slower and more agonising death than that produced by attempting that great architectural objective, the single authoritative database to which all applications talk.

    The theory is good, if we have a single database then we have all our business information in one place, accessible to all, easy to report against, reduced maintenance costs, consistency across all applications, and a host of other good objectives.

    However all these noble ideals hide a more fundamental problem, that the single database does not solve any of them, and makes most of them into far bigger problems.

    Read more...


  • Capturing Log Output in Tests with XUnit 2

    02 Jun 2015

    xunit 2.x now enables parallel testing by default. According to the docs, using console to output messages is no longer viable:

    When xUnit.net v2 shipped with parallelization turned on by default, this output capture mechanism was no longer appropriate; it is impossible to know which of the many tests that could be running in parallel were responsible for writing to those shared resources.

    The recommend approach is now to take a dependency on ITestOutputHelper on your test class.

    But what if you are using a library with logging support, perhaps a 3rd party one, and you want to capture it's log output that is related to your test?

    Because logging is considered a cross-cutting concern, the typical usage is to declare a logger as a static shared resource in a class:

    public class Foo
    {
        private static readonly ILog s_logger = LogProvider.For<Foo>();
    
        public void Bar(string message)
        {
            s_logger.Info(message);
        }
    }
    

    The issue here is that if this class is used in a concurrent way, it's log output will be interleaved, just in the same way as using console in tests.

    Read more...