Showing posts with label .net mvc. Show all posts
Showing posts with label .net mvc. Show all posts

Tuesday, 21 October 2014

Enable MvcBuildViews using TeamCity if a view is changed

At work we recently switched from using SVN to Git and GitHub. There are many advantages but there's one in particular I want to talk about. 

Using TeamCity you can automatically build all pull requests. This is incredibly useful as it ensures only code that compiles successfully and passes all unit tests gets back into master. If the build fails you are notified in GitHub.

But, there's a problem. View errors are not reported because MvcBuildViews is off. One solution is to enable MvcBuildViews for all web projects but in our case this is best avoided as it roughly quadruples compile time. The ideal solution is to enable MvcBuildViews only if a view has been changed in the current build. Unfortunately I struggled to work out how to do this. So I asked a question on Stack Overflow and the first answer I received pointed me the right direction.

I've managed to improve on my Stack Overflow answer. It simply enables MvcBuildViews for all .csproj files if a view has changed, but this is still quite slow. It's much faster to only enable the setting for projects in which views have changed. This may be overkill for many solutions but for ours it's not.

A few things to bear in mind:
  • I'm no PowerShell expert
  • You'll probably what to change the Get-ChildItem command in step one to point directly at your web project .csproj files rather than all .csproj files
  • The Write-Host commands must be formatted in this way so they appear in the TeamCity build log
  • By default TeamCity does not do a clean checkout of the source code (although this can be enabled). Instead changes are applied incrementally meaning that alterations to .csproj files are not undone on each build. So MvcBuildViews should be reset on every build
  • %system.teamcity.build.changedFiles.file% - This file lists all the changes in the current build in the format [fileName]:[status]:[commitHash]. E.g. Home/Index.cshtml:CHANGED:1400ea14c3196abbfd8de3ab6fe0a902be2ccad8
  • %teamcity.build.workingDir% - This is the directory that contains all the files to be built

Wednesday, 12 February 2014

Other people's code - Suteki Shop

It occurred to me a while ago it would be a good idea to have a dig through some open source code. Why? Primarily because in the last few years I've spent the majority of my time working on two codebases, one at home and the other at work. I feel very much in my own little code bubble. Working with the same code day in day out you become familiar with the conventions and patterns chosen and you can get into a rut. 

So, the point of this exercise is to get me out of my comfort zone and learn something new. How have other people solved problems I've faced? What is their code like? How to they handle errors? What new ideas or ways of working can I apply to my code?


Suteki Shop

Suteki Shop, written by Mike Hadlow using NHibernate and .NET MVC, is an open source eCommerce site aimed at the fashion and retail industry. I figured it was a good place to start because looking through an unfamiliar codebase is difficult but.NET MVC is my day job so that will give me a head start.


Observations

  • The UnitOfWorkAttribute is a great way of encapsulating all database operations in a single action into a transaction and committing on success or rolling back on exception
  • Exception handling is minimal. It seems to only be added where it's really required resulting in really clean code
  • Really nice use of fluent interfaces to create more readable code when mapping data to view models 
  • Generic repositories make CRUD operations ridiculously simple
  • On the whole the controllers are short. Unnecessary code hasn't leaked into them which I find often happens in my work codebase
  • Some domain objects fire events whose handlers call methods on services classes, which is a mechanism I've never considered using. E.g. The Order object has no dependencies on any other class, but if you call Confirm() it will set OrderStatus to OrderStatus.Created and fire an OrderConfirmed event whose handler calls EmailService.SendOrderConfirmation. It's a nice way of running non critical tasks
  • Object values can be retrieved from the database as if by magic using the power of the EntityModelBinder

ScaffoldController<T>

This is really interesting. It's CRUD done right. Several controllers inherit from this and they contain a couple of attributes and no other code. 

Repository operations are possible because the generic class that applies to the controller also applies to the repository. That generic class is also used to build the view which can store a single item, list of items or return data for a drop down list.

Obviously there are down sides to this approach. It can't be used if you want to do any non standard operations and you still need to create the view.

What can I take from this?

  • Chaining methods with fluent interfaces is great for creating readable code, I don't use it enough
  • There's really no reason to put any kind of logic in the controller, it can always go elsewhere
  • I don't understand generics quite as well as I'd like 
  • Model binding is something I should read up on
  • Not all actions in a web application need to be done synchronously. If something isn't critical it can be carried out using events or some other async process

Sunday, 22 July 2012

Simple database driven feature toggles for ASP.NET MVC


