Tag Archives: Lamar

Lamar 1.0: Faster, modernized successor to StructureMap

EDIT: 6/15/2018: Fixed an erroneous link and don’t you know it, there’s already a Lamar 1.0.2 up on Nuget (might take a second for indexing to catch up first) with some fixes  to user reported problems.

Lamar is a new OSS library written in C# that is a new IoC container meant to replace the venerable, but increasingly creaky StructureMap library. Lamar is also Jasper‘s “special sauce” that provides runtime code generation and compilation that helps make Jasper’s runtime pipeline very efficient compared to its competitors. You can happily use the code generation and compilation without the IoC functionality. Thank you to Mark Warpool, Jordan Zaerr, Mark Wuhrith and many others for their help and early feedback.

I’m happy to announce that Lamar and Lamar.Microsoft.DependencyInjection (the ASP.Net Core adapter) were both published as v1.0.0 to Nuget this morning. It’s been beaten up a bit by early adopters and I finished off the last couple features around type scanning that I wanted for a v1 feature set, so here we go. I’m pretty serious about semantic versioning, so you can take this release as a statement that the public API signatures are stable. The documentation website is completely up to date with the v1 API and ready to go. If you’re kicking the tires on Lamar and run into any trouble, check out the Gitter room for Lamar.

To get going, check out Lamar’s Getting Started page.

Lamar as IoC Container

To get started, just add Lamar to your project through Nuget.

Most of the time you use an IoC container these days, it’s probably mostly hidden inside of some kind of application framework. However, if you wanted to use Lamar all by itself you would first bootstrap a Lamar container with all its service registrations something like this:


var container = new Container(x =>
{
    // Using StructureMap style registrations
    x.For<IClock>().Use<Clock>();
    
    // Using ASP.Net Core DI style registrations
    x.AddTransient<IClock, Clock>();
    
    // and lots more services in all likelihood
});

Now, to resolve services from your container:


// StructureMap style

// Get a required service
var clock = container.GetInstance<IClock>();

// Try to resolve a service if it's registered
var service = container.TryGetInstance<IService>();

// ASP.Net Core style
var provider = (IServiceProvider)container;

// Get a required service
var clock2 = provider.GetRequiredService<IClock>();

// Try to resolve a service if it's registered
var service2 = provider.GetService<IService>();

Definitely note that the old StructureMap style of service resolution is semantically different than ASP.Net Core’s DI resolution methods. That’s been the cause of much user aggravation over the years.

 

Brief History of Lamar

I’ve become increasingly tired and frustrated with supporting StructureMap for the past several years. I also realized that StructureMap had fallen behind many other IoC tools in performance, and I really didn’t think that was going to be easy to address without some large scale structural changes in StructureMap.

Most of my ambition in OSS over the past couple years has been on Jasper (Marten was something we needed at work at the time and I had no idea it would turn out to be as successful as it has been). I’ve been planning for years to use Roslyn’s ability to generate code on the fly as a way to make Jasper’s runtime pipeline as fast as possible without losing much flexibility and extensibility. What is now Lamar’s code generation and compilation model was originally just a subsystem of Jasper for its runtime.

Because I was so focused on Jasper’s performance and throughput, I knew I would want to move beyond StructureMap as its IoC container. I tried the built in DI container from ASP.Net Core for a little bit, but its limited feature set was just too annoying.

Hence, Lamar was born as a new IoC container project called “‘BlueMilk” that would:

  • Completely comply with ASP.Net Core’s requirements for IoC container behavior and functionality
  • Retain quite a bit of functionality from StructureMap that I wanted
  • Provide an “off ramp” for folks that depend on StructureMap today now that I’m wanting to stop support on StructureMap
  • Ditch a lot of features from StructureMap that I never use personally and cause me a great deal of heartburn supporting
  • Support Jasper’s “Special Sauce” code weaving
  • Be as fast as possible

What’s Special about Lamar?

First off, how it works is unique compared to the at least 20-30 other OSS IoC containers in .Net.  is the usage of dynamic generation of C# code at runtime and subsequent compilation via Roslyn in memory. Most other containers build and compile Expressions to Func objects in memory. You might have to take my word for this, but that’s an awful model to work with efficiently.

Other containers depend on emitting IL and that’s just not something I ever care to do again.

It’s hard to explain, but when used in conjunction with Jasper, Lamar can in many cases use inline code generation to completely replace any kind of service location calls in Jasper’s runtime handling of messages or HTTP requests.

Why would I use this over the built in DI container?

