Tuesday, March 3, 2015

Changing TransactionScope - Timeout at runtime

So... TransactionScope...

If you have worked with the TransactionScope in the past you might have noticed that it can be tricky, and even dangerous if you don't use it correctly.

So anyways, I have tried to change the TransactionScope timeout property at runtime and the thing still goes back to the default timeout of 10 minutes.

This is because the 'TransactionScope' uses the following object to get the maximum timeout for a transaction: TransactionManager.MaximumTimeout. If you decompile it you will see the following:

if (!TransactionManager._cachedMaxTimeout)
{
  lock (TransactionManager.ClassSyncObject)
  {
    if (!TransactionManager._cachedMaxTimeout)
    {
      TransactionManager._maximumTimeout = TransactionManager.MachineSettings.MaxTimeout;
      TransactionManager._cachedMaxTimeout = true;
    }
  }
}

Pay special attention to: TransactionManager.MachineSettings.MaxTimeout

It always reads from the machine settings defined on the machine.config (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config)

And this specific section is defined as follows:

<sectionGroup name="system.transactions" type="System.Transactions.Configuration.TransactionsSectionGroup, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null">
   <section name="defaultSettings" type="System.Transactions.Configuration.DefaultSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/>
   <section name="machineSettings" type="System.Transactions.Configuration.MachineSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null" allowDefinition="MachineOnly" allowExeDefinition="MachineOnly"/>
</sectionGroup>

Note that it's marked with: allowExeDefinition="MachineOnly" that's why we cannot override it in our config files - shame :(

So basically I can think in two options to increase the maximum transaction timeout:

Updating the machine.config file

You could do it although I wouldn't recommend it so I won't bother to show you how... well take a quick look

Hacking - using reflection

Or do it the Ninja way...

private void ConfigureTransactionTimeout(TimeSpan value)
{
    //initializing internal stuff
    // ReSharper disable once NotAccessedVariable
    var timespan = TransactionManager.MaximumTimeout;

    //initializing it again to be sure
    // ReSharper disable once RedundantAssignment
    timespan = TransactionManager.MaximumTimeout;

    SetTransactionManagerField("_cachedMaxTimeout", true);
    SetTransactionManagerField("_maximumTimeout", value);

    Condition.Ensures(TransactionManager.MaximumTimeout, "TransactionManager.MaximumTimeout").IsEqualTo(value);
}

private void SetTransactionManagerField(string fieldName, object value)
{
    var cacheField = typeof (TransactionManager).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static);

    Condition.Ensures(cacheField, "cacheField").IsNotNull();

    cacheField.SetValue(null, value);
}

And use it like:

ConfigureTransactionTimeout(TimeSpan.FromMinutes(20));

var timespan = TransactionManager.MaximumTimeout;

var transactionOptions = new TransactionOptions
{
    IsolationLevel = isolationLevel,
    Timeout = timespan
};

var ts = new TransactionScope(transactionScopeOption, transactionOptions);

There you go

Monday, March 2, 2015

Testing Ninject container

I've found really useful to test our IoC container to make sure that all the components that are registered can be resolved.

This is the way I usually test my Ninject container

The model

so let's say that we have the following model:

public interface ICommand { }

public interface ICommandHandler<in T> where T : ICommand
{
    void Handle(T command);
}

public class DeploySqlScriptsUsingAGlobalTransactionCommand : ICommand
{
    public DeploySqlScriptsUsingAGlobalTransactionCommand(IEnumerable<string> scripts)
    {
        Scripts = scripts;
    }

    public IEnumerable<string> Scripts { get; private set; }
}

public class DeploySqlScriptsUsingAGlobalTransactionCommandHandler :
    ICommandHandler<DeploySqlScriptsUsingAGlobalTransactionCommand>
{
    private readonly IScriptDeployerService _scriptDeployerService;

    public DeploySqlScriptsUsingAGlobalTransactionCommandHandler(IScriptDeployerService scriptDeployerService)
    {
        _scriptDeployerService = scriptDeployerService;
    }

    public void Handle(DeploySqlScriptsUsingAGlobalTransactionCommand command)
    {
        //shalalalalal
        command.Scripts.ToList().ForEach(_scriptDeployerService.Deploy);
        Console.WriteLine("Scripts deployed");
    }
}

