Project description

CarTrackr is a sample application for the ASP.NET MVC framework using the repository pattern and dependency injection using the Unity application block. It was written for various demos in presentations done by Maarten Balliauw.

CarTrackr is an online software application designed to help you understand and track your fuel usage and kilometers driven.

You will have a record on when you filled up on fuel, how many kilometers you got in a given tank, how much you spent and how much liters of fuel you are using per 100 kilometer.

CarTrackr will enable you to improve your fuel economy and save money as well as conserve fuel. Fuel economy and conservation is becoming an important way to control your finances with the current high price.

Source code

Latest version: CarTrackr (ASP.NET MVC 1.0 version)

Author blog feed

 Maarten Balliauw {blog} News Feed 
Friday, May 8, 2015  |  From Maarten Balliauw {blog}

Pretty sweet: MyGet just announced Vsix support has been enabled for all MyGet customers! I wanted to work on a fun example for this new feature and came up with this: how can we use MyGet to build and distribute a Roslyn analyzer and code fix? Let’s see.

Developing a Roslyn analyzer and code fix

Roslyn analyzers and code fixes allow development teams and individuals to enforce certain rules within a code base. Using code fixes, it’s also possible to provide automated “fixes” for issues found in code. When writing code that utilizes DateTime, it’s often best to use DateTime.UtcNow instead of DateTime.Now. The first uses UTC timezone, while the latter uses the local time zone of the computer the code runs on, often introducing nasty time-related bugs. Let’s write an analyzer that detects usage of DateTime.Now!

You will need Visual Studio 2015 RC and the Visual Studio 2015 RC SDK installed. You’ll also need the SDK Templates VSIX package to get the Visual Studio project templates. Once you have those, we can create a new Analyzer with Code Fix.

image_thumb[2]

A solution with 3 projects will be created: the analyzer and code fix, unit tests and a Vsix project. Let’s start with the first: detecting DateTime.Now in code an showing a diagnostic for it. It’s actually quite easy to do: we tell Roslyn we want to analyze IdentifierName nodes and it will pass them to our code. We can then see if the identifier is “Now” and the parent node is “DateTime”. If that’s the case, return a diagnostic:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeIdentifierName, SyntaxKind.IdentifierName);
}

private void AnalyzeIdentifierName(SyntaxNodeAnalysisContext context)
{
var identifierName
= context.Node as IdentifierNameSyntax;
if (identifierName != null)
{
// Find usages of "DateTime.Now"
if (identifierName.Identifier.ValueText == "Now"
&& ((IdentifierNameSyntax)((MemberAccessExpressionSyntax)identifierName.Parent).Expression).Identifier.ValueText == "DateTime")
{
// Produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, identifierName.Identifier.GetLocation(), identifierName);

context.ReportDiagnostic(diagnostic);
}
}
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

If we compile our solution and add the generated NuGet package to another project, DateTime.Now code will be flagged. But let’s implement the code fix first as well. We want to provide a code fix for the syntax node we just detected. And when we invoke it, we want to replace the “Now” node with “UtcNow”. A bit of Roslyn syntax tree fiddling:


<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root
= await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

var diagnostic
= context.Diagnostics.First();
var diagnosticSpan
= diagnostic.Location.SourceSpan;

// Find "Now"
var identifierNode = root.FindNode(diagnosticSpan);

// Register a code action that will invoke the fix.
context.RegisterCodeFix(
CodeAction.Create(
"Replace with DateTime.UtcNow", c => ReplaceWithDateTimeUtcNow(context.Document, identifierNode, c)),
diagnostic);
}

private async Task<Document> ReplaceWithDateTimeUtcNow(Document document, SyntaxNode identifierNode, CancellationToken cancellationToken)
{
var root
= await document.GetSyntaxRootAsync(cancellationToken);
var newRoot
= root.ReplaceNode(identifierNode, SyntaxFactory.IdentifierName("UtcNow"));
return document.WithSyntaxRoot(newRoot);
}
<!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

That’s it. We now have an analyzer and a code fix. If we try it (again, by adding the generated NuGet package to another project), we can see both in action:


image_thumb[6]


Now let’s distribute it to our team!

Distributing a Roslyn analyzer and code fix using MyGet




Roslyn analyzers can be distributed in two formats: as NuGet packages, so they can be enabled for individual project, and as a Visual Studio extension so that all projects we work with have the analyzer and code fix enabled. You can build on a developer machine, a CI server or using MyGet Build Services. Let’s pick the latter as it’s the easiest way to achieve our goal: compile and distribute.