Just to be clear, Lamar is completely compliant with all of ASP.Net Core’s DI behavioral rules and expectations. Lamar even directly implements several of the DI abstractions itself this time around rather than depending on adapter libraries that kinda, sorta force your IoC container to act like what the ASP.Net Core team arbitrarily decided was the new standard for everybody.

As you may already know, ASP.Net Core comes with a simplistic DI container out of the box and many teams are frankly going to be perfectly fine with that as it is. It’s fast and has a good cold start time.

All the same, I tried to live with the built in container as it was and got way too annoyed with all the features I missed from StructureMap, and hence, Lamar was born.

Lamar has a much richer feature set that I think absolutely has some significant value for productivity over the built in container including, but not limited to:

And for those of you hyperventilating because “oh my gosh, that sounds like some magic and [conference speaker/MVP/celebrity programmer] says that all code must be painfully explicit or the world is going to end!”, you’ll definitely want to check out all of Lamar’s diagnostic facilities that help you unravel problems and understand what’s going on within Lamar.

StructureMap to Lamar

Lamar supports a subset of StructureMap’s functionality and API. There are some behavioral differences to be aware of though:

  • The lifetime support is simplified and reflects the ASP.Net Core semantics rather than the old StructureMap lifecycle support
  • Registry is now ServiceRegistry
  • You can use a mix of StructureMap-style registration and ASP.Net Core style registrations natively
  • There is no semantic difference between Add() and Use() like there was in StructureMap. Last one in wins. Just like ASP.Net Core expects.
  • Lamar supports nested containers like most .Net frameworks expect, but child containers or profiles will probably not be supported
  • Lamar doesn’t yet support setter injection (if you want it, just be prepared for an “I take pull requests” response)
  • The Container.With().GetInstance() functionality is never going to be supported in Lamar. I’m theorizing that a formal auto-factory feature later will be a better alternative anyway
  • Lamar only supports decorators for interception so far

 

Other Information:

Lamar was originally called “BlueMilk”

 

 

 

Advertisements

Planning the Next Couple Marten Releases

I think we’ve got things lined up for a Marten 2.9 release in the next week with these highlights:

  • Fixes for netcoreapp2.1. A user found some issues with the Linq support so here we go.
  • The upgrade to Npgsql 4.0
  • Eliminating Netstandard 1.3 support. Marten will continue to target .Net 4.6 & Netstandard 2.0, and we’ll be running tests for net46, netcoreapp2.0, and netcoreapp2.1.
  • Some improvements on exception messages in the event store support
  • Upgrades to Newtonsoft.Json — but if the performance isn’t better than the baseline, I’ll leave it where it is

Brainstorming What’s Next

I’ve been admittedly putting  most of my OSS energy into other projects (Jasper/Lamar) for the past year, but the Marten community has been happily proceeding anyway. One of my goals for OSS work this year is to get the Marten issue list count (bugs, questions, and feature ideas) under 25 and keep it there so it’s only a single page in the GitHub website.

We’ve got a big backlog of issues and feature requests. For a potential Marten 2.9, I’d like to suggest:

That’s all for the document store, so now let’s talk about the event sourcing. I don’t have a huge amount of ideas because I don’t get to use it on real projects (yet), but here’s what I think just from responding to user problems:

  • The async daemon is up for some love, and I think I’ve learned some things from Jasper work that will be beneficial back in Marten. First, I think we can finally get a model where Marten itself can handle distributing the ownership of the projections between multiple application nodes so you can more easily deploy the async daemon. After a tip from one of my new colleagues at Calavista, I also want to pursue using “tombstone” events as placeholders on event capture failures to make the async daemon potentially quite a bit more efficient at runtime.
  • I think this would be an add on, but I have an idea for an alternative to ViewProjection that would let you write your projection as just methods on a class that take in any combination of the actual event, the IDocumentSession, the containing EventStream, or Event<T> metadata, then use Lamar to do its thing to generate the actual adapter to Marten’s projection model. I think this could end up being more efficient than ViewProjection is now at runtime, and certainly lead to cleaner code by eliminating the nested lambdas.
  • Event Store partitioning?
  • Event Store metadata extensions?

EDIT 6/8/2018: We had some discussions about this list on Gitter and I definitely forgot some big things here:

  • The async daemon and projections in general needs to be multi-tenancy friendly
  • Other users are interested in the multi-tenancy via database per tenant that got cut from 2.0 at the last minute

Any thoughts about any of this? Other requests? Comments are open, or head to Gitter to join the conversation about Marten.

 

Marten 3.0 with Sql Server Support????

