A solution to missing XML files and Swagger

You use Swagger, and include XML comment files, which are copied during build from a few different projects to the root of your API application. Then one day, you realize that the build didn’t copy one of the XML files, so this line threw an exception:

options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "MyProject.Domain.xml"));

Yes, you can fix the build to resolve the error, but if you treat XML comments as content (not code), you can do this:

foreach (var file in Directory.GetFiles(AppContext.BaseDirectory, "*.xml"))
{
    options.IncludeXmlComments(file);
}

It appears that Swagger doesn’t break when a non-XML comment file are included, which is beneficial. With this method, only XML files that exist are included, you don’t risk breaking your app when they are missing.

Extending DbSet for easy filter expressions

Databases often have entities which are often by a repeated expression. A common one is filtering something by a UserId. In SQL, this looks like:

select * 
from orders
where userid = @userid;

Using Entity Framework, we may write something like this:

dataContext.Orders.Where(x => x.UserId == userId);

But I’d really like to make it more expressive and consistent, like this:

dataContext.Orders.ForUser(userId);

Fortunately, it is possible, with an interface and an extension method.

The interface, which I will call IUserEntity, will expose the common filtered expressions.

public interface IUserEntity
{
	int UserId { get; set; }
	User User { get; set; }
}

Any class that can be filtered by users should inherit this class.

public class Order : IUserEntity
{
	public int Id { get; set; }
	public int UserId { get; set; }
	public User User { get; set; } = null!;
}

Then our expression method will extend any DbSet with a type of IUserEntity to include our extension method, which simply returns a filtered DbSet.

public static class DbSetExtensions
{
	public static IQueryable<T> ForUser<T>(this DbSet<T> userEntities, int? userId) where T : class, IUserEntity
	{
		if (userId.HasValue)
		{
			return userEntities.Where(x => x.UserId == userId.Value);
		}
		return userEntities;
	}
}

Note how in the above I made the userId nullable — this is not required, but it does give you a bit more flexibility.

This can be replicated for any other common filter, which will make your code more expressive and easy to read. If you wanted similar extensions on other elements, such as Lists, you could just make a copy of the extension method for that object type, and the appropriate return types.

Everything you ever wanted to know about an enum (well, almost everything)

The enum, what a lovely creature available to us in C#. They help make our code more readable and bug-resistant. They also have some tricks up their sleeves.

Take a sample enum declaration:

public enum Level
{
	Unknown = 0,
	Low,
	Medium,
	High
}

If you want a string representation of an enum, you simply use the ToString() method.

Console.WriteLine(Level.Unknown.ToString());
/* output:
Unknown
*/

If you want the numeric value of an enum, cast it to an int. (By default, an enum is an int, though you can specify other numeric values for them.)

int i = (int)Level.Low;
Console.WriteLine(i);
/* output:
1
*/

If you have a string and want to convert it to an enum, use the Enum.Parse() method. Pass the enum type, the string value to parse, and an optional boolean parameter to note if you want the parsing to be case-insensitive. (By default, parsing is case-sensitive.)

Level lvl;

// case-insensitive parsing
lvl = (Level)Enum.Parse(typeof(Level), "medium", true);
Console.WriteLine(i);
/* output:
Medium
*/

// default, case-sensitive parsing
lvl = (Level)Enum.Parse(typeof(Level), "high");
/* throws an exception:
System.ArgumentException: Requested value 'high' was not found.
*/

If you have a numeric value and want to convert it to an enum, simply typecast the number to the enum type. Remember, an enum is just a number!

int val = 3;
Level lvl = (Level)val;
Console.WriteLine(lvl);
/* output:
High
*/

What about a set of enums that are not mutually exclusive (i.e. a sets of flags)? A “flags” enum can have multiple values, and is decorated with the [Flags] attribute, as shown below. Note that a these enums should have values defined in powers of two (1, 2, 4, 8, etc.). See below for a sporting example.

[Flags]
public enum Bases
{
	Empty = 0,
	First = 1,
	Second = 2,
	Third = 4,
	FirstAndSecond = Bases.First + Bases.Second,
	FirstAndThird = Bases.First + Bases.Third,
	SecondAndThird = Bases.Second + Bases.Third,
	Loaded = Bases.First + Bases.Second + Bases.Third
}

Many of the previously defined operations work on these enums. String output is as you would expect when using ToString():

Console.WriteLine(Bases.Empty.ToString());
Console.WriteLine(Bases.FirstAndSecond.ToString());
/* output:
Empty
FirstAndSecond
*/

Getting the numeric value is the same, too:

int i = (int)Bases.First;
int j = (int)Bases.SecondAndThird;
Console.WriteLine(i);
Console.WriteLine(j);
/* output:
1
6
*/

Parsing — yes, the same.

Bases b1 = (Bases)Enum.Parse(typeof(Bases), "second", true);
Bases b2 = (Bases)Enum.Parse(typeof(Bases), "Loaded");
Console.WriteLine(b1);
Console.WriteLine(b2);
/* output:
Second
Loaded
*/

Numeric values? The same as well.

int val = 5;
Bases bases = (Bases)val;
Console.WriteLine(bases);
/* output:
FirstAndThird
*/

One thing you’d want to do with a flagg enum is to detect if a particular flag is set. It’s easy to do using the AND operator (&).

bool isFirstOnSecondOrThird = (Bases.First & Bases.SecondAndThird) == Bases.First;
bool isFirstOnLoaded = (Bases.First & Bases.Loaded) == Bases.First;

/* output:
False
True
*/

There’s lots more that you can do with enums — check out some of the following links for more info:

C# 3.0’s syntatic sugar

In the old days, we’d write something like this:

view.Rows.Add("Type");
view.Rows.Add("Count");
view.Rows.Add("Whatever");

With C# 3.0 we can do this:

new string[] { "Type", "Count", "Whatever" }
    .ForEach(str => view.Rows.Add(str));

That is very cool syntatic sugar. Sure, this is not new news, but when you think about C# in the context of the new features available in 3.0, it really starts to feel a lot more like coding with JavaScript (which is a good thing).

Google AdSense ViewComponent for MonoRail

Like many, I use Google AdSense to host ads on my web sites. Including the ad code typically requires you to paste a block a block of JavaScript onto the page. I don’t mind injecting the JavaScript, but I wanted to come up with a better way.

The solution I came up with was a quick MonoRail ViewComponent, AdUnit. It has a simple purpose: to render a block of code for an ad unit of a given size.

The first task was to create an enum which represented all the possible ad unit sizes, based on what’s offered by Google. Continue reading