Automated Testing of Message Based Systems

Technology wise, everything in this blog post is related to OSS projects you’re very unlikely to ever use (FubuMVC and Storyteller 3), but I’d hope that the techniques and ideas would still be useful in whatever technical stack you happen to be using. At a minimum, I’m hoping this blog post is useful to some of our internal teams who have to wrestle with the tooling and the testing scenarios in this blogpost. And who knows, we still might try to make a FubuMVC comeback (renamed as “Jasper”) if the dust ever does settle on .Net Core and ASP.Net Core.

We heavily utilize message-based architectures using service bus tools at work. We’ve also invested somewhat in automating testing against those message based integrations. Automating tests against distributed systems with plenty of asynchronous behavior has been challenging. We’ve come up with a couple key aspects of our architectures and technical tooling that I feel have made our automated  testing efforts around message-based architectures easier mechanically, more reliable, and even create some transparency into how the system actually behaves.

My recipe for automating tests against distributed, messaging systems is:

  1. Try to choose tools that allow you to “inject” configuration programmatically at runtime. As I’ll try to make clear in this post, a tight coupling to the .Net configuration file can almost force you into having to swallow the extra complexity of separate AppDomain’s
  2. Favor tools that require minimal steps to deploy. Ideally, I love using tools that allow for fullblown xcopy deployment, at least in functional testing scenarios
  3. Try very hard to be able to run all the various elements of a distributed application in a single process because that makes it so much simpler to coordinate the test harness code with all the messages going through the greater system. It also makes debugging failures a lot simpler.
  4. At worst, have some very good automated scripts that can install and teardown everything you need to be running in automated tests
  5. Make sure that you can cleanly shut your distributed system down between tests to avoid having friction from locked resources on your testing box
  6. Have some mechanism to completely rollback any intermediate state between tests to avoid polluting system state between tests

Repeatable Application Bootstrapping and Teardown

The first step in automating a message-based system is simply being able to completely and reliably start the system with all the related publisher and subscriber nodes you need to participate in the automated test. You could demand a black box testing approach where you would deploy the system under test and all of its various services by scripting out the installation and startup of Windows services or *nix daemon processes or programmatically launching other processes to host various distributed elements from the command line.

Personally, I’m a big fan of using whitebox testing techniques to make test automation efforts much more efficient, meaning that I think

My strong preference however is to adopt architectures that make it possible for the test automation harness itself to bootstrap and start the entire distributed system, rather than depending on external scripts to deploy and start the application services. In effect, this has meant running all of the normally distributed elements collapsed down to the single test harness process.

Our common technical stack at the moment is:

  1. FubuMVC 3 as both our web application framework and as our service bus
  2. Storyteller 3 as our test automation harness for integrated acceptance testing
  3. LightningQueues as a “store and forward” persistent queue transport. Hopefully you’ll hear a lot more about this tool when we’re able to completely move off of Esent and onto LightningDB as the underlying storage engine.
  4. Serenity as an add-on library as a standard recipe to host FubuMVC applications in Storyteller with diagnostics integration

In all cases, these tools can be programmatically bootstrapped in the test harness itself. LightningQueues being “x-copy deployable” as our messaging transport has been a huge advantage over queueing tools that require external servers or installations. Additionally, we have programmatic mechanisms in LightningQueues to delete any previous state in the persistent queues to prevent leftover state bleeding between automated tests.

After a lot of work last year to streamline the prior mess, a FubuMVC web and/or service bus node application is completely described with a FubuRegistry class (here’s a link to an example), conceptually similar to the “Startup” concept in the new ASP.Net Core.

Having the application startup and teardown expressed in a single place makes it easy for us to launch the application from within a test harness. In our Serenity/Storyteller projects, we have a base “SerenitySystem” class we use to launch one or more applications before any tests are executed. To build a new SerenitySystem, you just supply the name of a FubuRegistry class of your application as the generic argument to SerenitySystem like so:

public class TestSystem : SerenitySystem<WebsiteRegistry>

That declaration above is actually enough to tell Storyteller how to bootstrap the application defined by “WebsiteRegistry.”

It’s not just about bootstrapping applications, it’s also about being able to cleanly shut down your distributed application. By cleanly, I mean that you release all system resources like IP ports or file locks (looking at you Esent) that could prevent you from being able to quickly restart the application. This becomes vital anytime it takes more than one iteration of code changes to fix a failing test. My consistent experience over the years is that the ability to quickly iterate between code changes and executing a failing test is vital for productivity in test automation efforts.

We’ve beaten this problem through standardization of test harnesses. The Serenity library “knows” to dispose the running FubuMVC application when it shuts down, which will do all the work of releasing shared resources. As long as our teams use the standard Serenity test harness, they’re mostly set for clean activation and teardown (it’s an imperfect world and there are *always* complications).

Bootstrapping the Entire System in One Process

Ideally, I’d prefer to get away with running all of the running service bus nodes in a single AppDomain. Here’s a pretty typical case for us, say you have a web application defined as “WebRegistry” that communicates bi-directionally with a headless service bus service defined by a “BusRegistry” class that normally runs in a Windows service:

    // FubuTransportRegistry is a special kind of FubuRegistry
    // specifically to help configure service bus applications
    // BusSettings would hold configuration data for BusRegistry
    public class BusRegistry : FubuTransportRegistry
    {
    }

    public class WebRegistry : FubuTransportRegistry
    {
        
    }

To bootstrap both the website application and the bus registry in a single AppDomain, I could use code like this:

        public static void Bootstrap_Two_Nodes()
        {
            var busApp = FubuRuntime.For<BusRegistry>();
            var webApp = FubuRuntime.For<WebRegistry>(_ =>
            {
                // WebRegistry would normally run in full IIS,
                // but for the test harness we tend to use 
                // Katana to run all in process
                _.HostWith();
            });

            // Carry out tests that depend on both
            // busApp and webApp
        }

This is the ideal, and I hope to see us use this pattern more often, but it’s often defeated by tools that have hard dependencies on .Net’s System.Configuration that may cause configuration conflicts between running nodes. Occasionally we’ll also have conflicts between assembly versions across the nodes or hit cases where we cannot have a particular assembly deployed in one of the nodes.