I want to hold the line that there won’t be any kind of huge Marten 3.0 until there’s enough improvements to the JSON support in Sql Server vNext to justify an effort to finally make Marten database engine neutral. I’m also hoping that Marten 3.0 could completely switch all the Linq support to using queries based on SQL/Json too. See this blog post for why Marten does not yet support Sql Server.

Compiling Code At Runtime with Lamar – Part 2

In my previous post, I introduced Lamar‘s ability and utilities for generating code in memory and compiling that code into usable, in memory assemblies with the Roslyn compiler. In this post I’m going to try to explain the more complicated “frames” model with Lamar that provides the backbone for the related Jasper framework’s middleware and runtime pipeline strategy.

The purpose of the “frames” model is to be able to generate dynamic methods by declaring a list of logical operations in generated code via Frame objects, then let Lamar handle:

  • Finding any missing dependencies of those frames
  • Determine what the necessary variable inputs are
  • Ordering all the frames based on dependency order just prior to generating the code

Before diving into an example, here’s a little class diagram of the main types:

LamarCodeGenClassDiagram

The various types represent:

  • Frame – Named after the StackFrame objects within stack traces in .Net. Models a logical action done in the generated code. Concrete examples in Lamar or Jasper would be calling a method on an object, calling a constructor function, or specific frame objects to create wrapped transaction boundaries or exception handling boundaries.
  • Variable – pretty well what it sounds like. This type models a variable within the generated method, but also includes information about what Frame created it to help order the dependencies
  • IVariableSource – mechanism to “find” or create variables. Examples in Lamar include resolving a service from an IoC container, passing along a method argument, or the example below that tells you the current time
  • IMethodVariables – interface that is used by Frame classes to go find their necessary Variable dependencies.

Alrighty then, let’s make this concrete. Let’s say that we want to generate and use dynamic instances of this interface:

public interface ISaySomething
{
    void Speak();
}

Moreover, I want a version of ISaySomething that will call the following method and write the current time to the console:

public static class NowSpeaker
{
    public static void Speak(DateTime now)
    {
        Console.WriteLine(now.ToString("o"));
    }
}

Our dynamic class for ISaySomething will need to pass the current time to the now parameter of that method. To help out here, there’s some built in helpers in Lamar specifically to write in the right code to get the current time to a variable of DateTime or DateTimeOffset that is named “now.”

To skip ahead a little bit, let’s generate a new class and object with the following code:

// Configures the code generation rules
// and policies
var rules = new GenerationRules("GeneratedNamespace");

// Adds the "now : DateTime" variable rule to 
// our generated code
rules.Sources.Add(new NowTimeVariableSource());

// Start the definition for a new generated assembly
var assembly = new GeneratedAssembly(rules);

// Add a new generated type called "WhatTimeIsIt" that will
// implement the 
var type = assembly.AddType("WhatTimeIsIt", typeof(ISaySomething));

// Getting the definition for the method named "Speak"
var method = type.MethodFor(nameof(ISaySomething.Speak));

// Adding a frame that calls the NowSpeaker.Speak() method and
// adding it to the generated method
var @call = new MethodCall(typeof(NowSpeaker), nameof(NowSpeaker.Speak));
method.Frames.Add(@call);

// Compile the new code!
assembly.CompileAll();

After all that, if we interrogate the source code for the generated type above (type.SourceCode), we’d see this ugly generated code:

    public class WhatTimeIsIt : Lamar.Testing.Samples.ISaySomething
    {


        public void Speak()
        {
            var now = System.DateTime.UtcNow;
            Lamar.Testing.Samples.NowSpeaker.Speak(now);
        }

    }

Some notes about the generated code:

  • Lamar was able to stick in some additional code to pass the current time into a new variable, and call the Speak(DateTime now) method with that value.
  • Lamar is smart enough to put that code before the call to the method (that kind of matters here)
  • The generated code uses full type names in almost all cases to avoid type collisions rather than trying to get smart with using statements in the generated code

So now let’s look at how Lamar was able to add the code to pass along DateTime.UtcNow. First off, let’s look at the code that just writes out the date variable:

public class NowFetchFrame : SyncFrame
{
    public NowFetchFrame(Type variableType)
    {
        // there's some sleight of hand here that's marking
        // this new Variable as created by this frame object
        // so that the dependency relationship is made
        Variable = new Variable(variableType, "now", this);
    }
    
    public Variable Variable { get; }
    
    public override void GenerateCode(
        GeneratedMethod method, 
        ISourceWriter writer)
    {
        writer.WriteLine($"var {Variable.Usage} 
            = {Variable.VariableType.FullName}.{nameof(DateTime.UtcNow)};");
        Next?.GenerateCode(method, writer);
    }
}

In the frame above, you’ll see that the GenerateCode() method writes its code into the source, then immediately turns around and tells the next Frame – if there is one – to generated its code. As the last step to write out the new source code, Lamar:

  1. Goes through an effort to find any missing frames and variables
  2. Sorts them with a topological sort (what frames depend on what other frames or variables, what variables are used or created by what frames)
  3. Organizes the frames into a single linked list
  4. Calls GenerateCode() on the first frame

In the generated method up above, the call to NowSpeaker.Speak(now) depends on the now variable which is in turn created by the NowFetchFrame, and that’s enough information for Lamar to order things and generate the final code.

Lastly, we had to use a custom IVariableSource to teach Lamar how to resolve the now variable. That code looks like this:

public class NowTimeVariableSource : IVariableSource
{
    public bool Matches(Type type)
    {
        return type == typeof(DateTime) || type == typeof(DateTimeOffset);
    }

    public Variable Create(Type type)
    {
        if (type == typeof(DateTime))
        {
            return new NowFetchFrame(typeof(DateTime)).Variable;
        }

        if (type == typeof(DateTimeOffset))
        {
            return new NowFetchFrame(typeof(DateTimeOffset)).Variable;
        }

        throw new ArgumentOutOfRangeException(nameof(type), "Only DateTime and DateTimeOffset are supported");
    }
}

Out of the box, the Lamar + Jasper combination uses variable sources for:

  • Services from the internal IoC container of the application
  • Method arguments
  • Variables that can be derived from a method argument like HttpContext.Request
  • The “now” convention shown here

Summary

I don’t know how popular this thing is going to be, but it’s powering the dynamic code generation of Jasper’s runtime pipeline and it’s the key to Jasper’s efficiency compared to other .Net tools with similar functionality. The early feedback I got was that this model was very abstract and hard to follow. I’m open to suggestions, but the very nature of needing to do the recursive dependency detection and ordering kind of necessitates a model like this in my opinion.

Compiling Code At Runtime with Lamar – Part 1

This code was originally written and proven out in the related Marten and described in a post titled Using Roslyn for Runtime Code Generation in Marten. This code was ripped out of Marten itself, but it’s happily running now in Lamar a couple years later.

As some of you know, I’ve been working on a new library called Lamar that I mean to be the next generation replacement for the venerable, but creaky StructureMap library. Besides the IoC Container support though, Lamar also provides some tooling and a model to generate and compile code at runtime, then ultimately load and use the newly generated types.

If all you want to do is take some C# code and compile that in memory to a new, in memory assembly, you can use
the Lamar.Compilation.AssemblyGenerator class.

Let’s say that you have a simple interface in your system like this:

    public interface IOperation
    {
        int Calculate(int one, int two);
    }

Next, let’s use AssemblyGenerator to compile code with a custom implementation of IOperation that we’ve generated
in code:

        [Fact]
        public void generate_code_on_the_fly()
        {
            var generator = new AssemblyGenerator();

            // This is necessary for the compilation to succeed
            // It's exactly the equivalent of adding references
            // to your project
            generator.ReferenceAssembly(typeof(Console).Assembly);
            generator.ReferenceAssembly(typeof(IOperation).Assembly);

            // Compile and generate a new .Net Assembly object
            // in memory
            var assembly = generator.Generate(@"
using Lamar.Testing.Samples;

namespace Generated
{
    public class AddOperator : IOperation
    {
        public int Calculate(int one, int two)
        {
            return one + two;
        }
    }
}
");

            // Find the new type we generated up above
            var type = assembly.GetExportedTypes().Single();
            
            // Use Activator.CreateInstance() to build an object
            // instance of our new class, and cast it to the 
            // IOperation interface
            var operation = (IOperation)Activator.CreateInstance(type);

            // Use our new type
            var result = operation.Calculate(1, 2);
         
            result.ShouldBe(3);
        }

There’s only a couple things going on in the code above:

  1. I added an assembly reference for the .Net assembly that holds the IOperation interface
  2. I passed a string to the ​GenerateCode() method, which successfully compiles my code and hands me back a .Net Assembly object
  3. Load the newly generated type from the new Assembly
  4. Use the new IOperation

If you’re not perfectly keen on doing brute force string manipulation to generate your code, you can
also use Lamar’s built in ISourceWriter to generate some of the code for you with
all its code generation utilities:

[Fact]
public void generate_code_on_the_fly_using_source_writer()
{
    var generator = new AssemblyGenerator();

    // This is necessary for the compilation to succeed
    // It's exactly the equivalent of adding references
    // to your project
    generator.ReferenceAssembly(typeof(Console).Assembly);
    generator.ReferenceAssembly(typeof(IOperation).Assembly);


    var assembly = generator.Generate(x =>
    {
        x.Namespace("Generated");
        x.StartClass("AddOperator", typeof(IOperation));
        
        x.Write("BLOCK:public int Calculate(int one, int two)");
        x.Write("return one + two;");
        x.FinishBlock();  // Finish the method
        
        x.FinishBlock();  // Finish the class
        x.FinishBlock();  // Finish the namespace
    });

    var type = assembly.GetExportedTypes().Single();
    var operation = (IOperation)Activator.CreateInstance(type);

    var result = operation.Calculate(1, 2);

    result.ShouldBe(3);
}

In Part 2, I’ll talk about the “frames” model that’s heavily used within Jasper (shown in this post).

Roslyn Powered Code Weaving Middleware

Jasper, with a big assist from Lamar, supports a unique middleware strategy that I believe will result in significantly higher performance, cleaner exception stack traces (and that matters), and better visibility into its runtime pipeline than similar frameworks in .Net. If you want to follow along with this code, you’ll need at least Jasper 0.8.3 that’s being indexed by Nuget as you read this and Jasper.SqlServer 0.8.2 because I managed to find some bugs while writing this post. Of course.

At this point, most .Net frameworks for messaging, local command running, or service bus message handling have some sort of support for nested middleware or what I used to call the Russian Doll Model. ASP.Net Core middleware is one example of this. Behaviors from NServiceBus is another example.

The great thing about this model when used judiciously is that it’s a great way to handle certain kinds of cross cutting concerns outside of your main HTTP route handling or message handling code. Used well, middleware will allow you to reuse a lot of code and simplify your application code by removing the need for repetitive infrastructure or workflow code.

In web development projects I’ve used or seen used middleware for:

  • Transaction management or unit of work semantics
  • Input validation where the middleware can stop further processing
  • Authentication
  • Authorization

Taking just authentication and authorization as examples, in many cases I’ve seen teams be able to get away with completely ignoring these concerns upfront while focusing on the core business functionality, then being able at a later time to just add middleware for authentication and authorization to take care of these concerns without having any impact on the existing business functionality. That’s a powerful exploitation of architectural reversibility to make development easier.

I’ve also seen this technique taken way, way too far to the point where the code was very difficult to understand. My advice is something along the lines of “don’t be stupid” and pay attention to what’s happening in your code if the middleware usage does more harm than good.

What Came Before and Why It Was Problematic

In FubuMVC, we supported a middleware strategy we called “behaviors” with this interface:

    public interface IActionBehavior
    {
        Task Invoke();
        Task InvokePartial();
    }

Calling the main HTTP action in FubuMVC’s equivalent to controller actions was a behavior. Reading the input body was a behavior. The common things like validation, authorization, authentication, and transactional management were potentially separate behavior objects. At runtime, we would use an IoC container to build out all the behaviors for the matched route, with each “outer” behavior having a reference to its “inner” behavior and each behavior having whatever services it needed to do its work injected into its constructor function.

When it worked well, it was awesome — at least in ~2010 terms when we .Net developers were just thrilled to break away from WebForms. Alas, this model has some issues:

  • It didn’t support an asynchronous model like you’d expect with more recent tooling
  • It results in an absurd number of objects being allocated for each HTTP request. Add in the mechanics around IoC scoped containers, and there was a lot of overhead just to assemble the things you needed to handle the request
  • When something went wrong, the stack traces were epic. There was so much FubuMVC-related framework noise code in the stack trace that many developers would just throw up their hands and run away (even though the real problem was clearly in their own code if they’d just looked at the top of the stack trace, but I digress….)
  • We had tools to visualize the full chain of behaviors for each route, but I don’t think that was ever fully effective for most developers who used FubuMVC

Jasper’s Approach

Not that long after publicly giving up on FubuMVC, I happened to see some articles about how the new Roslyn “compiler as a service” would allow you to compile and load assemblies on the fly from generated C# code. I theorized that this new Roslyn behavior could be exploited to create a new runtime pipeline for HTTP or messaging frameworks where you still had something like FubuMVC’s old Behavior model for cross cutting concerns, but you used some kind of code generation to “weave” in that functionality around your application code.

To make this more concrete, consider this function from a load testing harness that:

  • Handles an HTTP POST request to the url “/one”
  • Creates a new message object
  • Writes a record to the database tracking that the message was sent for the sake of verifying behavior later
  • Sends a message using Jasper’s Sql Server-backed messaging persistence

This is the actual code for the function that handles the HTTP POST:

        
[SqlTransaction] 
public static async Task post_one(IMessageContext context, SqlTransaction tx)
{
    // Loads a pre-packaged message body from a JSON string
    var target1 = JsonConvert.DeserializeObject(_json1);
    target1.Id = Guid.NewGuid();

    await tx.StoreSent(target1.Id, "Target");

    // Send a message through Jasper
    await context.Send(target1);
}

When Jasper bootstraps, it will generate a new class for each known route that inherits from this class partially shown below:

    public abstract class RouteHandler
    {
        public abstract Task Handle(HttpContext httpContext);

        // Other methods we don't care about here
    }

The RouteHandler classes are all compiled into a new assembly on the fly, then a single instance of each is instantiated and kept in the routing tree ready to handle any incoming requests.

The various instances of RouteHandler mediate between Jasper’s built in HTTP router and the interface it expects, the action methods that handle the actual request, and any Jasper middleware that might be mixed in. In the case of the post_one method shown above, the generated RouteHandler class is this (also on a Gist if the formatting is unreadable in your browser):

    public class SqlSender_HomeEndpoint_post_one : Jasper.Http.Model.RouteHandler
    {
        private readonly SqlServerSettings _sqlServerSettings;
        private readonly IMessagingRoot _messagingRoot;

        public SqlSender_HomeEndpoint_post_one(SqlServerSettings sqlServerSettings, IMessagingRoot messagingRoot)
        {
            _sqlServerSettings = sqlServerSettings;
            _messagingRoot = messagingRoot;
        }

        public override async Task Handle(Microsoft.AspNetCore.Http.HttpContext httpContext)
        {
            var messageContext = _messagingRoot.NewContext();
            using (System.Data.SqlClient.SqlConnection sqlConnection2 = new System.Data.SqlClient.SqlConnection(_sqlServerSettings.ConnectionString))
            {
                await sqlConnection2.OpenAsync();
                var sqlTransaction = sqlConnection2.BeginTransaction();
                await Jasper.SqlServer.SqlServerOutboxExtensions.EnlistInTransaction(messageContext, sqlTransaction);
                await SqlSender.HomeEndpoint.post_one(messageContext, sqlTransaction);
                sqlTransaction.Commit();
                await messageContext.SendAllQueuedOutgoingMessages();
                sqlConnection2.Close();
            }
        }
    }

So let’s deconstruct this generated code a little bit because there’s clearly more going on than just delegating to the post_one method. If you look up above at the post_one method, you’ll see that it’s decorated with an [SqlTransaction]attribute. That adds Jasper’s Sql Server transactional middleware into the mix. All told, the generated code:

  1. Creates a new IMessageContext object that the post_one method needs
  2. Creates and opens a new SqlConnection to the connection string specified in configuration (through the SqlServerSettings object)
  3. Starts a new transaction
  4. Enlists the IMessageContext in the current transaction using Jasper’s Sql Server-backed outbox support
  5. Calls post_one with its two arguments
  6. Commits the transaction
  7. Flushes out any queued up, outgoing messages into Jasper’s local sending queues
  8. Closes and disposes the open connection

What you don’t see in that generated code is maybe more important:

  • In this case, Jasper/Lamar didn’t have to resort to using a scoped IoC container of any kind when handling this HTTP request. That’s a lot of runtime overhead that just disappeared as compared to most other .Net frameworks that perform similar functions to Jasper
  • When something does go wrong, the exception stack traces are going to be much simpler because everything is happening in just a few methods now instead of having lots of wrapped objects implementing a middleware strategy
  • Very few object allocations compared to the way FubuMVC accomplished the exact same functionality, and that’s hugely advantageous for performance in high volume systems

I think a deeper dive blog post later is probably justified, but the implementation of the middleware is this class below:

    public class SqlTransactionFrame : AsyncFrame
    {
        private Variable _connection;
        private bool _isUsingPersistence;
        private Variable _context;

        public SqlTransactionFrame()
        {
            Transaction = new Variable(typeof(SqlTransaction), this);
        }

        public bool ShouldFlushOutgoingMessages { get; set; }

        public Variable Transaction { get; }

        public override void GenerateCode(GeneratedMethod method, ISourceWriter writer)
        {
            writer.Write($"await {_connection.Usage}.{nameof(SqlConnection.OpenAsync)}();");
            writer.Write($"var {Transaction.Usage} = {_connection.Usage}.{nameof(SqlConnection.BeginTransaction)}();");


            if (_context != null && _isUsingPersistence)
            {
                writer.Write($"await {typeof(SqlServerOutboxExtensions).FullName}.{nameof(SqlServerOutboxExtensions.EnlistInTransaction)}({_context.Usage}, {Transaction.Usage});");
            }


            Next?.GenerateCode(method, writer);
            writer.Write($"{Transaction.Usage}.{nameof(SqlTransaction.Commit)}();");


            if (ShouldFlushOutgoingMessages)
            {
                writer.Write($"await {_context.Usage}.{nameof(IMessageContext.SendAllQueuedOutgoingMessages)}();");
            }

            writer.Write($"{_connection.Usage}.{nameof(SqlConnection.Close)}();");
        }

        // This is necessary to identify other things that need to 
        // be written into the generated method as dependencies
        // to this Frame
        public override IEnumerable<Variable> FindVariables(IMethodVariables chain)
        {
            _isUsingPersistence = chain.IsUsingSqlServerPersistence();

            _connection = chain.FindVariable(typeof(SqlConnection));
            yield return _connection;


            if (ShouldFlushOutgoingMessages)
            {
                _context = chain.FindVariable(typeof(IMessageContext));
            }
            else
            {
                // Inside of messaging. Not sure how this is gonna work for HTTP yet
                _context = chain.TryFindVariable(typeof(IMessageContext), VariableSource.NotServices);
            }

            if (_context != null) yield return _context;
        }
    }

There’s a little bit of complicated goop around the code generation that’s necessary to allow Lamar to properly order the steps in the code generation, but the code generation itself is just writing C# code out — and the new C# string interpolation (finally) makes that pretty approachable in my opinion, especially compared to having to use .Net Expressions or emitting IL.

 

More Information

I wrote a blog post earlier this year called Jasper’s Roslyn-Powered “Special Sauce” that laid out some of the same arguments.

Using Roslyn for Runtime Code Generation in Marten presented an early form of the code generation and runtime compilation that ended up in Lamar. We ripped this out of Marten, but it still served as a proof of concept later for Jasper;)

Really, this amounts to what I think is an easier to use form of Aspect Oriented Programming.

Jasper Command Line App Support you Wish Your Framework Already Had

Jasper is a new messaging and command runner framework targeting Netstandard2 my shop has been building as a replacement for part of the old FubuMVC framework. I wrote about the general vision and rationale here.

Earlier today I made a v0.7.0 release of Jasper and its related extensions. The pace of development has kicked back up because we’re getting ready to start doing load and chaos testing with our QA folks later this week and we’re already transitioning some smaller, low volume systems to Jasper. The highlights this time are:

  • A lot of optimization for the “cold start” time, especially if you’re using Jasper in combination with ASP.Net Core. I collapsed the ASP.Net Core support back to the core library, so this post is already obsolete.
  • The integration with ASP.Net Core is a lot tighter. For example, Jasper is now using the ASP.Net Core logging under its covers, the ASP.Net Core IHostedService, and just generally plays nicer when used in combination with ASP.Net Core applications.
  • Jasper now has some support for stateful sagas, but only with Marten-backed persistence. I’ll blog about this one soon, and there will be other saga persistence options coming fairly soon. Sql Server backed persistence at a bare minimum.
  • Finer grained control over how certain message types are published
  • Mild improvements to the Marten integration. Again, Jasper isn’t hard coupled to Marten and Postgresql, but it’s just been easy to prove out concepts with Marten first.
  • More command line usages that I’m showing in the rest of this post;)

Command Line Integration

First off, let’s say that you have a simple Jasper application that listens for incoming messages at a designated port configured with this class:

public class SubscriberApp : JasperRegistry
{
    public SubscriberApp()
    {
        // Listen for incoming messages via the
        // built in, socket transport in a 
        // fire and forget way at port 2222
        Transports.LightweightListenerAt(2222);
    }
}

To run your Jasper application as a console application, you can use the Jasper.CommandLine library as a quick helper that also adds some diagnostic commands you may find helpful during both development and deployment time. Using your SubscriberApp class above, you can bootstrap your application in a console application like this:

