NuGet package restore with multiple repositories and file shares

To enable NuGet package restore from multiple repositories you have to edit the NuGet.targets file in the .nuget solution folder.

<ItemGroup Condition=" '$(PackageSources)' == '' ">
    <!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
    <!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
    <PackageSource Include="https://nuget.org/api/v2/" />
    <PackageSource Include="\\\\my-server\\my-packages\\" />
</ItemGroup>

Important: escape the backslashes in the file share path, or you’ll get a very cryptic error message!

Migrate Entity Framework migrations from automatic to code-based

Users of Entity Framework (EF) migrations must have noticed that there are two ways to perform migrations: automatic and code based.
With automatic migrations, EF compares the code-first model to the latest version that is stored in the __MigrationHistory system table in the database. After that, EF synchronizes the database with the code-first model and then stores a new model version in the __MigrationHistory table.
With code-based migrations, you have to explicitly specify all changes in code en EF doesn’t compare the models to detect changes.

In a project, we started using automatic migrations. Why automatic? Simply: it’s less work and at the time the drawbacks weren’t very clear. Unfortunately, after a year, we realized that this was the wrong choice. A new product version required changes that couldn’t simple be handled by automatic migrations without data loss. Time to move to code based migrations. This is easy with an existing database. Just create an initial migration with Add-Migration and the –IgnoreChanges flag and you have baseline. But this doesn’t work when you also a a requirement to create new databases from the migrations.

The solution is to script the database just before you’re moving to code-based migrations and execute this script in the Up() method of the initial migration. The key here is that this script has to check if database objects exist before creating them. This way it can also be used with existing databases.

Summary of migrations migration steps (SQL Server database):

  1. Before the migration, ensure that the database(s) and code-first model are in sync;
  2. Script the existing tables (in SQL Server Management Studio: Generate Scripts and then under Scripting Options –> Advanced, ensure that ‘Check for object existence’ is set to True). Add the script to your VS project that has the migrations. We need this later;
  3. In \Migrations\Configuration.cs turn off Automatic Migrations:
    internal sealed class Configuration : DbMigrationsConfiguration<PortalDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }
    }
    
  4. In the Package Manager Console enter ‘Add-Migration –IgnoreChanges’ and enter a name for the initial migration. This will create the baseline migration in the \MIgrations directory.
  5. Now the tricky bit: ensure that the script created in step 2 is executed in the Up() method of the initial migration. My Up() method looks like this:
    public override void Up()
    {
        // Run script that creates the tables while preserving
        // existing tables and data
        // The script is stored as embedded resource in the assembly
        var currentAssembly = Assembly.GetExecutingAssembly();
        using (var createScriptStream = 
            currentAssembly.GetManifestResourceStream("MyProject.Migrations.Scripts.CreateTablesFromAutomaticMigrations.sql"))
        {
            if (createScriptStream != null)
            {
                var createScript = new StreamReader(createScriptStream).ReadToEnd();
                // Get separate commands from the script (SQL Server uses GO as separator)
                var regex = new Regex(@"\r{0,1}\nGO\r{0,1}\n");            
                var commands = regex.Split(script);
                foreach (var command in commands)
                {
                    if (! string.IsNullOrEmpty(command))
                    {
                        Sql(command);
                    }
                }
            }
        }
    }
    
    

    In the Up() method you can execute arbitrary SQL commands with the Sql() method. Note that in the example, the script is read from an embbeded resource, but it’s also perfectly fine to store the script as a file somewhere and create a stream from that.

  6. Ready. Migrations are migrated.

Please leave a comment if you you know a better solution. I think this is still a little bit clumsy although it works for us.

Øredev 2012

oredev

Last week, my partner in crime Erwin and I went to Malmö, Sweden to visit the yearly Øredev conference. One word: magnificent!
Øredev is not your average developer conference where you learn about new technology. The topics are much broader, ranging from hardcore programming languages to the more social-cultural aspects of software development.

This year’s theme was ‘Vive la rebellion’ and especially the keynote sessions very much resembled this. The main message I personally got from the conference was:

If you want to make a difference and be successful, you have to stop following what your neighbours are doing but start with your own vision, knowledge and values and think! Don’t do anything ‘just because’.

It’s too easy to lean back into your comfortable IDE and just put out some code because your customer wants you to. We as software developers can do some much better!

Random tech observations

  • Microsoft has fully embraced Open Source. What started with embedding jQuery in ASP.NET now expanded to a huge amount of projects and initiatives with many of these located at GitHub;
  • Cloud technology is no hype anymore. It’s really happening on a large scale: Azure, Amazon, GitHub and others;
  • The same goes for NoSQL databases. These are now established technologies and will not go away anymore;
  • There was more Javascript than C# in the .NET sessions;
  • Javascript is bringing isolated developer cultures together;
  • Web, mobile, and desktop applications are converging.

Conference

Finally, many thanks to the Øredev organization for creating such a great event. I really don’t know of any other event like this in northern/middle Europe. Highly recommended!

1931818533

MvcPaging 2.0

image

Last week, a new version of the MvcPaging library has been released. This time there are some breaking changes and that’s why the major version number is increased.

