Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In one of my questions I used a ValidationContext class that looked like this:

public class ValidationContext<TArg>
{
    public ValidationContext(TArg argument, string memberName)
    {
        Argument = argument;
        MemberName = memberName;
    }

    public TArg Argument { get; }

    public string MemberName { get; }

    public virtual ValidationContext<TArg> ThrowIf<TException>(Func<TArg, bool> predicate, params object[] args) where TException : Exception
    {
        if (predicate(Argument))
        {
            throw (TException)Activator.CreateInstance(typeof(TException), args);
        }
        return this;
    }
}

Nothing special there. Just a couple of properties and one simple method.

Later I decided to create another context class for unit testing so I derived it from the first one and the result was:

public class UnitTestingValidationContext<TArg> : ValidationContext<TArg>
{
    public UnitTestingValidationContext(TArg argument, string memberName)
        :base(argument, memberName)
    {
    }

    public override ValidationContext<TArg> ThrowIf<TException>(Func<TArg, bool> predicate, params object[] args)
    {
        try
        {
            base.ThrowIf<TException>(predicate, args);
            return this;
        }
        catch (Exception inner)
        {
            //throw new AssertFailedException
            throw new Exception("This is a test.", inner);
        }
    }
}

This one is very simple too. New here is the try/catch around the base.ThrowIf.

Then I was reading about design patterns and I thought this might be good opportunity to try out the decorator pattern. I'm not very fond of the general terminology like Component, ComponentDecorator, ConcreteDecorater and whatsoever. I'm never sure what is what so I wanted to use a real example for that.

First I created an interface:

public interface IValidationContext<TArg>
{
    TArg Argument { get; }
    string MemberName { get; }
    IValidationContext<TArg> ThrowIf<TException>(Func<TArg, bool> predicate, params object[] args)
        where TException : Exception;
}

and derived the first context from it:

public class ValidationContext<TArg> : IValidationContext<TArg>
{
    public ValidationContext(TArg argument, string memberName)
    {
        Argument = argument;
        MemberName = memberName;
    }

    public TArg Argument { get; }

    public string MemberName { get; }

    public IValidationContext<TArg> ThrowIf<TException>(Func<TArg, bool> predicate, params object[] args)
        where TException : Exception
    {
        if (predicate(Argument))
        {
            throw (TException)Activator.CreateInstance(typeof(TException), args);
        }
        return this;
    }
}

then I used the same interface for the other context but I pass the first context as a parameter to the second one:

public class UnitTestingValidationContext<TArg> : IValidationContext<TArg>
{
    private readonly IValidationContext<TArg> _context;

    public UnitTestingValidationContext(IValidationContext<TArg> context)
    {
        _context = context;
    }

    public TArg Argument => _context.Argument;

    public string MemberName => _context.MemberName;

    public IValidationContext<TArg> ThrowIf<TException>(Func<TArg, bool> predicate, params object[] args) 
        where TException : Exception
    {
        try
        {
            _context.ThrowIf<TException>(predicate, args);          
            return this;
        }
        catch (Exception inner)
        {
            //throw new AssertFailedException // does not work in linqpad
            throw new Exception("This is a test.", inner);
        }
    }
}

Would you say this is a correct implementation of the decorator pattern?

share|improve this question
    
I would say yes, it is. However, what exactly is the UnitTesingValidationContext for? The unit test fails also without that decorator. – JanDotNet Jun 15 at 7:54
    
@JanDotNet its purpose is to throw a different exception namely the AssertFailedException... at least that's what I believe unit-tests have to do. – t3chb0t Jun 15 at 8:57
    
Do you use the UnitTesingValidationContext only in unit tests or also in prodcution code? Could you pls add an example how to use it? – JanDotNet Jun 15 at 9:09
    
@JanDotNet the UnitTestingValidationContext is defined in a separate assembly (there is an example - one line - in my previous question here) that I add as reference in a unit test project. I wouldn't use it in production code because I requries the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll and I don't want to polute the production project with it. It's purpose is to use the same framework and extensions for normal validation and for unit testing. – t3chb0t Jun 15 at 10:27
    
@JanDotNet the only difference is that a normal validation is initialized with .Validate() and a test with .Test() all other validations stay the same and of course the unit test context throws the AssertFailedException with the original exception as the inner one. – t3chb0t Jun 15 at 10:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.