Create a new feed on www.myget.org. Next, from the Build Services tab, we can add a GitHub repository as the source. We’ve open-sourced our example at https://github.com/myget/sample-roslyn-with-vsix so feel free to add it to your feed as a test. Once added, you can start a build. Just like that. MyGet will figure out it’s a Roslyn analyzer and build both the NuGet package as well as the Visual Studio extension.


image_thumb[9]


Sweet! You can now add the Roslyn analyzer and code fix per-project, by installing the NuGet package from the feed (https://www.myget.org/F/datetime-analyzer/api/v2). ANd when registering it in Visual Studio (https://www.myget.org/F/datetime-analyzer/vsix/) by opening the Tools | Options... menu and the Environment | Extensions and Updates pane, you can also install the full extension.


image_thumb[12]

Tuesday, February 17, 2015  |  From Maarten Balliauw {blog}

So you’re building a multi-tenant application. And just like many multi-tenant applications out there, the application will use a single (sub)domain per tenant and the application will use that to select the correct database connection, render the correct stylesheet and so on. Great! But how to do this with ASP.NET MVC 6?


A few years back, I wrote about ASP.NET MVC Domain Routing. It seems that post was more popular than I thought, as people have been asking me how to do this with the new ASP.NET MVC 6. In this blog post, I’ll do exactly that, as well as provide an alternative way of resolving the current tenant based on the current request URL.


Disclaimer: ASP.NET MVC 6 still evolves, and a big chance exists that this blog post is outdated when you are reading it. I’ve used the following dependencies to develop this against:



You’re on your own if you are using other dependencies.


Domain routing – what do we want to do?

The premise for domain routing is simple. Ideally, we want to be able to register a route like this:



The route would match any request that uses a hostname similar to *.localtest.me, where "*" is recognized as the current tenant and provided to controllers a a route value. And of course we can define the path route template as well, so we can recognize which controller and action to route into.


Domain routing – let’s do it!

Just like in my old post on ASP.NET MVC Domain Routing, we will be using the existing magic of ASP.NET routing and extend it a bit with what we need. In ASP.NET MVC 6, this means we’ll be creating a new IRouter implementation that encapsulates a TemplateRoute. Let’s call ours DomainTemplateRoute.


The DomainTemplateRoute has a similar constructor to MVC’s TemplateRoute, with one exception which is that we also want a domainTemplate parameter in which we can define the template that the host name should match. We will create a new TemplateRoute that’s held in a private field, so we can easily match the request path against that if the domain matches. This means we only need some logic to match the incoming domain, something which we need a TemplateMatcher for. This guy will parse {tenant}.localtest.me into a dictionary that contains the actual value of the tenant placeholder. Not deal, as the TemplateMatcher usually does its thing on a path, but since it treats a dot (.) as a separator we should be good there.


Having that infrastructure in place, we will need to build out the Task RouteAsync(RouteContext context) method that handles the routing. Simplified, it would look like this:



We match the hostname against our domain emplate. If it does not match, then the route does not match. If it does match, we call the inner TemplateRoute’s RouteAsync method and let that one handle the path template matching, constraints processing and so on. Lazy, but convenient!


We’re not there yet. We also want to be able to build URLs using the various HtmlHelpers that are around. If we pass it route data that is only needed for the domain part of the route, we want to strip it off the virtual path context so we don’t end up with URLs like /Home/About?tenant=tenant1 but instead with a normal /Home/About. Here’s a gist:



Fitting it all together, here’s the full DomainTemplateRoute class: https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroute-cs – The helpers for registering these routes are at https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroutebuilderextensions-cs


But there’s another approach!

One might say the only reason we would want domain routing is to know the current tenant in a multi-tenant application. This will often be the case, and there’s probably a more convenient method of doing this: by building a middleware. Ideally in our application startup, we want to add app.UseTenantResolver(); and that should ensure we always know the desired tenant for the current request. Let’s do this!


OWIN learned us that we can simply create our own request pipeline and decide which steps the current request is routed through. So if we create such step, a middleware, that sets the current tenant on the current request context, we’re good. And that’s exactly what this middleware does:



We check the current request, based on the request or one of its properties we create a Tenant instance and a TenantFeature instance and set it as a feature on the current HttpContext. And in our controllers we can now get the tenant by using that feature: Context.GetFeature<ITenantFeature>().


There you go, two ways of detecting tenants based on the incoming URL. The full source for both solutions is at https://gist.github.com/maartenba/77ca6f9cfef50efa96ec (requires some assembling).


 Maarten Balliauw {blog} News Feed 

Last edited Oct 15, 2008 at 7:15 AM by maartenba, version 4