Tag Archives: C#

C#: Ordering by a list of ordered predicates

In a project at work we were going to merge a bunch of PDfs and Word documents into a single PDF. The ordering irrelevant except that certain files had to be before all the others. Solved it initially like this:

    var filesInOrder = GetFiles()
        .OrderByDescending(x => x.Filename.StartsWith("ProjectDescription_"))
        .ThenByDescending(x => x.Filename.StartsWith("Budget_"))
        .ThenByDescending(x => x.Filename.StartsWith("CV_"))
        .ToArray();

Found it a bit ugly though, and decided to ask a question about other ways on StackOverflow. Got several interesting answers and inspired by those and some further thinking I tried to make a generic solution myself, which I thought I could also blog here so I definitely know where to find it if I ever need it again…

My solution

public class OrderedPredicateComparer<T> : IComparer<T>
{
    private readonly Func<T, bool>[] ordinals;
    public OrderedPredicateComparer(IEnumerable<Func<T, bool>> predicates)
    {
        ordinals = predicates.ToArray();
    }

    public int Compare(T x, T y)
    {
        return GetOrdinal(x) - GetOrdinal(y);
    }

    private int GetOrdinal(T item)
    {
        for (int i = 0; i < ordinals.Length; i++)
            if (ordinals[i](item))
                return i - ordinals.Length;
        return 0;
    }
}

One issue here might be that the predicates will be called several times per item, which could be bad if working on a huge list. Haven’t really benchmarked it though so could be fine for all I know. For smaller uses it shouldn’t matter much either way. Very curious to know about ways to optimize this though, so do let me know in the comments below if you have any good ideas!

The nice thing about it being an IComparer is that you could push this into both OrderBy and ThenBy, and also use it in for example ordered dictionaries, priority queues, etc, and since it uses a list of fully generic predicates you could order things by pretty much anything with a yes/no answer 🙂

Usage

var ordering = new Func<string, bool>[]
    {
        x => x.StartsWith("ProjectDescription_"),
        x => x.StartsWith("Budget_"),
        x => x.StartsWith("CV_"),
    };

var files = GetFiles()
    .OrderBy(x => x.Filename, new OrderedPredicatesComparer<string>(ordering))
    .ToArray();

To make the final code even cleaner the ordering could be encapsulated in a sublcass like following, which is what I did in my actual code too:

public class MySpecificOrdering : OrderedPredicatesComparer<string>
{
    private static readonly Func<string, bool>[] order = new Func<string, bool>[]
        {
            x => x.StartsWith("ProjectDescription_"),
            x => x.StartsWith("Budget_"),
            x => x.StartsWith("CV_"),
        };

    public MySpecificOrdering() : base(order) {}
}

var files = GetFiles()
    .OrderBy(x => x.Filename, new MySpecificOrdering())
    .ToArray();

ASP.NET MVC Areas in separate projects/assemblies

Had to implement a webshop section for an ASP.NET MVC website project which was to be reused by another one. Solving it was a bit finicky, so documenting it roughly here in case I need to do it again in the future. Not sure I remember all the steps, but hopefully it’ll be enough to reproduce the effect:P

The main problem here is the way razor views are compiled run-time and that is solved by using the Razor Generator VS extension to pre-compile the views and the belonging RazorGenerator.Mvc Nuget package to enable the web application to find them during run-time.

Don’t know if the solution I ended up with is the best, but it worked fairly great. If you have better/cleaner solutions please leave a comment 🙂

Continue reading ASP.NET MVC Areas in separate projects/assemblies

Output embedded resources into Razor views

In relation to my ASP.NET MVC Areas in separate projects thing I needed to share some tiny bits of javascript and css between pages in this separate project. Could probably be solved better by looking into the bundling stuff, but as a quick fix I decided to just compile the javascript and css files into the assembly and output them raw into my views. Quick and simple.

  1. Set the Build Action of your js and css file to Embedded Resource
  2. Add this extension method to a static class.
    public static IHtmlString RawResource(this HtmlHelper html, Type type, string resourceName)
    {
        using (var s = type.Assembly.GetManifestResourceStream(resourceName) ?? new MemoryStream())
        using (var r = new StreamReader(s))
        {
            s.Position = 0;
            return new HtmlString(r.ReadToEnd());
        }
    }
  3. Make sure the extension method is available in your view
    @using The.Namespace.Of.My.Static.Class
  4. Use the method in your view
    <script type="text/javascript">
        @Html.RawResource(typeof(AnyClassInAssembyOfEmbeddedResource), "Default.Namespace.Of.Project.Resources.file.js");
    </script>

    <style type="text/css">
        @Html.RawResource(typeof(AnyClassInAssembyOfEmbeddedResource), "Default.Namespace.Of.Project.Resources.file.min.css")
    </style>

Easy peasy. And slightly hackish and ugly… let me know if you have smoother, cleaner bundling approach 😉

If you’re having problems figuring out the right name of your embedded resource, see my post on how to use embedded resources for how to list them all out.

C#: Temporary file handler for unit tests and such

Wrote a class that worked with files and needed to unit test its methods. Created a simple TemporaryFile class to easily create and dispose of the files I used in those tests. Here it is:

using System;
using System.IO;

namespace Geekality.IO
{
    public sealed class TemporaryFile : IDisposable
    {
        private readonly FileInfo file;
        public FileInfo FileInfo { get { return file; } }

        public TemporaryFile() : this(Path.GetTempFileName()) { }
        public TemporaryFile(string fileName) : this(new FileInfo(fileName)) { }
        public TemporaryFile(FileInfo temporaryFile)
        {
            file = temporaryFile;
        }
        public TemporaryFile(Stream initialFileContents) : this()
        {
            using (var file = new FileStream(this, FileMode.Open))
                initialFileContents.CopyTo(file);
        }

        public static implicit operator FileInfo(TemporaryFile temporaryFile)
        {
            return temporaryFile.file;
        }
        public static implicit operator string(TemporaryFile temporaryFile)
        {
            return temporaryFile.file.FullName;
        }
        public static explicit operator TemporaryFile(FileInfo temporaryFile)
        {
            return new TemporaryFile(temporaryFile);
        }

        private volatile bool disposed;
        public void Dispose()
        {
            try
            {
                file.Delete();
                disposed = true;
            }
            catch (Exception) { } // Ignore
        }
        ~TemporaryFile()
        {
            if (!disposed) Dispose();
        }
    }
}

This class will create a temporary file and delete it on dispose (or when the finalizer is called). It also supports implicit casting to the FileInfo object it contains and to its full path string. This makes it easy to use with methods taking those types of parameters. For example:

using(var file = new TemporaryFile())
{
    Assume.That(file.FileInfo.Length, Is.EqualTo(0))

    File.WriteAllText(file, "some text");

    file.FileInfo.Refresh();
    Assert.That(file.FileInfo.Length, Is.GreaterThan(0));
}

For fun I also created a Nuget package for this, so that it’s easy to add to projects when I need it. Works pretty perfectly, if I may say so myself 🙂 Feedback is welcome!

Source: bitbucket.org/svish/geekality.io
Nuget: nuget.org/packages/Geekality.IO

C#: Getting started with Saxon-HE XSLT transformation

The XslCompiledTransform class of .NET only supports XSLT 1.0 for some annoying reason. I needed support for version 2.0 and for that I found the free Saxon-HE library through NuGet.

Their API documentation is OK I suppose, although I wish the API was more .NET targeted. Also can’t say I’m impressed by their documentation on how to get started using this stuff.

Either way, here are the steps to do a simple XSLT transformation of an XML document.

Continue reading C#: Getting started with Saxon-HE XSLT transformation