public interface IScriptDeployerService
{
    void Deploy(string script);
}

Note that we don't have a concrete implementation of IScriptDeployerService

The test

So we create this test to make sure that the container is valid:

[TestMethod]
public void it_should_resolve_all_registered_components_in_the_container()
{
    #region Binding container

    var kernel = new StandardKernel();

    kernel.Bind(config =>
    {
        config.FromThisAssembly()
            .SelectAllClasses()
            .BindAllInterfaces();
    });

    ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(kernel));

    kernel.Bind<IServiceLocator>().ToConstant(ServiceLocator.Current); 

    #endregion

    #region Testing container

    var field = typeof (KernelBase).GetField("bindings",
        BindingFlags.Instance | BindingFlags.NonPublic);

    field.Should().NotBeNull();

    var bindingsMap = field.GetValue(kernel) as Multimap<Type, IBinding>;

    bindingsMap.Should().NotBeNull();
    bindingsMap.Should().NotBeEmpty();

    var locator = ServiceLocator.Current.GetInstance<IServiceLocator>();

    locator.Should().NotBeNull();

    bindingsMap.SelectMany(x => x.Value).ToList()
        .ForEach(binding => ServiceLocator.Current.Invoking(instance =>
        {
            var services = instance.GetAllInstances(binding.Service);

            services.Count().Should().BeGreaterOrEqualTo(1);

            if (services.Count() == 1)
            {
                instance.GetInstance(binding.Service);
            }
        }).ShouldNotThrow());

    #endregion
}

The error

When we run the test we receive the following error from Ninject:

Result Message: Did not expect any exception, but found Ninject.ActivationException with message "Error activating IScriptDeployerService No matching bindings are available, and the type is not self-bindable. Activation path: 2) Injection of dependency IScriptDeployerService into parameter scriptDeployerService of constructor of type DeploySqlScriptsUsingAGlobalTransactionCommandHandler 1) Request for ICommandHandler{DeploySqlScriptsUsingAGlobalTransactionCommand}

Very explicit

The fix

So now let's fix it:

Let's add the missing concrete implementation:

public class ScriptDeployerService : IScriptDeployerService
{
    public void Deploy(string script)
    {
        Console.WriteLine("Script deployed: {0}", script);
    }
}

The result

And now our test pass =) Awesome

Binding Decorators - Mediators with Ninject

So let's talk about Ninject and how to bind decorators, I will illustrate it decorating Command Handlers in a CQRS architecture

Using this pattern will allow you to follow the Single Responsibility Principle in your command handlers.

Why? Let's take a look

So a typical command handler will validate its command and to achieve this we have several options:

Inside the command

public class GrantAccessToNightClubCommandHandler : ICommandHandler<GrantAccessToNightClub>
{
    public void Handle(GrantAccessToNightClub command)
    {
        if (command.Age < 21)
        {
            throw new InvalidOperationException("Age was not satisfied");
        }

        //do stuff
    }
}

So I don't like this approach because the validation is lost inside the handlers take a look to Make roles explicit by Udi Dahan

So let's try another approach

Injecting validators into the command handler

public class GrantAccessToNightClubCommandHandler : ICommandHandler<GrantAccessToNightClub>
{
    private readonly IValdiatorRunner<GrantAccessToNightClub> _valdiatorRunner;

    public GrantAccessToNightClubCommandHandler(IValdiatorRunner<GrantAccessToNightClub> valdiatorRunner)
    {
        _valdiatorRunner = valdiatorRunner;
    }

    public void Handle(GrantAccessToNightClub command)
    {
        _valdiatorRunner.Run(command);
        //valid at this point

        //do stuff
    }
}

I won't go into detail about the IValidatorRunner implementation, but it loads dynamically validators for the specified command and runs them all

