Category Archive News

ByMogens

Rebus and .NET Core

.NET Core is Microsoft’s new incarnation of .NET, where many things have been changed to be able to accommodate future needs for (primarily server side) application development. This is also the biggest change ever in the .NET world that is not backwards compatible!

For a long time we have had the ability to take an old .NET 2.0 DLL and plop it down next to our other DLLs, and then we would be able to use it right away. Because .NET Core is such a huge change (i.e. it uses a radically re-engineered runtime), that is no longer possible.

This puts a big burden on library developers (e.g. like me 🙂 ) who want to be prepared for the future, while supporting all of the old stuff still.

The good news is that with Visual Studio 2017 and the new CSPROJ format, it has actually become pretty straightforward to write libraries that target multiple frameworks by leveraging the <TargetFrameworks> element in the CSPROJ file (note the plural ‘s’ in there – when you create a new project, there is a <TargetFramework> element, but you need to add an ‘s’ if you put several targets in there).

By the power of open source and a persevering Rebus contributor, beta versions of Rebus 4 have now been released, targeting .NET 4.5 as always as well as .NETStandard 1.6 (which is .NET Core 1.0)

I am now in the process of porting all of the 40+ Rebus projects that it makes sense to port. You can follow the progress here. If you feel like messing a bit with .NET Core and becoming a Rebus contributor, feel free to get in touch and then we’ll figure out how you can help.

Exciting times ahead! 🙂

ByMogens

Check out Debaser

In case you are using Microsoft SQL Server, you may have tried writing a MERGE (...) statement…. did you think it was fun? 🙂

I think MERGE statements are not fun at all, but from time to time it IS necessary to execute a performant UPSERT-type of operation.

Maybe you also know that the fastest way to execute a huge number of upserts is to

  • create a custom table data type
  • create a stored procedure that executes the MERGE statement, using the data type as its input type
  • STREAM rows to the stored procedure via a table in tempdb

which can be pretty tedious to code.

Which is why the “upsert helper”, Debaser, was made 🙂

With Debaser, you can execute obscenely fast upserts by doing the following things:

Create a class that matches the layout of the table you want

E.g. something like

class SomeDataRow
{
    public SomeDataRow(int id, decimal number, string text)
    {
        Id = id;
        Number = number;
        Text = text;
    }

    public int Id { get; }
    public decimal Number { get; }
    public string Text { get; }
}

will do.

Initialize the upsert helper

This can be done like this:

var helper = new UpsertHelper<SomeDataRow>(connectionString);

and then you might want to

helper.CreateSchema();

when your application starts up. This will create a table, a custom table data type, and an appropriate stored procedure.

Upsert like crazy

Pass very very long sequences of row objects to the upsert helper like this:

await helper.Upsert(longLongSequence);

which is cool, because the upsert helper streams the data to SQL Server.

Pretty cool

If you think this looks cool, you should go to the Debaser wiki and read more about it, and maybe you want to Install-Package Debaser and start punishing your database right away?

Happy upserting!

ByMogens

Rebus 3 is out

Happy New Year!

This is just to let you know that Rebus 3 is out 🙂

The version was bumped to 3 because IAdvancedApi and IDataBus have been extended with more methods, and there are some changes around how to manually create transactions when sending messages outside of message handlers.

It is absolutely 100% wire-compatible with Rebus 2!

If you are interested in checking out which features were added, you can go to the tag comment and see the relevant bullets from the changelog. Most notable hightlights are a synchronous bus API (which can be accessed via bus.Advanced.SyncBus) and a few extra much needed methods on IDataBus.

Changes you need to make if you upgrade

If you are using DefaultTransactionContext

If you do this in your application:

using(var context = new DefaultTransactionContext())
{
    AmbientTransactionContext.Current = context;

    try
    {
        await bus.Publish(anEvent);

        await context.Complete();
    }
    finally
    {
        AmbientTransactionContext.Current = null
    }
}

you will have to change it to something like this:

using(var scope = new DefaultTransactionContextScope())
{
    await bus.Publish(anEvent);

    await scope.Complete();
}

which is much prettier and much much harder to mess up 🙂

If you implemented IDataBus or IAdvancedApi

…you will have to add two extra methods on IDataBus: Task<Stream> OpenRead(string dataBusAttachmentId); and Task<Dictionary<string, string>> GetMetadata(string dataBusAttachmentId); and one extra property on IAdvancedApi: ISyncBus SyncBus { get; }

If you implemented IDataBus or IAdvancedApi you most likely did it in order to decorate either service or to function as a test stub. Hopefully it will not be too cumbersome to extend those implementations to support the extra operations.

If you are using Rebus’ built-in logging

If you are using the GetCurrentClassLogger() method of IRebusLoggerFactory you will have to call GetLogger<YourClass>() instead – the stack frame walking turned out to be unreliable in some method inlining scenarios.

If you are using other Rebus packages

You will most likely have to update them to a version that is compiled against 3.0.0.

ByMogens

Rebus.fm has a new address…

…even though we didn’t move!

The Horsens Municipality just threw at us today that our address has been changed from