In these cases we resort to using a separate AppDomain for each service bus application. We’ve built this pattern into Serenity itself to standardize the approach with what I named “Remote Systems.” For an example from the FubuMVC acceptance tests, we execute tests against an application called “WebsiteRegistry” running as the main application in the test harness, and open a second AppDomain for a testing application called “ServiceNode” that exchanges messages with “WebsiteRegistry.” In the Serenity test harness, I can just declare the second AppDomain for “ServiceNode” like so:

    public class TestSystem : SerenitySystem<WebsiteRegistry>
    {
        public TestSystem()
        {
            // Running the "ServiceNode" app in a second AppDomain
            AddRemoteSubSystem("ServiceNode", x =>
            {
                x.UseParallelServiceDirectory("ServiceNode");
                x.Setup.ShadowCopyFiles = false.ToString();
            });
        }

The code above directs Serenity to start a second application found at a directory named “ServiceNode” that is parallel to the main application. So if the main application is hosted at “src/FubuMVC.IntegrationTesting”, then “ServiceNode” is at “src/ServiceNode.” The Serenity harness is smart enough to figure out how to launch the second AppDomain pointed at this other directory. Serenity can also bootstrap that application by scanning the assemblies in that AppDomain to find a class that inherits from FubuRegistry — very similar to how ASP.Net Core is going to use the Startup class convention to bootstrap applications.

The biggest problem now is generally in dealing with the asynchronous behavior in the different AppDomain’s and “knowing” when it’s safe for the test harness to start checking for the outcome of the messages that are processed within the “arrange” and “act” portions of a test. In a following post, I’ll talk about the tooling and technique we use to coordinate activities between the different AppDomain’s.

 

 

This All Changes in .Net Core

AppDomain’s and .Net Remoting all go away in .Net Core. While no one is really that disappointed by those features going away, I think that’s going to set back the state of test automation tools in .Net for a little while because almost every testing tool uses AppDomain’s in some fashion. For our part, my thought is that we’d move to launching all new Process’s for the additional service bus nodes in testing.

I know there’s also some plans for an “AssemblyLoadContext” that sounds to me like a better, lightweight way of doing the kinds of Assembly loading sandboxes for testing that are only possible with separate AppDomain’s in .Net today. Other than rumors and an occasionally cryptic hint from members of the ASP.Net team, there’s basically no information about what AssemblyLoadContext will be able to do.

The new “Startup” mechanism in .Net Core might serve in the exact same fashion that our FubuRegistry does today in FubuMVC. That should make it much easier to carry out this strategy of collapsing distributed or microservice applications down into a single process.

I also think that the improved configuration mechanisms in ASP.Net Core (is this in .Net Core itself? I really don’t know). The tight coupling of certain libraries we use to the existence of that single app.config/web.config file today is a headache and the main reason we’re sometimes forced into the more complicated, multiple AppDomain issue.

What’s Next

This blog post went a lot longer than I anticipated, so I cut it in half. Next time up I’ll talk about how we coordinate the test harness timing with the various messaging nodes and how we expose application diagnostics in automated test outputs to help understand what’s actually happening in your application when things fail or just run too slowly.

 

 

How we do Semantic Logging

I know full well that what I’m showing here is polarizing and some of you are going to hate it, but what we did does have some significant benefits and it’s possible it could be pulled off later with cleaner usage mechanics. When you read this and start saying, “isn’t this like Serilog?”, please just read to the end. 

I’ve frequently used the term “semantic logging” to describe the mechanism we still use in FubuMVC for our logging abstraction. By semantic logging, I mean that we log strong-typed messages for most framework audit and debug actions.

To make that concrete, this is part of our ILogger interface that FubuMVC uses internally:

    public interface ILogger
    {
        // LogTopic is yes, a standardized base
        // class with some basic properties for
        // timestamps and a Guid Id
        void DebugMessage(LogTopic message);
        void InfoMessage(LogTopic message);

        // This is the mechanism for conditional logging if
        // there is a registered listener for whatever T is
        void DebugMessage<T>(Func<T> message) where T : class, LogTopic;
        void InfoMessage<T>(Func<T> message) where T : class, LogTopic;
    }

Taking the service bus part of FubuMVC as an example, we have these log topic types that get logged at various points in message sending and handling:

  1. EnvelopeSent — in service bus parlance, an “envelope” would be a message plus whatever metadata the service bus needs to get it to the right place.
  2. EnvelopeReceived
  3. MessageSuccessful
  4. MessageFailed

For a concrete example from inside our service bus features, we log an EnvelopeSent log record any time a message is sent from the service bus client:

private void sendToChannel(Envelope envelope, ChannelNode node)
{
    var replyUri = _router.ReplyUriFor(node);

    var headers = node.Send(envelope, _serializer, replyUri: replyUri);
    _logger.InfoMessage(() => new EnvelopeSent(new EnvelopeToken
    {
        Headers = headers,
        Message = envelope.Message
    }, node));
}

As you can see above, we pass a Func<EnvelopeSent> into the logger.InfoMessage() method instead of directly building an EnvelopeSent object. We do that so that the logging can be optional, so that if nothing is listening for the EnvelopeSent log record type, that Func in never executed. Some of you might argue that this is a little less efficient at runtime than doing the if (_logger.ListensFor(typeof(EnvelopeSent)) _logger.InfoMessage(new EnvelopeSent{}); approach and you’d be correct, but I prefer using the Func approach to express the optional logging because I think it’s more terse and easier to read.

Internally, the actual “sinks” for these log records have to implement this interface (partially elided for space):

    public interface ILogListener
    {
        bool IsDebugEnabled { get; }
        bool IsInfoEnabled { get; }

        // Does this particular listener
        // care about a log record type?
        bool ListensFor(Type type);

        void DebugMessage(object message);
        void InfoMessage(object message);

    }

With this interface, you are able to subscribe for certain log record types being logged by the application.

We manage both ILogger and the full collection of ILogListener’s through our application’s IoC container. While there probably isn’t a more polarizing technique in the software world than using an IoC tool, in our case I think it’s been very advantageous for us because of how easy that makes it to add or remove log listeners and to govern the lifecycle or scoping of log listeners (think about having a log listener scoped to a single HTTP request that makes it stupidly easy to correlate log messages to a certain HTTP request).

 

The Downside

Some of my coworkers don’t like this approach because of the need to add all the extra Type’s to your code. To their point, I don’t think you’d bother to make every single log message its own special type, only things that are more valuable to key off of in system diagnostics or in tooling like our test automation support sample I’m showing in another section below. We do have some basic “Info(string message) or Debug(string message)” support too in our ILogger, but my advice for that kind of thing has been to go straight to some kind of low level logging tool like NLog or log4net.

The benefits are richer system monitoring because it’s so easy to intelligently parse and filter the information being logged.

Some Valuable Usages

 

  • Our HTTP request tracing in FubuMVC depends on a custom ILogListener that tracks any and all log topic records to the record of that HTTP request. By being able to listen for only certain log topic Type’s, we can easily move our diagnostic trace level from nothing to a production mode where we only hang on to certain types of logging actions to a very verbose, record everything mode for local development. Ditto for our service bus support inside of FubuMVC (was FubuTransportation).
  • Having the strong typed log record messages made it fairly simple to create powerful visualizations of different logging actions in FubuMVC’s built in diagnostics
  • I actually think it’s easier to filter out what logging message types you care about listening for than trying to filter logging output by the classes or namespaces in your application like folks do with tools like log4net or NLog.
  • We can inject custom ILogListener’s in automated testing harnesses to gather a lot of application diagnostics and embed these diagnostics directly into our acceptance testing output reports. That’s been extremely valuable for us to troubleshoot failing tests or understand performance problems in our code by having an easy correlation between each automated test and the logging records.  I’ll write a blog post about how we do that someday.
  • In my very next blog post I’ll talk about how we use an ILogListener to monitor the activity of a service bus applications so that you can much more reliably coordinate automated test harnesses with the application code.

Replace with Serilog the next time around?

I’m very happy with what we were able to do in terms of its impact, and “semantic logging” has consistently been in my “keep from FubuMVC” column in our planning for whatever we do next. In the longer term though, I think I’d like look to look at using Serilog as our underlying logging mechanism and just figure out how we could inject custom listeners into Serilog to replace our diagnostic and test automation abilities. It would mean giving up on the strong typed messages that *I* like, but might be more palatable for other developers. Now that we’ve mostly replaced server side rendering with a React.js based UI in our diagnostics, it might make more sense anyway to do the visualizations against a JSON body.

Mostly though, that’s just a way to have less custom OSS code that I have to support and maintain;)

 

What about…?

Anytime I write a blog post like this I get a flood of “have you tried XYZ?” kind of questions about other tools that I may or may not have heard of. I’ll try to cover some of them:

  • log4net? NLog? – now that NLog is strong named (boo!), I don’t have any preference for either and I would never in a million years consider coupling any of my OSS projects to either. In other news, strong naming still sucks and it’s something you have to consider when you release an OSS tool
  • There is the Semantic Logging Block tool from Microsoft P&P. I haven’t used it, and my informal Twitter poll on it suggests that folks prefer Serilog over it.
  • What about taking a dependency on Common Logging then doing whatever you want for the actual logging? I looked at doing this years ago when we first introduced logging into FubuMVC and decided against it. My thinking is that Common Logging suffers from a “boiling the ocean” kind of problem that bloats its API surface.
  • Liblog? It’s probably a better alternative to Common Logging without some of the compatibility headaches brought on by strong naming conflicts, but doesn’t really address the idea of semantic logging
  • I know that once upon a time the Glimpse guys were throwing around a similar idea for semantic logging (they weren’t using the same terminology though) with rich logging messages that you could consume in your own application monitoring tooling.

New Marten Release and What’s Next?

I uploaded a new Nuget for Marten v0.9.2 yesterday with a couple new features and about two weeks worth of bug fixes and some refinements. You can find the full list of issues and pull requests in this release from the v0.9.1 and v0.9.2 milestones in GitHub.

The highlight of this release in terms of raw usability is probably some overdue improvements to Marten’s underlying schema management:

  1. Marten can detect when the configured upsert functions are missing or do not match the configuration and rebuild them
  2. Marten can detect missing or changed indexes and make the appropriate updates.

Some other things that are new:

  • There’s now a synchronous batch querying option
  • You can now use the AsJson() Linq operator in combination with Select() transforms (this is going to get its own blog post soon-ish).
  • The default transaction isolation level is ReadCommitted
  • It won’t provide much value until there’s more there, but I’ve added some rolling buffer queueing support for being able to do asynchronous projections in the event store. There’ll be a blog post about that one soon just to see if I can trick some of you into being technical reviewers or contributors on that one;)

The two big features are discussed below:

Paging Support

We flat out copied part of RavenDb’s paging support for more efficient paging support. Take the example of showing a large data set in a user interface and wanting to do that one page at a time. You need to know how many total documents match the query criteria to be able to present an accurate paging bar. Fortunately, you can get that total number now without making a second round trip to the database with this syntax:

// We're going to use stats as an output
// parameter to the call below, so we
// have to declare the "stats" object
// first
QueryStatistics stats = null;

var list = theSession
    .Query<Target>()
    .Stats(out stats)
    .Where(x => x.Number > 10).Take(5)
    .ToList();

list.Any().ShouldBeTrue();

// Now, the total results data should
// be available
stats.TotalResults.ShouldBe(count);

In combination with the existing support for the Take() and Skip() Linq operators, you should have everything you need for efficient paging with Marten.

Include() inside of Compiled Queries

The Include() feature is now usable from within the compiled query feature, so finally, two of our best features for optimizing data access can work together. Below is a sample:

public class IssueByTitleIncludingUsers : ICompiledQuery<Issue>
{
    public string Title { get; set; }
    public User IncludedAssignee { get; private set; } = new User();
    public User IncludedReported { get; private set; } = new User();
    public JoinType JoinType { get; set; } = JoinType.Inner;

    public Expression<Func<IQueryable<Issue>, Issue>> QueryIs()
    {
        return query => query
            .Include<Issue, IssueByTitleIncludingUsers>(x => x.AssigneeId, x => x.IncludedAssignee, JoinType)
            .Include<Issue, IssueByTitleIncludingUsers>(x => x.ReporterId, x => x.IncludedReported, JoinType)
            .Single(x => x.Title == Title);
    }
}

 

What’s Next?

Besides whatever bug fixes come up, I think the next things I’m working on for the document database support are soft deletes, bulk insert improvements, and finally getting a versioned document story going. On the event store side of things, it’s all about projections. We’ll have a working asynchronous projection feature in the next release, maybe support for arbitrary categorization inside of aggregated projections, and some preliminary support for Javascript projections.

Got other requests, needs, or problems with Marten? Tell us all about it anytime in the Gitter room.

 

Using Mocks or Stubs, Revisited

This post is a request from work. As part of our ongoing effort to convert a very large application from RavenDb to Marten for its backing persistence, we want to take some time to reconsider our automated testing strategies in regards to using unit tests versus integration tests versus full end to end tests.

I originally wrote a series of blog posts on these subjects in my CodeBetter days about a decade ago (the formatting of the old posts has all been destroyed after several blog engine migrations, sorry about that):

I read over those posts just now and feel like the content mostly holds up today (concepts and fundamentals tend to be useful much longer than any specific technology).

What’s Different Today?

For one, a couple years back there was a somewhat justified backlash against the over use of mocking libraries in unit tests. For another, I think there’s more of a bias in favor of doing much more integration testing and a focus on “vertical slice” testing than there used to be. For my part, I’d say that I use mock objects much more rarely now than I would have a decade ago.

Most of my coding efforts these days go into OSS projects, so a quick rundown:

  • Marten is mostly tested through integration tests all the way through to the underlying Postgresql database. I did a count today and only found about 5-6 test fixture classes that use NSubstitute for mocking or stubbing. This is mostly because I’m not confident enough in my knowledge of Postgresql JSON manipulation or the underlying Npgsql library mechanics to put much faith in intermediate tests that would just verify expected SQL strings or verifying the “correct” interaction with ADO.Net objects.
  • StructureMap is an old codebase, and you can see many different styles of testing throughout its history. At this point, there are very, very few unit tests (~20 out of about 1100) that use mock objects. With StructureMap, it’s generally very fast to set up full end to end scenarios for new features or bug fixes and that’s now what I prefer.

I’m not yet ready to say that mocking libraries are ready for the waste bin, but even I use them much more rarely now. Some of that may be that I’m in very different problem domains than I was a decade ago when we were still using the Model View Presenter architecture that made the usages of mocking more natural. What little client side work I do today is all in Javascript in the browser, and integration testing is much easier in that context than it ever was in WinForms or WPF and I don’t feel the need for mocks nearly as often.

State vs Interaction Testing

I spent a lot of time in my summers growing up helping my grandfather around the farm. Since there’s nothing in this world that breaks more often than farming implements (hay balers were the worst, but I remember the combine being pretty nasty too), I spent a lot of time using wrenches of all sorts. Ratchets when you could to be faster, closed ended wrenches if you had enough room to attach them, or open ended wrenches for tight spaces where you just couldn’t get to it otherwise. My point being that all those different tools for the same basic job were necessary to effectively get at all the bolts and nuts in all the crazy angles and tight spaces we ran into working on my grandfather’s equipment.

wrench-988762_960_720

Similar to my old choice of open or closed ended wrenches, when you’re writing automated tests, you’re measuring the expected outcome of the test in two ways:

  1. By measurable changes in the system state or a value returned from a function call. You might be verifying data written to the system database, or files being dropped, or content appearing on a screen. This is what’s known as state-based testing.
  2. By watching the messages sent between classes or subsystems. This style of testing is interaction-based testing.

Most developers are going to be more naturally comfortable with state-based testing and many developers will flat out refuse to use anything different. That being said, interaction testing is often the “open ended wrench” of test automation you have to use when it’s going to be much more work to verify some part of the system with state based checks.

A common objection I’ve seen in regards to mocking is “why would I ever care that a particular method was called?” I’m going to apply a little bit of sophistry here, because you don’t necessarily care that a method was called so much as “did it make the right decision” that happens to be determined.

Interaction testing is probably most effective when you’re purposely separating code that decides what actions to take next from actually taking that action — especially if your choice on verifying that action was taken is to either:

  1. Verify that a particular message was sent to initiate the action
  2. Check through the state of an external database, file, or email inbox to see if we can spot some kind of evidence that the desired action took place