I used to like this technique since it provides a good separation of concerns, making the roles explicit but still... it looks like the command handler is doing too much, it's not following the SRP

Let's see the third option

Using Decorators

public class CommandHandlerValidator<TCommand> : ICommandHandler<TCommand> where TCommand : ICommand
{
    private readonly IEnumerable<IValdiator<TCommand>> _valdiators;
    private readonly ICommandHandler<TCommand> _commandHandler;

    public CommandHandlerValidator(
        IEnumerable<IValdiator<TCommand>> valdiators,
        ICommandHandler<TCommand> commandHandler)
    {
        _valdiators = valdiators;
        _commandHandler = commandHandler;
    }

    public void Handle(TCommand command)
    {
        _valdiators.ToList().ForEach(x => x.ApplyTo(command));
        // wow everything is valid here, lets continue
        _commandHandler.Handle(command);
    }
}

public class GrantAccessToNightClubCommandHandler : ICommandHandler<GrantAccessToNightClub>
{
    public void Handle(GrantAccessToNightClub command)
    {
        //do stuff
    }
}

Wow, now it looks like we are following the SRP therefore everything starts to look simpler and easier to maintain and extend. Just by following the SRP. Wow it blows my mind

Now imagine that we want to apply authorization to our command handlers, again we can solve this by decorating them like:

public class CommandHandlerAuthenticator<TCommand> : ICommandHandler<TCommand> where TCommand : ICommand
{
    private readonly ICommandHandler<TCommand> _commandHandler;

    public CommandHandlerAuthenticator(ICommandHandler<TCommand> commandHandler)
    {
        _commandHandler = commandHandler;
    }

    public void Handle(TCommand command)
    {
        Authenticate(command);
        //when authenticated simply...
        _commandHandler.Handle(command);
    }

    private void Authenticate(TCommand command)
    {
        // some authentication
    }
}

Now the trick is to inject the Decorators. I'm a big fan of Ninject so I will show you how to do it the Ninja style.

You need to define the injectors in the order that you want them, if you take a closer look to the previous code again, we have not specified what concrete command handler is going to be injected into the CommandHandlerValidator or the CommandHandlerAuthenticator. All we've defined is that a ICommandHandler will be injected somehow.

All this configuration will be done via our container. It's awesome

//we bind everythig except our command handlers since we will treat them as decorators
kernel.Bind(config =>
{
    config.From(fromTypes.Select(x => x.Assembly))
        .SelectAllClasses()
        .Where(x => !x.IsAssignableToGenericType(typeof(ICommandHandler<>)))
        .BindAllInterfaces();
});

kernel.Bind(config =>
{
    config.From(fromTypes.Select(x => x.Assembly)).SelectAllClasses()
        .Where(x => x.IsAssignableToGenericType(typeof(ICommandHandler<>)))
        .BindAllInterfaces().Configure(x => x.WhenInjectedInto(typeof(CommandHandlerValidator<>)));
});
kernel.Bind(typeof(ICommandHandler<>)).To(typeof(CommandHandlerValidator<>))
    .WhenInjectedInto(typeof(CommandHandlerAuthenticator<>));
kernel.Bind(typeof(ICommandHandler<>)).To(typeof(CommandHandlerAuthenticator<>));

This code can be read as follows (from bottom to top):

  • When I ask an ICommandHandler give me CommandHandlerAuthenticator
  • Then when I'm injecting a CommandHandlerAuthenticator give me a CommandHandlerValidator
  • And finally, when I'm injecting a CommandHandlerValidator give me my ICommandHandler

It's tricky I know... but it works great

This code could be improved maybe creating an Extension Method to bind decorators.

So when you test it like this:

var guard = kernel.Get<ICommandHandler<GrantAccessToNightClub>>();

guard.Handle(new GrantAccessToNightClub("jp", 21));

This is the output:

Test Name:  TestMethod1
Test Outcome:   Passed
Result StandardOutput:  
Authenticating...
Valdiating: 21: Granted
Valdiation done, lets continue
Finally doing some work here...

Now the fun part, TEST IT