Søndergade 15F, 2. sal

to

Søndergade 15H, 2. sal

Of course it does not matter that much these days, but in case you were planning on stopping by for a cup of coffee, Søndergade 15H, 2. sal is the place to go.

I think the address has been updated in all the relevant places. Good thing we don’t have any business cards yet 😉

ByMogens

Today is cake-day in the Alley…

…because Mogens has – once again, after a break that has lasted a couple of years – received the “Most Valuable Professional” award from Microsoft, a.k.a. Microsoft MVP.

Here is what a bunch of programmers look like when they are high on sugar:

2016-10-03-13-47-57

ByMogens

Fleet Manager status

Work is ongoing with building Fleet Manager, but it is not going as fast as we would like.

However, that does not mean that there is no progress – we are working slowly, but steadily, in order to provide a truly useful tool with a sturdy backend and an acceptable frontend 🙂

If you are interested in trying it out, please go to the Fleet Manager pre-alpha sign-up page and register yourself – then we will get in touch as soon as we think we have something that is worth trying out.

ByMogens

Rebus 2 is out!

I am happy to announce that Rebus 2 has finally been published with a “real version number”.

After many year of notorious unwillingness to bump the version to something binding (i.e. >= 1.0), Rebus is now out in version 2.0.1, accompanied by its > 30 integration packages.

This means that all APIs are now stable, and users can rely on pulling down only non-breaking changes when they update packages within the v2 range.

Happy messaging! 🙂

ByMogens

Rebus roadmap

Rebus 2 has been in development for about 1,5 years now, and it has been used in production for at least one year by myself and many others… and by “Rebus 2”, I mean Rebus versions >= 0.90.0 🙂

Sorry about the confusion

First off, I would like to apologize for the confusion about the versions. For historical reasons the versions less than and including 0.84.0 are known as “Rebus 1”, and versions greater than and including 0.90.0 are known as “Rebus 2”. If you are interested, you can see the original announcement in this blog post.

Fixing the versioning

In order to “fix the versioning”, Rebus will soon become a real version 2.0.0.

In semantic versioning this marks as big step, as versions < 1.0.0 are allowed to make breaking changes for every single release, and thus are inherently unstable. Therefore, when Rebus becomes 2.0.0, it means that patch increments are for bugfixes and small improvements, minor increments are for backwards compatible feature additions, and then the major version number is incremented whenever a change is made which is NOT readily compatible with existing code.

When is this going to happen?

A few things need to be done before this is going to happen, where the main thing is that the ground must be laid for how the Rebus code repository should be split into separate repositories in the future.

It does not mean that 2.0.0 will necessarily wait for all of the libraries to have been moved, it just means that a few libraries must have been moved to prove that the code structure and everything surrounding the code works to support the new way.

If you are interested, you can follow the progress here on GitHub – for now, the due date for the milestone is set to the October 1, 2016.

Summary

If all goes well, Rebus 2.0.0 will be published on October 1, 2016 🙂

ByMogens

Rebus now has a data bus

The most recent addition to Rebus is a “data bus”, i.e. an implementation of the claim check pattern as described in The Good Book.

With the data bus, it has suddenly become extremely easy to transfer e.g. large CSV files from one endpoint to another, because the bus now supports creating attachments from streams, as well as opening up attachments as streams again in the receiving end.

Data bus attachments support including arbitrary metadata along with the attachment, allowing you to pass along file names, information about who made the attachment, etc.

You can read more about the feature on the official documentation wiki page.

ByMogens

Open source update

As part of daily work, little code snippets and useful bits crystallize and turn out to be so useful that it would be a shame not to share it with anyone.

Yesterday, two new small and focused projects were added to rebus-org: Owino and Swindler.

Owino

Owino is a NuGet package with OWIN extensions. At the moment, it has one single extension method: RegisterForDisposal, which is an extension method on IAppBuilder. You can use it like this:

public void Configuration(IAppBuilder app)
{
    // we're using Windsor
    var container = new WindsorContainer();

    // we're doing stuff
    // (...)

    // we ALWAYS dispose our IoC containers after use
    app.RegisterForDisposal(container);
}

which then ensures that the container is properly disposed when the application shuts down – no matter if the OWIN endpoint is hosted in-process, in an IIS, in a test, or somewhere else.

Swindler

Yesterday Jeremy Miller talked about having to juggle AppDomains in order to properly test code that relies on ConfigurationManager.

You don’t have to pull out the big gun to shoot that tiny bird though, because it IS possible to have the current AppDomain load another app.config – it just requires some tweaking of some private static fields in ConfigurationManager and some other places.

Swindler makes that part easy, because you can just do this:

[Test]
public void SomeTest()
{
    using (AppConfig.Use("my.custom.app.config"))
    {
        // ConfigurationManager will load app settings,
        // connection strings, and custom sections from
        // my.custom.app.config in here
    }
}

which then provides a way to actually test that you can pick up app settings, connection strings, and any custom configuration sections that you might have created.

Where to get it?

They’re both MIT-licensed and can be downloaded from the following places: