September 2009 Entries

This post was spawned as I was reviewing the latest Oxite source code on CodePlex. I’ve been reading any source code I could get my hands on lately looking for inspiration to cure my “winter coding boredom.” While it isn’t winter yet, it is fast approaching, which means less outdoors time and more computer time. I try to blog more, update my open source projects with a new release, and with any luck begin a new project worth getting passionate about.

Today I'm going to hit the ground running with a short tip, again, on the yield keyword.

The following code is an excerpt from the Oxite Blog class. Blog as it turns out, is a Cacheable Entity (ICacheEntity) where the designer of the interface determined that cached entities can specify any dependencies they may have. Clearly, the developer of the ICacheEntity interface understood iterators and realized that the consumer of any ICacheEntity requires nothing more foreach’ing over the dependencies. For this reason, the method does not return an IList<T>, an ICollection<T>, or (heaven forbid) a List<T>.

Unfortunately, the developer writing the Blog class did not take advantage of the (albeit minor) utility provided. The developer chose to new up a List, insert the single item, then return the list -- as seen in the following code.

IEnumerable<ICacheEntity> ICacheEntity.GetCacheDependencyItems()
{
    List<ICacheEntity> dependencies = new List<ICacheEntity>();

    dependencies.Add(Site);

    return dependencies;
}

We've all written code like this. The bad habit may even be so ingrained into our developer DNA that we don't even realize it. Long story short, if it returns IEnumerable, you should probably use the yield keyword!

The above code can simply be re-written as follows. The benefits of this should be clear: fewer lines of code, easier readability, greater performance (minor of course, but still).  Since this topic has been covered at great length on the blogosphere I won't go into any more detail, but just in case, here is a quick article I found that should help explain the benefits.

IEnumerable<ICacheEntity> ICacheEntity.GetCacheDependencyItems()
{
     yield return Site;
}

 

Bonus Protip

I actually stumbled onto something small but nice while reading the Oxite code. Enumerable.Empty.

IEnumerable<Product> products = Enumerable.Empty<Product>;

 

Technorati Tags:

Today I began integration testing my SqlRepository while I experiment with an MVC prototype. I tried googling for a simple base class for integration testing a LINQ to SQL DataContext that would provide automatic rollback between each test, but after (minimal) searching, decided to simply write my own. Perhaps this will help someone. This base class was written for MS Test, but simply renaming the attributes accordingly would yield the same results on nUnit, xUnit, etc.

The Code

Simply inherit your test class from this base class and any changes done via the internal Context property will be automatically rolled back after each test runs.

/// <summary>
/// The base class will allow LINQ to SQL integration testing with automatic rollbacks after each test
/// </summary>
/// <typeparam name="TContext">The type of data context to use</typeparam>
public abstract class RolledBackDataContextTests<TContext> where TContext : DataContext
{
    private TContext _context;
    private DbTransaction _transaction;

    [TestInitialize]
    public void InitDataContext()
    {
        if(string.IsNullOrEmpty(ConnectionString))
        {
            _context = (TContext)Activator.CreateInstance(typeof(TContext));
        }
        else
        {
            _context = (TContext) Activator.CreateInstance(typeof (TContext), ConnectionString);
        }

        _context.Connection.Open();
        _transaction = _context.Connection.BeginTransaction();
        _context.Transaction = _transaction;
    }

    /// <summary>
    /// Provides access to the internal data context. Any changes made will be automatically rolled back
    /// </summary>
    protected TContext Context
    {
        get
        {
            if(_context == null)
                InitDataContext();

            return _context;
        }
    }

    /// <summary>
    /// Optionally specify the connection string to use
    /// </summary>
    protected virtual string ConnectionString
    {
        get
        {
            return null;
        }
    }

    [TestCleanup]
    public void TestCleanup()
    {
        _transaction.Rollback();
        _context.Dispose();
        _context = null;
    }
}

Usage

[TestClass]
public class SqlRepositoryTests : RolledBackDataContextTests<NorthwindDataContext>
{
    // Insert as many Products as required and then exercise your database integration Test Methods
    public void InsertProductToContext()
    {
        Product p = new Product { ProductName = "Temporary Product"};
        Context.Products.InsertOnSubmit(p);
        Context.SubmitChanges();

        // After each test ends, the transaction will be rolled back, and the new Product will not be in the database
    }

    [TestMethod]
    public void Test1()
    {
        // Test logic here
    }
}
Technorati Tags: ,

This was one of the first extension methods I wrote when C# 3.0 arrived, since I just stumbled across it on an older project I figured I might as well post it, if for nothing else but future reference. One downside to be aware of if you choose to use this method, is that it will not project the results on a IQueryable provider like LINQ to SQL, so please be aware the conversion will be done on the client side.

The Code

public static class DelimitedStringExtensions
{
    public static string DefaultDelimiter = ", ";

    /// <summary>
    /// Convert a sequence of items to a delimited string. By default, ToString() will be called on each item in the sequence to formulate the result. The default delimiter of ', ' will be used
    /// </summary>
    public static string ToDelimitedString<T>(this IEnumerable<T> source)
    {
        return source.ToDelimitedString(x => x.ToString(), DefaultDelimiter);
    }

    /// <summary>
    /// Convert a sequence of items to a delimited string. By default, ToString() will be called on each item in the sequence to formulate the result
    /// </summary>
    /// <param name="delimiter">The delimiter to separate each item with</param>
    public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter)
    {
        return source.ToDelimitedString(x => x.ToString(), delimiter);
    }

    /// <summary>
    /// Convert a sequence of items to a delimited string. The default delimiter of ', ' will be used
    /// </summary>
    /// <param name="selector">A lambda expression to select a string property of <typeparamref name="T"/></param>
    public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> selector)
    {
        return source.ToDelimitedString(selector, DefaultDelimiter);
    }

    /// <summary>
    /// Convert a sequence of items to a delimited string.
    /// </summary>
    /// <param name="selector">A lambda expression to select a string property of <typeparamref name="T"/></param>
    /// <param name="delimiter">The delimiter to separate each item with</param>
    public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> selector, string delimiter)
    {
        if (source == null)
            return string.Empty;

        if(selector == null)
            throw new ArgumentNullException("selector", "Must provide a valid property selector");

        if (string.IsNullOrEmpty(delimiter))
            delimiter = DefaultDelimiter;

        return string.Join(delimiter, source.Select(selector).ToArray());
    }
}

Usage

Example using an array of ints

int[] ints = { 1, 4, 5, 7 };

// Returns "1, 4, 5, 7"
string result = ints.ToDelimitedString();

Example using a List

var products = new List<Product>
               {
                   new Product { ProductName = "Chai" },
                   new Product { ProductName = "Chang" },
                   new Product { ProductName = "Tofu" },
               };

// Returns "Chai, Chang, Tofu"
string result1 = products.ToDelimitedString(p => p.ProductName);


// Returns "Chai;Chang;Tofu"
string result2 = products.ToDelimitedString(p => p.ProductName, ";");

Example using a DataTable

// Returns "Chai, Chang, Tofu"
string result = table.AsEnumerable().ToDelimitedString(row => (string)row["ProductName"]);

 

Technorati Tags: ,

LINQ and Expression Trees have enabled a ton of possibilities for us as developers, particularly in establishing some code-reducing convention based querying. I have found myself playing with Expressions in C# since their inception and will hopefully be publishing a few other posts I have queued up. For now, this post will simply demonstrate how to take advantage of a popular convention whereby each database table always has a single integer primary key named “Id”

By taking advantage of this primary key convention I can save myself a ton of boilerplate code to query a table by ID.

The Extension Method

public static T GetById<T>(this IQueryable<T> query, int id) where T : class
{
    // Create lambda parameter x of type T
    var param = Expression.Parameter(typeof(T), "x");

    // Given x param, extract the Id property
    var memberExpression = Expression.Property(param, "Id");

    // Build Lambda expression
    // x => x.Id == id
    var whereClause =
        Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                memberExpression,
                Expression.Constant(id)
                ), param);

    return query.Single(whereClause);
}

Usage

NorthwindDataContext db = new NorthwindDataContext();
var product = db.Products.GetById(1);
var order = db.Orders.GetById(15);