class Program
{
    static int Main(string[] args)
    {
        return JasperAgent.Run(args);
    }
}

Once that’s done, you can immediately run your application from the command line with dotnet run, which would give you some output like this:

Running service 'SubscriberApp'
Application Assembly: Subscriber, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Hosting environment: Production
Content root path: [the IHostedEnvironment.ContentRootPath value]
Hosted Service: Jasper.Messaging.MessagingActivator
Hosted Service: Jasper.Messaging.NodeRegistration
Listening for loopback messages
Listening for messages at [url]/messages
Listening for messages at [url]/messages/durable

Active sending agent to loopback://replies/
Active sending agent to loopback://retries/
Handles messages:
            [Message Type]: [Handler Type and Handler Method Name]

Now listening on: [listener Uri]
Application started. Press Ctrl+C to shut down.

Other than a little bit of contextual information, it’s about what you would get with the ASP.Net Core command line support. If you’re not familiar with the dotnet cli, you can pass command line arguments to your Program.Main() ​method by using double dashes to separate arguments that apply to dotnet run from the arguments that get passed into your main method. Using the Oakton library for parsing Linux style command arguments and flags, your Jasper application can also respond to other commands and optional flags.

Knowing all that, this:

dotnet run -- -v

or

dotnet run -- --verbose