My preference in this kind of case has always been to use mock objects to test that the decision to carry out the action takes place correctly, and then test that action completely independently.

Some examples of when I would still reach for interaction testing, often with a mock object:

  •  Routing type of logic like “send this box to this warehouse”
  • Deciding to carry out actions like
  • From one of our systems at work, whether or not we should mark an active call as “on hold” or in an “active” state.

To get more specific, and since this post was originally supposed to be specifically about how we should be testing with Marten, here’s some examples of operations that I think are or are not appropriate to mock:

[Fact]
public void good_usages()
{
    var session = Substitute.For<IDocumentSession>();

    // Were the changes to a session saved?
    session.Received().SaveChanges();

    // or not
    session.DidNotReceive().SaveChanges();

    // Was a new Issue document stored into the session?
    var issue = new Issue {};
    session.Received().Store(issue);
}

[Fact]
public void not_places_or_interfaces_you_should_mock()
{
    var session = Substitute.For<IDocumentSession>();

    User user = null;

    // No possible way you should stub this functionality
    // Go to a fullblown integration test
    var issue = session
        .Query<Issue>()
        .Include<User>(x => x.AssigneeId, x => user = x)
        .FirstOrDefault(x => x.Title.StartsWith("some problem"));
}


Mocks versus Stubs

A lot of people get genuinely upset about even trying to make a distinction  between mocks and stubs and some mocking tools even made it a point of pride to make absolutely no distinction between the two different things. Regardless of implementation, the important difference is strictly in the role of the testing “double” within the test.

  • “Stub” means that you are simply pre-canning the response to a request for data. You use stubs just to set up test inputs
  • “Mock” objects are used to verify the interactions with the object

To put that in context, here’s an example of stubbing and mocking using NSubstitute against Marten’s IDocumentSession interface:

[Fact]
public void stub_versus_mock()
{
    // Create a substitute IDocumentSession that could be used
    // as either a mock or stub
    var session = Substitute.For<IDocumentSession>();
    
    // Use session as a stub to return known data for
    // the given issue id
    var issueId = Guid.NewGuid();
    session.Load<Issue>(issueId).Returns(new Issue{});

    // Then inside the real code,
    var issue = session.Load<Issue>(issueId);

    // If the real code should be committing the current
    // Marten unit of work, we could verify that by seeing
    // if the SaveChanges() method was called.

    session.SaveChanges();

    // Using session as a mock object
    session.Received().SaveChanges();
}

I may be the last person left who thinks this, but I think it’s still valuable to be conscious of the different roles of mocks and stubs when you’re formulating a testing strategy. I also prefer that folks use the terminology correctly just for better communication. In reality though, most developers are so confused by the differences that most people have just thrown their hands up in the air and use the terms all interchangeably.

When are Stubs Desirable?

Automated tests are only effective when you can consistently create a known system state and inputs, then exercise the system to measure expected outputs. Quite often your system will have some architectural dependency on data provided by some kind of external system or subsystem that’s either impossible to control or just too much mechanical work to setup.

As I talked about last year in Succeeding with Automated Testing, I strongly believe in the effectiveness and efficiency of whitebox testing over insisting that only black box tests are valid. Following that philosophy, I’ll almost automatically prefer to use stubs in place of any external dependency that we can’t really control in the test data setup. Examples from our work include:

  • An identity service from a government entity that isn’t always available
  • A centralized database where we have no ability to set up on our own (using Docker might be an alternative here to start from a known state). Shared, centralized databases are hell in automated tests.
  • Authentication subsystems, especially Windows authentication
  • Active Directory access

 

Avoid Chatty Interfaces

Anytime you’re having to deal with a chatty interface that takes a lot of interactions to perform. Taking our Marten project as an example, it takes a lot of calls to manipulate the ADO.Net objects to do the simple work of resolving a document from a single row returned from an ADO.Net reader:

public virtual T Resolve(int startingIndex, DbDataReader reader, IIdentityMap map)
{
    if (reader.IsDBNull(startingIndex)) return null;

    var json = reader.GetString(startingIndex);
    var id = reader[startingIndex + 1];

    return map.Get <T> (id, json);
}

I could technically test the Resolve() method shown above by using mock objects in place of the IIdentityMap and the underlying database reader, but my tests would require several mocking expectations just to get both the reader and identity map to behave the way the test needs. A mocked test would certainly run faster than an end to end test, but in this case, only the end to end test would tell me with any confidence that the Resolve() method truly works as it should.

Avoid Mocking Interfaces You Don’t Understand

I used to say that you shouldn’t mock an interface that you don’t control, but the real danger is mocking any interface that you don’t entirely understand. I say this because it’s perfectly common to write a unit test using mock objects that passes, then turns out to fail when you run it in real life or within some kind of integration test. Maybe the best way of saying this is that it’s only appropriate to use mocking when the interaction being measured will definitely tell you something useful about how the code is going to behave.

 

Marten v0.9 is Out!

The Marten community made a big, big release today that marks a big milestone for Marten’s viability as a usable product. I just uploaded v0.9 to Nuget, and published all the outstanding documentation updates to our project website.

A lot of folks contributed to this release, and I’ll inevitably miss several names, so I’m just going to issue a huge thank you to everyone who put in pull requests or provided valuable feedback in our Gitter room or helped with the documentation updates. Marten is well on its way to being the most positive OSS experience I’ve ever had.

While you can see the full list of changes, fixes, and improvements in the GitHub milestone (81 issues!), the big highlights are:

  1. The Event Store feature is finally ready for very early adopters with some basic projection support. I discussed the vision for this functionality in a blog post yesterday. The very early feedback suggests that the existing API is in for some changes, but I’d still like to get more folks to look at what we have.
  2. Compiled Queries to avoid re-parsing Linq queries
  3. The Include() feature for more efficient data fetching
  4. Select() transformations inside of the Linq support
  5. Improved new ways to fetch the raw JSON for documents with the new AsJson() method.
  6. The ability to configure which schema Marten will use for document storage or the event store as part of the DocumentStore options. That was a frequent user request, and thanks to Tim Cools, we’ve got that now.
  7. Ability to express foreign key relationships between document types. Hey, Postgresql is a relational database, so why not take advantage of that when it’s valuable?
  8. More efficient asynchronous querying internals
  9. Linq support for aggregate functions like Average(), Min(), Max(), and Sum()

 

Next Steps

Other than the event store functionality that’s just getting off the ground, I think the pace of Marten development is about to slow down and be more about refinements than adding lots of new functionality. I’m hoping to switch to dribbling out incremental releases every couple weeks until we’re ready to declare 1.0.

 

Marten as an Event Store — Now and the Future Vision

The code shown in this post isn’t quite out on Nuget yet, but will be part of Marten v0.9 later this week when I catch up on documentation.

From the very beginning, we’ve always intended to use Marten and Postgresql’s JSONB support as the technical foundation for event sourcing persistence. The document database half of Marten has been a more urgent need for my company, but lately we have a couple project teams and several folks in our community interested in seeing the event store functionality proceed. Between a couple substantial pull requests and me finally getting some time to work on it, I think we finally have a simplistic event store implementation that’s ready for early adopters to pull it down and kick the tires on it.

Why a new Event Store?

NEventStore has been around for years, and we do use an older version on one of our big applications. It’s working, but I’m not a big fan of how it integrates into the rest of our architecture and it doesn’t provide any support for “readside projections.” Part of the rationale behind Marten’s event store design is the belief that we could eliminate a lot of our hand coded projection support in a big application.

There’s also GetEventStore as a standalone, language agnostic event store based on an HTTP protocol. While I like many elements of GetEventStore and am taking a lot of inspiration from that tool for Marten’s event store usage, we prefer to have our event sourcing based on the Postgresql database instead of a standalone store.

Why, you ask?

  • Since we’re already going to be using Postgresql, this leads to fewer things to deploy and monitor
  • We’ll be able to just use all the existing DevOps tools for Postgresql like replication and backups without having to bring in anything new
  • Building on a much larger community and a more proven technical foundation
  • Being able to do event capture, document database changes, and potentially just raw SQL commands inside of the same native database transaction. No application in our portfolio strictly uses event sourcing as the sole persistence mechanism, and I think this makes Marten’s event sourcing feature compelling.
  • The projection documents published by Marten’s event store functionality are just more document types and you’ll have the full power of Marten’s Linq querying, compiled querying, and batched querying to fetch the readside data from the event storage.

 

Getting Started with Simple Event Capture

Marten is just a .Net client library (4.6 at the moment), so all you need to get started is to have access to a Postgresql 9.4/9.5 database and to install Marten via Nuget.

Because I’ve read way too much epic fantasy series, my sample problem domain is an application that records, analyses, and visualizes the status of quests. During a quest,  you may want to record events like:

  • QuestStarted
  • MembersJoined
  • MembersDeparted
  • ArrivedAtLocation

With Marten, you would want to describe these events with simple, serializable DTO classes like this:

public class MembersJoined
{
    public MembersJoined()
    {
    }

    public MembersJoined(int day, string location, params string[] members)
    {
        Day = day;
        Location = location;
        Members = members;
    }

    public int Day { get; set; }

    public string Location { get; set; }

    public string[] Members { get; set; }

    public override string ToString()
    {
        return $"Members {Members.Join(", ")} joined at {Location} on Day {Day}";
    }
}

 

Now that we have some event classes identified and built, we can start to store a “stream” of events for a given quest as shown in this code below:

 

var store = DocumentStore.For("your connection string");

var questId = Guid.NewGuid();

using (var session = store.OpenSession())
{
    var started = new QuestStarted {Name = "Destroy the One Ring"};
    var joined1 = new MembersJoined(1, "Hobbiton", "Frodo", "Merry");

    // Start a brand new stream and commit the new events as 
    // part of a transaction
    session.Events.StartStream(questId, started, joined1);
    session.SaveChanges();

    // Append more events to the same stream
    var joined2 = new MembersJoined(3, "Buckland", "Merry", "Pippen");
    var joined3 = new MembersJoined(10, "Bree", "Aragorn");
    var arrived = new ArrivedAtLocation { Day = 15, Location = "Rivendell" };
    session.Events.Append(questId, joined2, joined3, arrived);
    session.SaveChanges();
}

Now, if we want to fetch back all of the events for our new quest, we can do that with:

using (var session = store.OpenSession())
{
    // events are an array of little IEvent objects
    // that contain both the actual event object captured
    // previously and metadata like the Id and stream version
    var events = session.Events.FetchStream(questId);
    events.Each(evt =>
    {
        Console.WriteLine($"{evt.Version}.) {evt.Data}");
    });
}

When I execute this code, this is the output that I get:

1.) Quest Destroy the One Ring started
2.) Members Frodo, Merry joined at Hobbiton on Day 1
3.) Members Merry, Pippen joined at Buckland on Day 3
4.) Members Aragorn joined at Bree on Day 10
5.) Arrived at Rivendell on Day 15

At this point, Marten is assigning a Guid id, timestamp, and version number to each event (but thanks to a recent pull request, you do not have to have an Id property or field on your event classes). I didn’t show it here, but you can also fetch all of the events for a stream by the version number or timestamp to perform historical state queries.

 

Projection Support

What I’m showing in this section is brand spanking new and isn’t out on Nuget yet, but will be as Marten v0.9 by the middle of this week (after I get the documentation updated).

So raw event streams might be useful to some of you, but we think that Marten will be most useful when you combine the raw event sourcing with “projections” that create parallel “readside” views of the event data suitable for consumption in the rest of your application for concerns like validation, business logic, or supplying data through HTTP services.

Let’s say that we need a view of our quest data just to see what the current member composition of our quest party is. In our event store usage, you would create an “aggregate” document class and teach Marten how to update that aggregate based on event data types. The easiest way to expose the aggregation right now is to expose public “Apply([event type])” methods like the QuestParty class shown below:

public class QuestParty
{
    private readonly IList _members = new List();

    public string[] Members
    {
        get
        {
            return _members.ToArray();
        }
        set
        {
            _members.Clear();
            _members.AddRange(value);
        }
    }

    public IList Slayed { get; } = new List();

    public void Apply(MembersJoined joined)
    {
        _members.Fill(joined.Members);
    }

    public void Apply(MembersDeparted departed)
    {
        _members.RemoveAll(x => departed.Members.Contains(x));
    }

    public void Apply(QuestStarted started)
    {
        Name = started.Name;
    }

    public string Name { get; set; }

    public Guid Id { get; set; }

    public override string ToString()
    {
        return $"Quest party '{Name}' is {Members.Join(", ")}";
    }
}

Without any further configuration, I could create a live aggregation of a given quest stream calculated on the fly by using this syntax:

using (var session = store.OpenSession())
{
    var party = session.Events.AggregateStream(questId);
    Console.WriteLine(party);
}

When I execute the code above for our new “Destroy the One Ring” stream of events, this is the output:

Quest party 'Destroy the One Ring' is Frodo, Merry, Pippen, Aragorn

Great, but since it’s potentially expensive to calculate the QuestParty from large streams of events, we may opt to have the aggregated view built in our Marten database ahead of time. Let’s say that we’re okay with just having the aggregate view updated every time a quest event stream is appended to. For that case, you can register a “live” aggregation in your DocumentStore initialization with this code:

var store2 = DocumentStore.For(_ =>
{
    _.Events.AggregateStreamsInlineWith<QuestParty>();
});

With the configuration above, the “QuestParty” view of a stream of related quest events is updated as part of the transaction that is persisting the new events being appended to the event log. If we were using this configuration, then we would be able to query Marten for the “QuestParty” as just another document type:

If your browser is cutting off the code formatting, the syntax is “session.Load<QuestParty>(questId)” down below:

using (var session = store.OpenSession())
{
    var party = session.Load<QuestParty>(questId);
    Console.WriteLine(party);

    // or
    var party2 = session.Query<QuestParty>()
        .Where(x => x.Name == "Destroy the One Ring")
        .FirstOrDefault();
}

Our Projections “Vision”

A couple years ago, I got to do what turned into a proof of concept project for building out an event store on top of Postgresql’s JSON support. My thought for Marten’s projection support is largely taken from this blog post I wrote on the earlier attempt at writing an event store on Postgresql.

Today the projection ability is very limited. So far you can use the live or “inline” aggregation of a single stream shown above or a simple pattern that allows you to create a single readside document for a given event type.

The end state we envision is to be able to allow users to:

  • Express projections in either .Net code or by using Javascript functions running inside of Postgresql itself
  • To execute the projection building either “inline” with event capture for pure ACID, asynchronously for complicated aggregations or better performance (and there comes eventual consistency back into our lives), or do aggregations “live” on demand. We think that this break down of projection timings will give users the ability to handle systems with many writes, but few reads with on demand projections, or to handle systems with few writes, but many reads with inline projections.
  • To provide and out of the box “async daemon” that you would host as a stateful process within your applications to continuously calculate projections in the background. We want to at least experiment with using Postgresql’s NOTIFY/LISTEN functionality to avoid making this a purely polling process.
  • Support hooks to perform your own form of event stream processing using the existing IDocumentSessionListener mechanism and maybe some way to plug more processors into the queue reading in the async daemon described above
  • Add some “snapshotting” functionality that allows you to perform aggregated views on top of occasional snapshots every X times an event is captured on an aggregate
  • Aggregate data across streams
  • Support arbitrary categorization of events across streams

 

 

Anything I didn’t cover that you’re wondering about — or just want to give us some “constructive feedback” — please feel free to pop into Marten’s Gitter room since we’re talking about this today anyway;)

How we did authorization in FubuMVC, and what I’d do differently today

FubuMVC as an OSS project is still mostly dead, but we still use it very heavily at work and one of our teams asked me to explain how the authorization works. You’re probably never going to use FubuMVC, but we did some things that were interesting and successful from a technical perspective. Besides, it’s always more fun to learn from other people’s mistakes — in this case, my mistakes;)

Early in the project that originally spawned FubuMVC we spent almost two months tackling authorization rules in our application. We had a couple needs:

  1. Basic authorization to allow or deny user actions based on their roles and permissions
  2. Authorization rules based on the current business object state (rules like “an amount > 5,000 requires manager approval”).
  3. The ability to extend the authorization of the application with custom rules and exceptions for a customer without any impact on the core code
  4. Use authorization rules to enable, disable, show, or hide navigation elements in the user interface

The core architectural concept of FubuMVC was what we called the “Russian Doll Model” that allowed you to effectively move cross cutting into our version of middleware. Authorization was an obvious place to use a wrapping middleware class around endpoint actions. If a user has the proper rights, continue on. If the user does not, return an HTTP 403 and some kind of authorization failure response and don’t execute the inner action at all.

For some context, you can see the part of our AuthorizationBehavior class we used to enforce authorization rules:

protected override void invoke(Action action)
{
    if (!_settings.AuthorizationEnabled)
    {
        action();
        return;
    }

    var access = _authorization.IsAuthorized(_context);

    // If authorized, continue to the inner behavior in the 
    // chain (filters, controller actions, views, etc.)
    if (access == AuthorizationRight.Allow)
    {
        action();
    }
    else
    {
        // If authorization fails, hand off to the failure handler
        // and stop the inner behaviors from executing
        // the failure handler service was pluggable in fubu too
        var continuation = _failureHandler.Handle();
        _context.Service<IContinuationProcessor>().Continue(continuation, Inner); 
    }
}

Pulling the authorization checks into a separate middleware independent of the inner HTTP action had a couple advantages:

  • It’s easier to share common authorization logic
  • Reversibility — meaning that it was easy to retrofit authorization logic onto existing code without having to dig into the actual endpoint action code.
  • The inner endpoint action code could be simpler by not having to worry about authorization (in most cases)

FubuMVC itself might have failed, but the strategy of using composable middleware chains is absolutely succeeding as you find it in almost all of the newer HTTP frameworks and service bus frameworks including the new ASP.Net Core MVC code.

Authorization Rights and Policies

The core abstraction in FubuMVC’s authorization  subsystem was the IAuthorizationPolicy interface that could be executed to determine if a user had rights to the current action:

    public interface IAuthorizationPolicy
    {
        AuthorizationRight RightsFor(IFubuRequestContext request);
    }

The “AuthorizationRight” class above was a strong typed enumeration consisting of:

  1. “None” — meaning that the policy just didn’t apply
  2. “Allow”
  3. “Deny”

If multiple rules applied to a given endpoint, each rule would be executed to determine if the user had rights. Any rule evaluating to “Deny” automatically failed the authorization check. Otherwise, at least one rule had to be evaluated as “Allow” to proceed.

Being able to combine these checks enabled us to model both the simple, role and permission-based authorization, and also rules based on business logic and the current system state.

Simple Role Based Authorization

In the following example, we have an endpoint action that has a single “AllowRole” authorization rule:

        // This action would have the Url: /authorized/hello
        [AllowRole("Greeter")]
        public string get_authorized_hello()
        {
            return "Hello.";
        }

Behind the scenes, that [AllowRole] attribute is evaluated once at application startup time and adds a new AllowRole object to the underlying model for the “GET /authorized/hello” endpoint.

For some context, the AllowRole rule (partially elided) looks like this:

    public class AllowRole : IAuthorizationPolicy
    {
        private readonly string _role;

        public AllowRole(string role)
        {
            _role = role;
        }

        public AuthorizationRight RightsFor(IFubuRequestContext request)
        {
            return PrincipalRoles.IsInRole(_role) ? AuthorizationRight.Allow : AuthorizationRight.None;
        }

    }

 

Model Based Configuration

FubuMVC has an underlying model called the “behavior graph” that models exactly which middleware handlers are applicable to each HTTP route. Part of that model is an exact linkage to the authorization policies that were applicable to each route. In the case above, the “GET /authorized/hello” endpoint has a single AllowRole rule added by the attribute.

More powerfully though, FubuMVC also allowed you to reach into the underlying behavior graph model and add additional authorization rules for a given endpoint. You could do this through the marker attributes (even your own attributes if you wanted), programmatically if you had to, or through additive conventions like “all endpoints with a route starting with /admin require the administrator role.” We heavily exploited this ability to enable customer-specific authorization checks in the original FubuMVC application.

Authorization & Navigation

By attaching the IAuthorizationPolicy objects to each behavior chain, FubuMVC is also able to tell you programmatically if a user could navigate to or access any HTTP endpoint using the IEndpointService like this:

            IEndpointService endpoints = runtime
                .Get<EndpointService>();             

            var endpoint = endpoints
                 .EndpointFor<SomeEndpoint>(x => x.get_hello());

            var isAuthorized = endpoint.IsAuthorized;

We used the IEndpointService (and a simpler one not shown here called IAuthorizationPreviewService) in server side rendering to know when to show, hide, enable, or disable navigation elements based on whether or not a user would have rights to access those routes. By decoupling the authorization rules a little bit from the actual endpoint action code, we were able to define the authorization rules exactly once for every endpoint, then reuse the same logic in navigation accessibility that we did at runtime when the actual resource was requested.

This ability to “preview” authorization rights for HTTP endpoints was also useful for hypermedia endpoints where you used authorization rights to include or exclude additional links in the response body.

Lastly, having the model of what authorization rules applied to each route enabled FubuMVC to be able to present diagnostic information and visualizations of the middleware configuration for each HTTP endpoint. That kind of diagnostics becomes very important when you start using conventional policies or extensibility mechanism to insert authorization rules from outside of the core application.

Rule Object Lifecycle

FubuMVC, especially in its earlier versions, is awful for the number of object allocations it makes at runtime. Starting with FubuMVC 2, I tried to reduce that overhead by making the authorization rule objects live through the lifecycle of the application itself instead of being created fresh by the underlying IoC container on every single request. Great, but there are some services that you may need to access to perform authorization checks — and those services sometimes need to be scoped to the current HTTP request. To get around that, FubuMVC’s IAuthorizationPolicy takes in an IFubuRequestContext object which among other information contains a *gasp* service locator for the current request scope that authorization rules can use to perform their logic.

There’s been an almost extreme backlash against any and all usages of service locators over the past several years. Most of that is probably very justified, but in my opinion, it’s still very valid to use a service locator within an object that has a much longer lifetime than the dependencies it needs to use within certain operations. And no, using Lazy<T> or Func<T> builders injected in at the original time of creation will not work without making a potentially harmful dependency on things like the HttpContext for the scoping to work.

