Integration

Test .NET 6 (Or any Core version) from legacy .NET Framework

I’m currently working on moving a large legacy system from .NET Framework 4.8 to .NET 6. Since this is a large system the move will take years and we need to work iteratively meaning both systems will co-exist over a few years.

This means that integration tests we already have for the legacy system now needs to execute code over two application domains running two completely different CLRs. I ended up making a little service that the legacy code can call to execute code in the new system.

First we create a new web API project with a single controller.

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    private static readonly Dictionary<Guid, IServiceProvider> ServiceProviders = new();

    public bool Get()
    {
        return true;
    }

    [HttpPost("SetupTest")]
    public async Task SetupTest(Guid testId, string connectionString)
    {

        var collection = new ServiceCollection();

        var provider = collection
            .AddCqs(configure => collection.AddMassTransitTestHarness(cfg =>
            {
                cfg.UsingInMemory((ctx, mem) =>
                {
                    mem.ConfigureTestHarness(ctx);
                    mem.AddOutbox(ctx);
                    mem.ConfigureEndpoints(ctx);
                });
                configure(cfg);
            }))
            .AddDbContext<PcDbContext>(b =>
            {
                b.UseSqlServer(connectionString);
            })
            .AddBusinessCore()
            .AddRepositories()
            .AddDomain()
            .AddTestHarness()
            .AddTestGuidFileRepository()
            .BuildServiceProvider();


        var harness = provider.GetRequiredService<IHarness>();
        await harness.Start();

        ServiceProviders.Add(testId, provider);
    }

    [HttpPost("TeardownTest")]
    public void TeardownTest(Guid testId)
    {
        ServiceProviders.Remove(testId);
    }


    private static readonly JsonSerializerOptions Options = new() { PropertyNameCaseInsensitive = true };

    [HttpPost("ExecuteCommand")]
    public async Task ExecuteCommand(Guid testId, string cmdType)
    {
        var provider = ServiceProviders[testId];

        var cmd = (await JsonSerializer.DeserializeAsync(HttpContext.Request.Body, Type.GetType(cmdType)!, Options))!;
        await provider.GetRequiredService<IBus>().Publish(cmd);
        await provider.GetRequiredService<IHarness>().WaitForBus();
    }
}
(more…)

SignalR event aggregation with Blazor WASM

As you probably know by now I love event aggregation and being able to seamless forward server side events to clients. My library SignalR.EventAggregatorProxy have been around for a while now and it enables seamless event aggregation between server and client. The .NET core client library just got updated to .NET 5. And as it turns out it works without any effort in Blazor WASM.

(more…)

Convention based Concurrency Management in Entity Framework Core

Who does not love convention over configuration? Whenever it makes sense I try to use it in my role as a system architect. It helps my programmers write more robust code out of the box.

Writing concurrency safe code is a corner stone in writing robust code today,  without it data quality can not be guaranteed. And when things go wrong you want to know who and when entities were updated so you can investigate what have gone wrong.

So what I did at my latest assignment was to force this onto the entities by convention using two markup interfaces ICreated and IUpdated(more…)

Flexible integration tests with dacpac support

Integration tests are an important aspect of software development, high code coverage does improve code quality. But the tests need to be flexible and fast so they do not hinder the developers in their daily work. On the build server speed doesn’t matter that much, but a good test suite must be fast enough so that the developers choose to use it instead of running the system manually to test their features. Thats how you get good code coverage. Sadly publishing a dacpac is anything but fast. But there are clever tactics you can apply to make it work good as your daily testing platform.
(more…)

Build server – client contracts with dotnet CLI

Now days type safety is common within the web-world with TypeScript and on the horizon WebAssembly with .NET Core (Blazor etc). I have for a long time advocated for the importance of this, especially when we are talking the contract between server and client. For example this T4 template that spits out C# CQS types as javascript.

T4 doesn’t play well with Dot Net Core, but we now have the dotnet CLI toolset we can use instead.
(more…)

Z-Wave – A system architects view

I’ve been looking into smart home systems lately. Z-Wave seemed like a popular choice and I liked the possible scenarios you could achieve with it. So I have played around with it for a few days now, and my final verdict on it, looking through my system architect eyes is that the entire thing must been developed by hackers, at least the software stack. Let me tell you why… (more…)

Microsoft.Rest.ServiceClient opt out retry

If you use Swagger generated REST proxies then you have probably come across the pretty new Microsoft.Rest namespace and namely the abstract class ServiceClient. I noticed a strange behavior when using clients that subclass this base class. The default behavior for this class is to retry when a 500 status code is returned.
I can not understand the reason for this being Opt out, its obvious a feature like this should be Opt in. So keep in mind when using this class you must always call SetRetryPolicy to disable the retry strategy.

var service = new MyService(uri, credentials);
service.SetRetryPolicy(new RetryPolicy(new HttpStatusCodeErrorDetectionStrategy(), 0));

Client – Server Event aggregation with Role Authorization

I’ve covered my SignalR Event aggregation library in an earlier post found here. That library has a Constraint API so that you can control which events a specific user should receive. It requires you to write one constraint handler for each type of event. But how about standard declarative Role Authorization?
(more…)

Typed javascript contracts using T4 Templates

A big problem with AJAX enabled JavaScript sites are the contract between server and client. A common “contract” is just to use jQuery.ajax with an inline declared URL and some parameters. A big problem with this approach is the fact that there is no real contract between client and server. Another problem is the fact that, as the site grows, so will your list of web methods and URL’s to go with them.

CQRS is winning more ground these days, and it has several advantages over the more classic ways of communication. One of the biggest is that there are no more god service classes with hundreds of methods and URL’s. Most implementations I have seen with CQRS in web projects only leverage CQRS between the server-side web and the message bus/backend. The client still communicates with a standard web method that just redirects the calls to the message bus. Why not leverage the contract safety and other perks of CQRS all the way from the client to message bus?

In the WCF-world we can share a common contract assembly that holds all command and queries, this is not the case with JavaScript. At my latest customer project I came up with the idea to use a T4 template to render all the commands and queries into a JavaScript file. You will even benefit from code completion in Visual Studio, at least if you use Resharper 6 or later.

First we need to create the T4 template. We can not use reflection to get the Command and query types because a T4 template is executed at design time not runtime or compile time. Instead we have to use the tools found in the EnvDTE namespace to retrieve all the projects of the solution and their types. The problem with EnvDTE is that it’s a major pain to work with, but don’t worry, there are remedies out there. From the extension manager in VS install the Tangible T4 Editor, it comes with a T4 template with helper methods for the EnvDTE tools.

Include the Visual Studio Automation Helper from the Tangible editor.

Image

It comes with a helper class called VisualStudioHelper with a bunch of helpful methods to retrieve info from a project and its types. Even though VisualStudioHelper is very helpful we still need some custom helper methods written. You need to write a method that gets all types that inherit a specific base class or resides in a special namespace or any other convenient convention that fits your project . It should look something like this.

public IEnumerable<CodeClass> GetSubClasses(string baseClass, Project project)
{
	return VisualStudioHelper		
		.CodeModel
		.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false)
		.Cast<CodeClass>()
		.Where(c => GetInheritance(c).Any(b => b.FullName == baseClass) && !c.IsAbstract)
		.ToList(); 
}

public IEnumerable<CodeClass> GetInheritance(CodeClass @class) 
{
	foreach(CodeClass @base in @class.Bases) 
	{
		yield return @base;
		foreach(var sub in GetInheritance(@base)) 
			yield return sub;
	}
}

Now we can get all DTO contract types for a specific project like this

var project = VisualStudioHelper.GetProject("MyApp.Core.Contracts");
var contracts = GetSubClasses("MyApp.Core.Contracts.Commands.Command", project)
	.Concat(GetSubClasses("MyApp.Core.Contracts.Queries.Query", project));

After that its just a matter of rendering the JavaScript version of the types, you have to be very specific about how you declare your objects for VS to be able to pick them up with code completion. And at the same time you must ensure that you do not overwrite any existing object closures.

First we create object closures for all namespaces and make sure they do not overwrite any existing closures.

window.MyApp = (window.MyApp || {});
window.MyApp.Core = (window.MyApp.Core || {});
window.MyApp.Core.Contracts = (window.MyApp.Core.Contracts || {});
window.MyApp.Core.Contracts.Commands = (window.MyApp.Core.Contracts.Commands || {});

Then we create each Type as a javascript function (Constructor).

window.MyApp.Core.Contracts.Commands.FooCommand = function(bar) {
    this.bar = bar;
};

I also add the fully qualified name to the object like this

window.MyApp.Core.Contracts.Commands.FooCommand.type = "MyApp.Core.Contracts.Commands.FooCommand";

It’s later used when sending a DTO to the server. Above JavaScript is rendered like this. Helper methods excluded, you can checkout the full example at Github.

foreach(var part in BuildNamespace(contracts)) {
	#>	<#= part #>
<#
}

foreach(var contract in contracts) {
		#>	
	<#

    var properties = GetProperties(contract).Select(p => CamelCased(p.Name)).ToList();
    var args = string.Join(", ", properties);

    #>

    window.<#= contract.FullName #> = function(<#= args #>) {<#
    foreach(var property in properties) {#>

        this.<#= property #> = <#= property #>;<#
    }
	#>

    };
    window.<#= contract.FullName #>.type = "<#= contract.FullName #>";
<#
}
#>

We also need some client code that can send the DTO’s, sadly the .NET WebApi that we use for this particular project does not support dynamic C# objects from arbitrary JSON objects so we had to send the DTO data as a string (Side note, vanilla JSON.NET that WebApi utilizes does support dynamic objects).

function buildContract(contract) {
	return { type: contract.constructor.type, data: ko.toJSON(contract) };
}
var url = "api/commandQuery";
MyApp.cqrs = {
	sendQuery: function(query, callback) {
		MyApp.utils.get(url, buildContract(query), callback);
	},
	sendCommand: function(command) {
		MyApp.utils.post(url, buildContract(command));
	}
};

You send a command or query like this.

MyApp.cqrs.sendCommand(new MyApp.Core.Contracts.Commands.FooCommand("bar"));

The server needs to create static typed C# objects instances, to do this we need to get a little creative with JSON.NET. First we declare a Data contract that WebApi is capable of deserialize to.

public class Contract
{
    public string Type { get; set; }
    public string Data { get; set; }
}

Then we need to create a way of decoding that data into a real object instance of the correct static type. We use some JSON.Net magic for this.

private TDto CreateDto<TDto>(Contract contract) where TDto : class
{
    var type = typeof(Query).Assembly.GetType(contract.Type);
    var jObject = JObject.Parse(contract.Data);
    var dto = jObject.ToObject(type);

    return dto as TDto;
}

We get the Type object instance from the type string sent from client then we use JSON.NET to first create e dynamic object from the string data and then we use the ToObject method that uses reflection to create a static typed version of the dynamic object. We use the above method from our WebApi method like.

public QueryResult Get([FromUri]Contract contract)
{
    var query = CreateDto(contract);
    return client.SendQuery(query);
}

A fully featured example of this technique can be found here