will run your application with console and debug loggers, and set the minimum log level in the ASP.Net Core logging to “Debug.”

Alternatively, you can also override the log level by:

dotnet run -- --log-level Information

or

dotnet run -- -l Trace

where the value is one of the values in the LogLevel enumeration.

To override the environment your application is running under, you can use this flag:

dotnet run -- --environment Development

or use the “-e” short version of that.

So what, what else do you got?

You can run a Jasper application, but there’s actually quite a bit more. If you type dotnet run -- ?, you can see the other available commands:

 

Screen Shot 2018-04-11 at 3.53.09 PM

The “export-json-schema” and “generate-message-types” commands are from an extension library that allows you to export JSON schema documents for the known message types or generate C# classes with the necessary Jasper message type identity from JSON schema documents. The command line support is extensible, allowing you to add prepackaged commands from addon Nugets or even be exposed from your own application. I’m going to leave that to a later post or *gasp*, updated documentation.

Preview the Generated Code

If you read my earlier post on Jasper’s Roslyn-Powered “Special Sauce,” you know that Jasper internally generates and compiles glue code to handle messages or HTTP requests. To help troubleshoot applications or just to understand the interplay between message handlers and any configured middleware, you can use this command to either list out the generated code or export it to a file:

dotnet run -- code -f export.cs

 

Check out the IoC Container Configuration

As a long time IoC tool author and user, I’m painfully aware that people run into issues with service registrations being incorrect or using erroneous lifecycles. To help ease those issues, Jasper allows you to see the service registrations of your entire application with this command:

dotnet run -- services

This is just displaying the output of the Lamar WhatDoIHave() report, similar to StructureMap’s WhatDoIHave() functionality.

Validate the System

As part of deployment or maybe even local development, you can choose to just start up the application, run all the registered environment checks, and verify that all the known message handlers and HTTP routes can be successfully compiled — with oodles of ugly red textual output if any check along the way fails. That’s done with dotnet run -- validate.

 

Manage Subscriptions

It’s admittedly kind of boring and I’m running out of time before I need to head home, but there is a dotnet run -- subscriptions command that you can use to manage message subscriptions at deployment or build time that’s documented here.

 

Next up:

I’ll get a decent, business facing example of Jasper’s stateful saga support.

 

Lamar v0.9 — Decorators and “MVP”

Lamar, which started life as “BlueMilk,” is the now permanent codename for my next generation IoC tool that is meant to replace StructureMap in new .Net Core projects. I did a little bit of work this morning to add in at least the basic functionality for decorators similar to what StructureMap has supported since 3.0 (but no other kinds of interception for now):

[Fact]
public void decorator_example()
{
    var container = new Container(_ =>
    {
        // This usage adds the WidgetHolder as a decorator
        // on all IWidget registrations
        _.For<IWidget>().DecorateAllWith<WidgetHolder>();
        
        // The AWidget type will be decorated w/ 
        // WidgetHolder when you resolve it from the container
        _.For<IWidget>().Use<AWidget>();
        
        _.For<IThing>().Use<Thing>();
    });

    // Just proving that it actually works;)
    container.GetInstance<IWidget>()
        .ShouldBeOfType<WidgetHolder>()
        .Inner.ShouldBeOfType<AWidget>();
}

This change, and a few other miscellaneous fixes for integration with Jasper, are available on Nuget in Lamar 0.9.0. At this point, I feel like Lamar is already at the feature set I intend to support for a 1.0 release. It’s going to at least go through some load testing at my work over the next month, and still lacks documentation (but most of it behaves identically to StructureMap or the ASP.Net Core DI compliance). All the same,  I’m declaring it ready for real usage if anybody is up for trying it out and hopefully sharing any feedback. It should *mostly* be a drop in replacement for StructureMap if you’re not doing too much weird stuff.

For more information, see some of my previous blog posts about Lamar/BlueMilk: