Reinventing the System.Web.Optimization wheel with gulp

For a long time, I was using the standard bundling and minification System.Web.Optimization framework to deliver bundled and minified JavaScript and CSS to users of our app. In one of Azure's more frustrating changes, the 'In Role' cache was removed from the Cloud Service offering. The only cache choice now is Redis. Which is great, but it caused us some infrequent problems with bundles getting "stuck". We'd have to run a console application to clear out all of the bundle information in Redis whenever that happened.

We had need for a better front end build anyway as we started to explore replacements for angular (e.g. Aurelia) so decided to add bespoke bundling and minification. The actual implementation is more complex than what I'll show here because the code runs 2 'brands' (sites), each in 3 different countries. Let's assume the code runs one brand in one deployment instead!

Config The bundles are configured in a file called "bundles.…

Composing Expressions in C#

This post follows on from Reusing predicates in Entity Framework.

In my previous post I introduced the "and" extension method which allowed me to create a new entity framework safe expression from two existing expressions. Here's how we make that happen:

The code is from a blogpost from Colin Meek from 2008: InvocationExpression and LINQ to Entities.

I'll just dump my version of the code here. The idea is exactly the same (even using the visitor as an immutable stack):

publicclass InvocationExpander : ExpressionVisitor { privatereadonly ParameterExpression _parameter; privatereadonly Expression _expansion; privatereadonly InvocationExpander _previous; publicstatic T Expand<T>(T expr) where T : LambdaExpression { return (T)new InvocationExpander().Visit(expr); } public InvocationExpander() { } private InvocationExpander(ParameterExpression parameter, Expression expansion, InvocationExpander previous) { …

Reusing predicates in EntityFramework

Warning: some knowledge of Expressions is required.

Entity Framework simplifies a great number of things; for starters, I don't have to write a lot of SQL which makes development a lot faster - I'm a lot more productive in C# than SQL. One thing that works really well in EF, is the ability to reuse predicates - how often do you find yourself typing:
posts.Where(p => !p.IsDeleted); In progamming we often get taught to DRY out the code - i.e. Don't Repeat Yourself. I think that extends to the expressions we're pass in to EF. The expressions are the specification language of EF (ignore that part if you don't do DDD). I'll look at a couple of ways of storing that expression - first up: extension methods.
Set up Let's a assume we have a blog post entity like: publicclassBlogPost { publicint Id { get; set; } publicstring Title { get; set; } publicstring Body { get; set; } publicstring AuthorName { get; set; } publicbool IsPublished { get; set…

Passing the current ClaimsIdentity to the regenerateIdentity callback

I wanted to persist some extra claims that weren't driven directly from the database. That was all well and good until the user identity was refreshed and the extra claims were lost.

The template code for Startup.cs looks like this:

app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { // Enables the application to validate the security stamp when the user logs in.// This is a security feature which is used when you change a password or add an external login to your account. OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) } });
It turns out that getting t…

A coder's new year's resolution

When I write and review code I'm always looking to have one thing happen per line. I've mostly favoured this because of how much more readable it makes the code e.g. see this review

However, I refactored some code and introduced a massive bug (caught by tests!) because I missed a side effect... The real code was a lot longer (100+ LoC method - hence the refactor). It was something of this form though:

var i = 0; var maxAttempts = 5; while (true) { var workRequest = someQueue.GetWork(); var workResult = someService.Execute(workRequest); if (!workResult.IsSuccess) { Log("{0}, {1}, {2}", workRequest.Name, i++, workResult.ErrorsDisplay); } if (i > maxAttempts) { thrownew DomainException("Some details!"); } }
When I refactored the code I changed the line that incremented the i variable and lost the side effect! It's a really important bit of inform…

Interest payments on technical debt

All of our decisions when creating software have pros and cons. Solution A might solve the problem well but lack flexibility. Solution B might have loads of flexibility and solve the problem just as well but be difficult to understand. A third solution, C, might be flexible and intuitive but involve a large upfront cost.

I remember when I first started developing software, I'd be presented with a problem and then I'd work at it until I solved it and then move on. It was certainly a simpler time! The issue now is that I see so many different ways of solving a problem it can be almost impossible to choose which one to go with.

There are several common themes I think about when evaluating the options:

However, aside from the technical considerations there's also the business concerns:

DeadlineSeverityBudget It's these concerns which generally lead to technical debt. It's a great metaphor. Just as financial debt has positives and negative…

Full text search in Entity Framework 6 using command interception

Background One of the main problems we encountered using Entity Framework was its lack of support for full text search. Our search function is based around a series of processors that attempt to match the incoming phrase against a set of patterns that we're expecting (10+). For example, there's one for dates and times, recent financial quarters as well as more domain specific ones. Everything is cached and so is really fast, except when it isn't:

Here's the monitoring chart for our SQL DB in Azure
That's a spike to 100% resource utilisation because we fall through to a phrase search as a last resort (which cannot be cached) - it's exceedingly rare but it still hurts.

Before EF, the app used full text search and it was one of the casualties when the app was migrated to EF4 several years ago. The lack of full text search has been getting more and more painful as the amount of data has grown. We really needed full text search back...

Command interception Entity F…