What’s new:

  • Simplified API with reduced number of Html.Pager overloads;
  • DisplayTemplate option and PaginationModel;
  • Configurable number of pages.

Simplified API

There have been some requests for extra configuration options, but I didn’t want to add more overloads to the Html.Pager helper. Instead, the number of overloads is reduced drastically:

Html.Pager(int pageSize, int currentPage, int totalItemCount)

and

Html.Pager(int pageSize, int currentPage, int totalItemCount, AjaxOptions ajaxOptions)

We now only have a method with the required parameters and one overload for Ajax scenarios. Also, the Ajax.Pager helper is removed. Note that this is a breaking change, so if you were using the Ajax.Pager helper, you now have to use the Html.Pager with the AjaxOptions overload.

Non-required configuration options are added via the Options() method. This interface also replaces the overloads in the previous version where you could set route values or controller actions. This is the second breaking change. You can now only set these values via the Options method.

Html.Pager(pageSize, pageNumber, totalItemCount).Options(o => o
    .Action("action")
    .AddRouteValue("q", mySearchQuery)
)

Below are all options:

  • Action(string action)Sets an alternative action for the pager that is different from the current action.
  • AddRouteValue(string name, object value)Adds a single route value parameter that is added to page url’s.
  • RouteValues(object routeValues)Adds route value parameters that are added to the page url’s.
  • RouteValues(RouteValueDictionary routeValues)Adds route value parameters that are added to the page url’s.
  • DisplayTemplate(string displayTemplate)When set, the internal HTML rendering is bypassed and a DisplayTemplate view with the given name is rendered instead. Note that the DisplayTemplate must have a model of type PaginationModel.
  • MaxNrOfPages(int maxNrOfPages)Sets the maximum number of pages to show.

DisplayTemplate option

A few people have been asking for configurable rendering, especially since Twitter Bootstrap has become popular. Rajeesh CV submitted a pull request that introduced a view model for the Pager, the PaginationModel. This view model made it very easy to create an option where you can specify a DisplayTemplate that is used for the actual rendering. It works like any other ASP.NET MVC DisplayTemplate and requires a model of PaginationModel. As a bonus, the PaginationModel makes unit testing a lot easier.

The MvcPaging.Demo project has an example DisplayTemplate that renders Html that is compatible with Twitter Bootstrap:

Html.Pager(pageSize, pageNumber, totalItemCount).Options(o => o
    .DisplayTemplate("BootstrapPagination")
    .MaxNrOfPages(14))

image

Configurable number of pages

As you can see in  the screenshot above, the pager can now be configured to show more or less than 10 pages via the MaxNrOfPages() option.

I’d like to thank Rajeesh CV, jbucht01 for the contributions and ideas. For more information, visit the GitHub project page, or install the Pager in your own projects with NuGet.

Introducing Actya – a .NET CMS that doesn’t get in your way

Actya is a simple open source ASP.NET MVC Content Management System (CMS).

Why on earth would we need another CMS?

Quite often, a CMS is chosen as application framework for custom application development because you’ll get a lot for free: navigation, security and content management (obviously). Custom applications are then developed as modules that run within the context of the CMS. Cuyahoga, the CMS I’ve started  8 years ago works exactly like this.

Rob Conery describes an issue with this solution:

I’ve deployed Big CMS’s before as a solution for clients and every single time we decided to move away. They’re great for getting off the ground – but after a while there’s jus too much friction.

And that’s probably what many of us experience: a CMS gets in the way when your main focus is the custom application. This is the single main reason to create Actya: a CMS that doesn’t get in your way when doing custom development.

CMS as add-on

Actya can act as an add-on library for your application. While developing your custom application in Visual Studio, you can add it with NuGet just like any other library. The first time you run your application after adding Actya, an installer kicks in to ask you where you want to have your CMS data stored, what theme you want to use and which account is the CMS administrator. No further configuration required and nothing has to change in your custom application.

The video below shows this scenario with NuGetGallery as the ‘custom’ application:

Even though Actya is mainly designed to act as an add-on CMS, you can also use it as a simple regular CMS. Download it at from CodePlex downloads page, point an IIS 7+ web site or application to the extracted files, open de site in your browser and the installation starts automatically.

After installation, you can access Actya’s admin pages at http://my-host-or-application/cmsadmin.

RavenDB document database

Here’s the other reason for creating Actya: schema-less NoSQL databases are considered to be ideal for CMS applications because you can put any type of content in it without having to alter a database schema or have some kind of monstrous Entity-Attribute-Value model. I wanted to experience if that claim is true.

Actya uses the .NET NoSQL database RavenDB and it really makes development easier. Not only due to the flexibility of the schema-less design but also to the absence of a mapping layer. Wonderful! A cool feature of RavenDB is the embedded mode where you don’t need a database server at all. Actya uses this mode by default (the data goes in App_Data), but can also connect to an existing RavenDB server.

Requirements

  • ASP.NET 4.0
  • Full-Trust environment

Wanted: Feedback

I’ve released the first alpha version to see if anybody finds this CMS useful. Your feedback will have a have a lot of weight in determining future development. If you have any, please go to http://actya.codeplex.com/discussions and open a discussion with ‘User Feedback’ as topic.