Please don’t dare commenting on this post with any form of “but Mark Seemann says…” I swear that I’ll reach through the interwebs and smack you silly if you do. Probably make a point of never, ever doing that on any kind of StructureMap list too for that matter.

What I’d do differently if there’s a next time

For the past couple years we’ve kicked around the idea of an all new framework we’re going to call “Jasper” that would be essentially a reboot of a core subset of FubuMVC on the new CoreCLR and all the forthcoming ASP.Net Core goodies. At some point I’ve said that I wanted to bring over the authorization model from FubuMVC roughly as is, but the first step is to figure out if we could use something off the shelf so we don’t have to support our own custom infrastructure (and there’s always the possibility that we’ll just give up and go to the mainstream tools).

The single biggest thing I’d change the next time around is to make it far easier to do one-off authorization rules as close as possible to the actual endpoint action methods. My thought has been to have something like a convention or yet another interface something like “IAuthorized” so that endpoint classes could happily expose some kind of Authorize() : AuthorizationRight method for one off rules.

Honestly though, I’m content with how the authorization model played out in FubuMVC. A big part of the theoretical plans for “Jasper” is be much, much more conscious about allocating new objects (i.e., use the IoC container much less) and adopting an async by default, all the way through approach to the runtime model.

The compiled query feature in Marten and why it rocks.

The “compiled query” feature is a brand new addition to Marten (as of v0.8.9), and one we think will have some very positive impact on the performance of our systems. I’m also hopeful that using this feature will make some of our internal code easier to read and understand. Down the line, the combination of compiled queries with the batch querying support should be the foundation of a decent dynamic, aggregated query mechanism to support our React/Redux based client architectures (with a server side implementation of Falcor maybe?). Big thanks and a shoutout to Corey Kaylor for adding this feature.

Linq is easily one of the most popular features in .Net and arguably the one thing that other platforms strive to copy. We generally like being able to express document queries in compiler-safe manner, but there is a non-trivial cost in parsing the resulting Expression trees and then using plenty of string concatenation to build up the matching SQL query. Fortunately, as of v0.8.10, Marten supports the concept of a Compiled Query that you can use to reuse the SQL template for a given Linq query and bypass the performance cost of continuously parsing Linq expressions.

All compiled queries are classes that implement the ICompiledQuery<TDoc, TResult> interface shown below:

    public interface ICompiledQuery<TDoc, TOut>
    {
        Expression<Func<IQueryable<TDoc>, TOut>> QueryIs();
    }

In its simplest usage, let’s say that we want to find the first user document with a certain first name. That class would look like this:

public class FindByFirstName : ICompiledQuery<User, User>
{
    public string FirstName { get; set; }

    public Expression<Func<IQueryable<User>, User>> QueryIs()
    {
        return q => q.FirstOrDefault(x => x.FirstName == FirstName);
    }
}

So a couple things to note in the class above:

  1. The QueryIs() method returns an Expression representing a Linq query
  2. FindByFirstName has a property (it could also be just a public field) called FirstName that is used to express the filter of the query

To use the FindByFirstName query, just use the code below:

            var justin = theSession.Query(new FindByFirstName {FirstName = "Justin"});

            var tamba = await theSession.QueryAsync(new FindByFirstName {FirstName = "Tamba"});

Or to use it as part of a batched query, this syntax:

var batch = theSession.CreateBatchQuery();

var justin = batch.Query(new FindByFirstName {FirstName = "Justin"});
var tamba = batch.Query(new FindByFirstName {FirstName = "Tamba"});

await batch.Execute();

(await justin).Id.ShouldBe(user1.Id);
(await tamba).Id.ShouldBe(user2.Id);

How does it work?

The first time that Marten encounters a new type of ICompiledQuery, it executes the QueryIs() method and:

  1. Parses the Expression just to find which property getters or fields are used within the expression as input parameters
  2. Parses the Expression with our standard Linq support and to create a template database command and the internal query handler
  3. Builds up an object with compiled Func’s that “knows” how to read a query model object and set the command parameters for the query
  4. Caches the resulting “plan” for how to execute a compiled query

On subsequent usages, Marten will just reuse the existing SQL command and remembered handlers to execute the query.

What is supported?

To the best of our knowledge and testing, you may use any Linq feature that Marten supports within a compiled query. So any combination of:

  • Select() transforms
  • First/FirstOrDefault()
  • Single/SingleOrDefault()
  • Where()
  • OrderBy/OrderByDescending etc.
  • Count()
  • Any()

At this point (v0.9), the only limitations are:

  1. You cannot yet incorporate the Include’s feature with compiled queries, but there is an open GitHub issue you can use to track progress on adding this feature.
  2. You cannot use the Linq ToArray() or ToList() operators. See the next section for an explanation of how to query for multiple results

Querying for multiple results

To query for multiple results, you need to just return the raw IQueryable<T> as IEnumerable<T> as the result type. You cannot use the ToArray() or ToList() operators (it’ll throw exceptions from the Relinq library if you try). As a convenience mechanism, Marten supplies these helper interfaces:

If you are selecting the whole document without any kind of Select() transform, you can use this interface:

    public interface ICompiledListQuery<TDoc> : ICompiledListQuery<TDoc, TDoc>
    {
    }

A sample usage of this type of query is shown below:

    public class UsersByFirstName : ICompiledListQuery<User>
    {
        public static int Count;
        public string FirstName { get; set; }

        public Expression<Func<IQueryable<User>, IEnumerable<User>>> QueryIs()
        {
            // Ignore this line, it's from a unit test;)
            Count++;
            return query => query.Where(x => x.FirstName == FirstName);
        }
    }

If you do want to use a Select() transform, use this interface:

    public interface ICompiledListQuery<TDoc, TOut> : ICompiledQuery<TDoc, IEnumerable<TOut>>
    {
    }

A sample usage of this type of query is shown below:

    public class UserNamesForFirstName : ICompiledListQuery<User, string>
    {
        public Expression<Func<IQueryable<User>, IEnumerable<string>>> QueryIs()
        {
            return q => q
                .Where(x => x.FirstName == FirstName)
                .Select(x => x.UserName);
        }

        public string FirstName { get; set; }
    }

Querying for a single document

Finally, if you are querying for a single document with no transformation, you can use this interface as a convenience:

    public interface ICompiledQuery<TDoc> : ICompiledQuery<TDoc, TDoc>
    {
    }