I don't know how to call this kind of test, I don't believe it's a unit test, integration test perhaps uhmm well I just call them Wiring tests

[TestMethod]
public void it_should_resolve_the_CommandHandlerDecorators()
{
    var kernel = new StandardKernel();

    var fromTypes = new[]
    {
        typeof (DecoratorTests)
    };

    //we bind everythig except our command handlers since we will treat them as decorators
    kernel.Bind(config =>
    {
        config.From(fromTypes.Select(x => x.Assembly))
            .SelectAllClasses()
            .Where(x => !x.IsAssignableToGenericType(typeof(ICommandHandler<>)))
            .BindAllInterfaces();
    });

    kernel.Bind(config =>
    {
        config.From(fromTypes.Select(x => x.Assembly)).SelectAllClasses()
            .Where(x => x.IsAssignableToGenericType(typeof(ICommandHandler<>)))
            .BindAllInterfaces().Configure(x => x.WhenInjectedInto(typeof(CommandHandlerValidator<>)));
    });
    kernel.Bind(typeof(ICommandHandler<>)).To(typeof(CommandHandlerValidator<>))
        .WhenInjectedInto(typeof(CommandHandlerAuthenticator<>));
    kernel.Bind(typeof(ICommandHandler<>)).To(typeof(CommandHandlerAuthenticator<>));

    var field = typeof(KernelBase).GetField("bindings",
        BindingFlags.Instance | BindingFlags.NonPublic);

    field.Should().NotBeNull();

    var bindingsMap = field.GetValue(kernel) as Multimap<Type, IBinding>;

    bindingsMap.Should().NotBeNull();
    bindingsMap.Should().NotBeEmpty();

    var commandHandlerBindings = bindingsMap.SelectMany(x => x.Value)
        .Where(x => x.Service.IsAssignableToGenericType(typeof(ICommandHandler<>))).ToList();

    commandHandlerBindings.Should().NotBeNullOrEmpty();

    commandHandlerBindings.Where(x => !x.Service.IsGenericTypeDefinition).ToList().ForEach(x =>
    {
        var handlers = kernel.GetAll(x.Service);

        foreach (var instance in handlers)
        {
            instance.GetType().IsAssignableToGenericType(typeof(CommandHandlerAuthenticator<>)).Should().BeTrue();

            // testing that the CommandHandlerValdiator was injected into CommandHandlerAuthenticator
            VerifyInnerCommandHandler(instance, x.Service, typeof (CommandHandlerValidator<>),
                typeof (CommandHandlerAuthenticator<>));

            var innerCommandHandler = instance.GetType().GetField("_commandHandler",
                BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance);

            // testing that the ICommandHandler was injected into CommandHandlerValdiator
            VerifyInnerCommandHandler(innerCommandHandler, x.Service, typeof (ICommandHandler<>),
                typeof (CommandHandlerAuthenticator<>), typeof (CommandHandlerValidator<>));
        }
    });
}

private void VerifyInnerCommandHandler(object instance, Type service, Type expectedType, params Type[] notExpectedTypes)
{
    var innerHandlerField = instance.GetType().GetField("_commandHandler",
        BindingFlags.Instance | BindingFlags.NonPublic);
    innerHandlerField.Should().NotBeNull();
    var innerHandler = innerHandlerField.GetValue(instance);

    innerHandler.GetType().IsAssignableToGenericType(expectedType).Should().BeTrue();

    foreach (var notExpectedType in notExpectedTypes)
    {
        innerHandler.GetType().IsAssignableToGenericType(notExpectedType).Should().BeFalse();
    }

    Console.WriteLine("{0} should be: {1}", innerHandler.GetType(), service);
    service.IsInstanceOfType(innerHandler).Should().BeTrue();
    service.IsAssignableFrom(innerHandler.GetType()).Should().BeTrue();
    innerHandler.GetType().IsAssignableToGenericType(expectedType).Should().BeTrue();
}

Ohh almost forgot, I'm using the following Type extension: IsAssignableToGenericType

There you go

Hope you have enjoyed it