A bit like a broken record I keep mentioning that we use continuous integration at work. So blah blah blah, we need feature toggles. My previous experience has involved using a very simple feature toggling mechanism and looking into a few other open source feature toggling tools. For this blog I'm going to ramble on about another simple idea that I implemented using toggles stored in a database. This solution is specific to ASP.NET MVC due to the way the toggles are populated but I imagine similar mechanisms exist in other frameworks. Although I wrote most of the code, I can't take credit for the idea. That goes to a couple of my colleagues (see their blogs here and here). They each claim it was their idea. I'll let them fight it out. 

How it works

The feature toggles are stored in a static class. What? A static class?!? I don't like it! Bear with me. I thought the same when I first heard the idea but I was convinced otherwise. This static class is used purely to store the values of the toggles, that's it. This comes with a few significant benefits. Primarily it can be defined in a common project (our solution has a lot of projects) and then be used anywhere, view, service, or controller. In addition it doesn't need to be passed around via constructor injection so it doesn't pollute a huge number of classes in the code base. Just to highlight that point, there is absolutely zero IoC setup required to use toggles once the initial implementation is done. But wait, there's more good stuff. What about unit tests? Will adding feature toggles break them? Nope. Because the static class is just a container the toggles will default to being off. If you want to create unit tests which test the toggle being on, just set the toggle to true in the unit test. Easy.

So how is it populated? It's very simple. A new Action Filter is applied to all controllers. For our code this is very easy because all controllers inherit from a base class. On every page load this Action Filter retrieves the toggle values from the database, if they have changed. 

Why get toggles from the database? There are a few good reasons. Firstly it's very easy to change their value at run time. Secondly it's very easy to make them available to every project in a solution. This is in contrast to a previous mechanism I tried whereby the toggles were stored in appSettings in a web.config file which required the adding of a file attribute to the appSettings element in each project where the toggles were required. Another benefit of using database toggles is that the implementation can easily be extended. It would be fairly easy to add new features like toggles controlled by date or toggle state. E.g. Always on, always off.

Are there any disadvantages to this approach? Currently because the toggles are populated by an Action Filter they can only be used in MVC applications, not windows services or console applications etc. 

The code

FeatureToggles static class


Each feature toggle is simply a public static boolean with a private setter. Why a private setter? It indicates to others using that class that they shouldn't change the value of an individual toggle variable. However there does need to be a mechanism for setting toggle values for unit testing purposes, which is done by SetToggleValue. Reflection is used to prevent the need for any extra code being written when a toggle is added.

SetFeatureToggles is used to populate all the toggles using reflection. Again reflection means no code changes are required when adding or removing toggle variables. The toggle name passed in must match the name of the toggle variable. Note, the FeatureToggle classes passed into the method simply contain two properties, string Name and bool IsActive.

GetActiveFeatureTogglesAsStringForBodyTag returns a string containing a space separated list of toggle variable names prefixed with "FT_" which is outputted in the class attribute of the body tag in each page. This allows CSS rules to be defined for when the toggle is on.

HasBeenInitalised is required to ensure the toggle values are retrieved from the database the first time the application is run. This is a quirk of our implementation because the cache isn't necessarily invalidated when the application is restarted.

Action Filter


The job of this Action Filter is very straight forward. If the toggles have changed retrieve the values from the database and repopulate the static toggle variables. This avoids reloading the toggles on every page load. I'm not showing the implementation details of FeatureToggleService because it's very specific to our application. There's nothing special going on to be honest. GetAll() simply returns a list of FeatureToggle classes either from the cache, if populated, or the database. The FeatureToggle class has two properties, string Name and bool IsActive. HaveValuesChanged() unsurprisingly returns a bool indicating whether the toggle values have changed.

How to add a toggle

To start using a feature toggle only one step is required. Add a public static boolean property to FeatureToggles class.


Obviously the toggle will always be false until you also add the toggle to the database. This is done using a simple admin tool which can add, remove or flip toggles. Whenever one of these actions is taken the cache is cleared which will cause the static toggle values to be refreshed.

How to use a toggle

In code


In views

Programmatically hide or show a feature:


Or use the outputted CSS class:

Advantages/disadvantages

Advantages
  • Incredibly easy to add a new toggle
  • Incredibly easy to use a toggle in any layer of the application
  • Easy to extend the implementation. E.g. Add date after which toggle is active
  • Existing unit tests are not broken 
  • Toggles can be flipped easily at run time with no need to manually edit a config file
  • No IoC set up required
  • Toggles can incorporate CSS

Disadvantages
  • Only works in MVC projects
  • Some people won't like the static class implementation