And an example:

    public class FindUserByAllTheThings : ICompiledQuery<User>
    {
        public string Username { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Expression<Func<IQueryable<User>, User>> QueryIs()
        {
            return query =>
                    query.Where(x => x.FirstName == FirstName && Username == x.UserName)
                        .Where(x => x.LastName == LastName)
                        .Single();

        }
    }

 

 

 

 

A quick followup to my opinions on .Net OSS

After one last puff piece to blow up my blogging numbers, I will do penance by sticking to actual technical content for awhile.

So the other day I made a somewhat conscious decision to get more blog traffic and posted something I’d been dwelling on for a while:  What I think is and is not better about .Net OSS these days. A couple follow up points from the feedback I’ve gotten:

Do most .Net developers care?

I honestly don’t know. I’d guess the answer is “no,” but I’m firmly convinced that there is no such thing as a  “typical” .Net software shop anyway. I do know that when folks say that “most development shops do this,” it’s frequently something that I’ve never experienced.

Why does OSS even matter to .Net?

There’s a lot of smart folks in the .Net community that don’t work in Redmond, and OSS is a great way to capture and cultivate innovation in .Net from more people. Having a greater diversity of tools that take different approaches to solving technical problems is always nice.

Other communities have problems too!

Well, duh.

Someone pointed out that Javascript suffers from a lot of duplication too. The Node.js/NPM/Javascript world is churning fast, and some duplication of effort kind of has to be expected as a result.

Why don’t I leave .Net and go to <insert other platform here>?

.Net has been very good to me, and I probably get to do much more interesting work than the average developer on any platform. I’m one of the very few people who actually likes their job, and .Net happens to be a part of most of our systems.

Besides, I get to do enough Javascript development that I don’t particularly feel trapped into only working on .Net anyway.

Please stop using the word “Zealot”

Despite a comment or two to the contrary, I am certainly not a Richard Stallman-style OSS “zealot.” That’s one of the words that developers use very sloppily in technical arguments. I’m just gonna stick a link to my old post about why I hate the word “Zealot” or “Pragmatic” or “Dogma” tossed around in technical discussions.

About Microsoft, one last time

I don’t actually believe that Microsoft works directly against OSS efforts in .Net. I think the biggest issues simply arise from how utterly dominant of a mindshare that Microsoft has within the .Net community, and that’s the main thing that’s really different about .Net versus other communities.

Even with the lack of attention and publicity issues aside, I think that overall, the .Net community is probably more conservative about adopting new ideas or tools than other communities. I think that also explains why many software development concepts aren’t widely adopted by .Net developers until it’s been promoted, supported, or endorsed by Microsoft themselves.

But Microsoft themselves use Newtonsoft!

So? Everything does, and that’s why Newtonsoft binding conflicts were such an awful mess a couple years ago. I’d guess that any considerably sized .Net system has at least 3-4 privately merged copies of Newtonsoft.Json somewhere.

I’m just bitter

“You’re just bitter about FubuMVC” – I’m somewhat guilty on that score (human nature and all), but my main point was just to say that it’s highly unlikely you can succeed with an OSS tool that directly competes with an established MS offering. There were a whole raft of things I did wrong with fubu, but competing directly against ASP.Net MVC probably put our ceiling as a successful OSS project pretty low right out of the gate.

I’ll have to admit that it irritates me when I see folks all excited about something new in ASP.Net MVC Core that is very similar to something we had in FubuMVC years previously. A healthier way to look at it is that sometimes it has been nice to see our design ideas validated by similar designs in the real MS .Net tools.

What I think is and is not better about .Net OSS these days

I meant to write this a couple months ago after I made a sarcastic remark about how saying “I take pull requests” was a fast way to end a conversation with .Net developers. That got retweeted quite a bit, but honestly, my experiences doing OSS work in .Net have gotten so very much more positive in the last couple years and this post might be warranted.

There’s a never ending stream of consternation and angst about the state of OSS development inside of the .Net community — and yes, I’ve been a part of that from time to time. One common perception is that OSS is not as vibrant in .Net as it is in many other technology stacks. Another complaint that I see frequently (and make) is that there sometimes seem like there’s a lot of “not invented here” type duplication between OSS projects in .Net.

A lot of that is probably true, and I think unlikely to ever completely change, but working on .Net OSS projects now is definitely far better than it was just a few years ago.

A quick rundown of my experiences and involvement for some context:

  • StructureMap has been around since 2004, and probably been widely used since about 2007/8. For whatever reasons, StructureMap has actually enjoyed a pretty significant uptick in contributions and development over the past couple years.
  • Marten is about six months old, but it’s already the busiest OSS community I’ve been a part of
  • Storyteller doesn’t have a lot of usage yet, but the early feedback has been encouraging
  • FubuMVC was a great learning experience and directly responsible for my current position and several personal relationships with other developers, but was a otherwise a massive failure as an OSS project and a tremendous opportunity cost for me

What I think is definitely better now

The most important difference in being an OSS author now as opposed to even just a few years ago is how much more pleasant my interactions are with users. In the past, it was all too common to deal with endless belligerence and an annoying sense of entitlement from users who were probably much more used to leaning on official support lines and documentation from software vendors. I still get a little bit of that once in awhile, but lately I’m seeing a lot more of:

  • Users acting as collaborators with me to solve their issues
  • Getting much clearer reproduction steps for their problems, often including failing unit tests to demonstrate their issues
  • Patience and pleasantness from users needing help
  • A willingness to take on pull request work to fix their issues and contribute back to the project
  • An obvious sense that the project is a community effort
  • Users helping each other in our Gitter rooms before I have a chance to respond

I think that GitHub and its like have definitely made OSS development a much more positive experience. I’d even say that Microsoft’s recent adoption and de facto endorsement of GitHub have definitely made git and GitHub skills much more common throughout the .Net community — and that in turn has made it much more common for users to be able to contribute back to OSS projects.

At least for Marten, we’ve been able to attract quite a bit of early interest and several active contributors and early adopters. It’s easily been the most positive OSS experience I’ve ever had.

I think it’s helped a bit that more .Net developers are comfortable and familiar with automated build and testing tools. I rarely see pull requests submitted without tests anymore, but that would have been a common occurrence a few years ago.

What’s still not great about .Net OSS

  • A large number of shops will simply not adopt anything that isn’t an official tool from Microsoft
  • I think that Microsoft still stomps all over the existing OSS projects in .Net by building direct competitors or not taking any cognizance of existing tools when they plan .Net framework changes. I should say that I don’t think this is purposeful, but I’ve never gotten the sense that the teams in Redmond have much awareness or visibility into the .Net OSS ecosystem
  • The unusual status of the .Net community being so centered on Microsoft and the tools that they provide out of the box just doesn’t leave enough Oxygen for community OSS projects
  • I think that the forthcoming CoreCLR / DNX / New Name? tooling is probably going to make a lot of the existing OSS projects go extinct. The runtime is very different in some aspects (it wasn’t that bad to move StructureMap up to the CoreCLR, but Storyteller will be much more work and Marten cannot work yet on the DNX runtime as we wait on Roslyn work). Even on top of waiting for your dependencies to support CoreCLR, I think that there won’t be enough interest or activity to bring a lot of tools forward. .Net OSS might be a lot better in the long term as .Net simply becomes a better platform for development
  • I think that ASP.Net Core and related efforts are going to take most of the .Net community’s attention for quite awhile
  • It’s still hard to get visibility for .Net OSS projects and that in turn makes it unlikely that a community coalesces around any one project. This is my working theory for why there are so many duplicated projects in .Net
  • There aren’t many venues, groups, or conferences dedicated to OSS efforts in .Net. Most .Net technical conferences tend to skew heavily toward Microsoft offerings
  • I think the MVP program skews the community toward official Microsoft tools and away from OSS projects

 

What about Microsoft being so much more involved in OSS themselves?

I honestly don’t know. It’s making much more developers aware of OSS in general, but I don’t know that it will really encourage folks to be more involved in community projects.

In Summary

My advice is yes, definitely get involved in .Net OSS projects or start your own if you enjoy doing that kind of work, you want to expand your technical skills, or want to make yourself more marketable. If you are making a big bet on the success of that project or have high hopes for it to be widely adopted, I think I’d advise you to set your sights much lower. You also have to realize that it’s very difficult for .Net OSS projects to gain visibility and widespread adoption.

I’d also discourage anyone from trying to compete directly with any tool from Microsoft itself. It can be done, but that’s an uphill slog. It’s probably a lot easier to either find niches where Microsoft tooling has not real entry, or focus on projects that try to add value to mainstream Microsoft .Net tooling. Then hope that Microsoft doesn’t start building their own version of your tool and send one of their celebrity programmers to conferences to sell it;)