As I am working on my Entity Framework extras project, I found myself needing to determine table name in the database based on class name used with DbSet in my context. I was unable to find a way to query entity framework for this information, so I resorted to brute force approach, having to query database based on class name or pluralized class name. I ready this blog post by Scott Hanselman about pluralization. However, this class has been made internal, and I could not use it directly. Having enough experience with reflection, I wrote a wrapper class that used internal class via reflection. This code will break if API changes, but the fix at that point should be trivial. The code of course is super easy, and looks as following:
public static class Pluralizer
{
private static object _pluralizer;
private static MethodInfo _pluralizationMethod;
public static string Pluralize(string word)
{
CreatePluralizer();
return (string)_pluralizationMethod.Invoke(_pluralizer, new object[] {word});
}
public static void CreatePluralizer()
{
if (_pluralizer == null)
{
Assembly aseembly = typeof(DbContext).Assembly;
var type =
aseembly.GetType(
"System.Data.Entity.ModelConfiguration.Design.PluralizationServices.EnglishPluralizationService");
_pluralizer = Activator.CreateInstance(type, true);
_pluralizationMethod = _pluralizer.GetType().GetMethod("Pluralize");
}
}
}
As you can see, I am loading assembly class by picking a random class from Entity Framework assembly, DbContext in my case. Then I am getting a type corresponding to English pluralization service. Once that is done, I am getting a handle of Pluralize method based on name.
Pretty easy, hah? Here is how I am testing (using) my new class:
[TestMethod]
public void PluralizationTest()
{
Assert.AreEqual("people", Pluralizer.Pluralize("person"));
Assert.AreEqual("people", Pluralizer.Pluralize("people"));
}
Ah, the magic of reflection!
Very nice !!!