Use extension methods to let your enums hold the logic.

I often stumble upon code checking values on enumerations to determine the state of some object or rule. At best, this code is extracted and put in a helper or utils class of some sort. Don’t! Use extension methods instead. It let’s you provide a name for the condition (rule) that you are checking, and it put’s it together with the enumeration.

Example
Lets say I have an enumeration with storage providers. Each provider might be able to store data virtually, hence I need the possibility of determining if it’s capable of this.

[Serializable]
public enum StorageProviders
{
    LuceneIo = 0,
    LuceneVirtual = 1
}

public static class StorageProvidersExtensions
{
    public static bool IsVirtual(this StorageProviders provider)
    {
        return provider == StorageProviders.LuceneVirtual;
    }
}

I can now act on the enumeration value it self.

...connectionInfo.ProviderType.IsVirtual()...

//Daniel

How-to write tests for extension methods without Typemock

Ok, I’m not a happy owner of Typemock, hence I can’t use it to mock extension methods.

I will show you two really simple workarrounds for achieving this.

I have some simple extension methods that extends IQueryable. One of the extensions is responsible for checking if a certain username allready is taken.
The extension method

public static bool UsernameIsTaken(this IQueryable<UserAccount> userAccounts, string username)
{
    return
        userAccounts.Where(
            u =>
            u.Username.Equals(username, StringComparison.InvariantCultureIgnoreCase)).Count() > 0;
}

As I’m using the Moq-framework for setting up my fakes (in this case stub, see earlier post) I will get an exception.

The test as I want it (which doesn’t work) looks like this

[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    var userAccountStoreStub = Fake.Stub.New<IQueryable<UserAccount>>();
    Fake.Stub.Returns(userAccountStoreStub, stub => stub.UsernameIsTaken(userAccount.Username), true);

    var validator = new NewUserAccountValidator(userAccountStoreStub);
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

This stub is fairly simple to replace manually. All I need is a generic List of UserAccount that contains an instance of an useraccount that has the same username as the username I’m validating.

Solution 1 – Setup a generic list and pass it as IQueryable

[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    var userAccountStoreStub = new List<UserAccount>
                                   {
                                       UserAccountFactoryForTests.CreateValidUserAccount()
                                   }.AsQueryable();
    
    var validator = new NewUserAccountValidator(userAccountStoreStub);
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

This time I was lucky, since the extension method was on the IQueryable, but what if it was something that is totally custom? Just let the extension method consume something that you can stub. In this case, e.g., a Func (see Daniel Cazzulino’s blog).

Solution 2 – Let the extension method consume something you can stub

public static class UserAccountQueries
{
    public static Func<IQueryable<UserAccount>, string, bool> userNameIsTaken = (userAccounts, username) =>
        userAccounts.Where(
                u =>
                u.Username.Equals(username, StringComparison.InvariantCultureIgnoreCase)).Count() > 0;

    public static bool UsernameIsTaken(this IQueryable<UserAccount> userAccounts, string username)
    {
        return userNameIsTaken(userAccounts, username);
    }
}
[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    UserAccountQueries.userNameIsTaken = (stub, username) => true;

    var validator = new NewUserAccountValidator(new List<UserAccount>().AsQueryable());
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

In my scenario I used solution 1, but in the future I will probably refactor away my code from the extension methods.

//Daniel

Extend IQueryable instead of a certain dataprovider – more decoupled code

This is going to be a real short post and is more of an update to my last post (Entity validaton using Custom Data Annotation attributes) then a new one. I have made two small technical changes and with these small changes I have gained a more decoupled code.

Change One
Instead of having a helper method in my service base class I have put it in the entity store. This due to the fact that the validation is mere simple datavalidation and is pure validation of the entity’s state. Custom validation logic is still in my services but this logic is injected to the validation method in the entity store, via a Func<>.

Change Two
I don’t make use of repositories anymore. Instead I have a generic entity store that can handle whichever entity you pass to it, as long as you have provided mapping information about the entity. But what if I want to have “Named queries”, e.g GetAllUsersThatAreBlocked? In this case, I don’t create a custom implementation of my entity store by inheriting the generic implementation and creates the function “GetAllUsersThatAreBlocked”. No, I use my generic implementation that lets me get an IQueryable<T>, which I then extend. In my previous post I extended the entity store, which was really ugly. This new solution decouples my queries from the entity store and gives me the opportunity to execute the queries against any source that can provide me an IQueryable<T>.

The validation
The code below shows a Service-method and how it calls the ValidateEntity-method (which now is placed in the EntityStore).

public ServiceResponse<UserAccount> SetupNewUserAccount(UserAccount userAccount)
{
    var validationResult = EntityStore.ValidateEntity<UserAccount>(userAccount, CustomValidationForSettingUpNewAccount);
    var serviceResponse = new ServiceResponse<UserAccount>(userAccount, validationResult);
    
    if (!serviceResponse.ValidationResult.HasViolations)
    {
        EntityStore.AddEntity(userAccount);
        EntityStore.SaveChanges();
    }

    return serviceResponse;
}

private IEnumerable<ValidationResult> CustomValidationForSettingUpNewAccount(UserAccount userAccount)
{
    var violations = new List<ValidationResult>();
    var emailIsTaken = EntityStore.Query<UserAccount>().EmailIsTakenByOther(userAccount.Username, userAccount.Email);

    if (emailIsTaken)
        violations.Add(new ValidationResult("Email is allready taken."));

    return violations;
}

The ValidateEntityMethod is as before. Where it uses a EntityValidator that I have written about before. To perform custom validation you can pass in a Func<> which is done above, where I pass a pointer to method “CustomValidationForSettingUpNewAccount” in my service. This function only ensures that the email isn’t allready in use.

public EntityValidationResult ValidateEntity<T>(T entity, Func<T, IEnumerable<ValidationResult>> customValidation = null)
    where T : IEntity
{
    Func<T, bool, IEnumerable<ValidationResult>> customValidationProxy = null;

    if (customValidation != null)
        customValidationProxy = (e, isValid) => isValid ? customValidation(e) : null;

    return new EntityValidator<T>().Validate(entity, customValidationProxy);
}

Named queries as extensions to IQueryable<T>
The extension code is the same as in earliear post except that I now extend IQueryable instead of EfEntityStore and can hook on the where clause directly on the injected queryable. A verry little syntax change but a tremendous architechtural change since, the query extension now has no dependency to a certain implementation technique.

namespace Sds.Christmas.Storage.Queries.UserAccounts
{
    public static class UserAccountQueries
    {
        public static bool EmailIsTakenByOther(this IQueryable<UserAccount> userAccounts, string username, string email)
        {
            return
                userAccounts.Where(
                    u =>
                        u.Username.Equals(username, StringComparison.InvariantCultureIgnoreCase) &&
                        u.Email.Equals(email, StringComparison.InvariantCultureIgnoreCase)).Count() > 0;
        }
    }
}

As always, there’s a complete sample project available for download.

Enjoy!

//Daniel