Gareth Hughes

Gareth Hughes

goals, fitness, gaming, new-year, reading

I've set myself some goals for 2016. To make sure I don't forget them and to hold myself slightly accountable i'm going to post them there.

So here they are.

Read 10 books this year

Not really all that many but I'm quite lazy when it comes to reading. I want to read a few more books this year. (Plus audio books which I listen to quite a lot, Audible is awesome)

Do more development

I need to do some more freelance work or pet projects, this is something I've neglected in my time in Australia. Time to improve!

Clear some of my gaming backlog

My backlog is insane, if I ignore the games left over from the last gen and my steam collection that I can't play without buying a new gaming pc I still have loads of games I can play.

So far I've managed to finish Pillars of Eternity and Starcraft 2 campaign from my backlog.

Keep getting fitter

Last year was amazing for my fitness wise, I finally dropped into normal weight BMI and currently sitting at 78kg (down from 155kg in 2008 and about 95kg at the start of last year)

Get Permanent Residency

This is complicated by Miyuki's visa situation but hopefully buy the end of this year we will both be PR.

The previous domain events solution had Castle Windsor added in just to resolve dependences for the handler constructors (the original version didn't have this). So I figure I could just simplify this further and depend entirely on Castle.

public static class DomainEvent  
{
    private static IWindsorContainer _container;

    public static void Initialize(IWindsorContainer container, BasedOnDescriptor[] basedOnDescriptors)
    {
        _container = container;

        basedOnDescriptors.ForEach(d => _container.Register(d.WithServiceAllInterfaces().LifestylePerWebRequest()));
    }

    public static void RaiseAsync<TEvent>(TEvent eventToHandle) where TEvent : IDomainEvent
    {
        Handle<TEvent>(instance => Task.Factory.StartNew(() => instance.Handle(eventToHandle)));
    }

    public static void Raise<TEvent>(TEvent eventToHandle) where TEvent : IDomainEvent
    {
        Handle<TEvent>(instance => instance.Handle(eventToHandle));
    }

    private static void Handle<TEvent>(Action<IDomainEventHandler<TEvent>> func) where TEvent : IDomainEvent
    {
        if (_container == null) throw new Exception("Event Manager not initialized");

        _container.ResolveAll<IDomainEventHandler<TEvent>>().ForEach(func);
    }
}

To initialize this we pass an array of BasedOnDescriptor from the Application Bootstrapper. Triggering the events remains the same.

DomainEvent.Initialize(_container, new[] {Classes.FromAssemblyNamed("SomeAssembly.Library").InNamespace("SomeAssembly.Library.Handlers")});  

In the previous version the code which loaded all current assemblies and use reflection to find the handlers caused issues as we had a mess of nuget package versions in the solution and a lot of badly configured version redirects.

This is something I quickly knocked together for a simple domain events spike in C# using Castle Windsor. Simply load all event handlers on app startup, when handling an event we resolve those handlers with castle to resolve any dependencies the handler may have and fire the handlers.

public static class EventManager  
{
    private static IWindsorContainer _container;
    private static IEnumerable<Type> _handlers;
    private static readonly Type HandlerType = typeof (IEventHandler<>);

    public static void Initialize(IWindsorContainer container)
    {
        _container = container;

        _handlers = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(t => t.IsClass && IsAssignableToGenericType(t, HandlerType));

        _container.Register(Classes.From(_handlers).BasedOn(HandlerType).LifestylePerWebRequest());
    }

    public static void RaiseAsync<TEvent>(TEvent eventToHandle) where TEvent : IEvent
    {
        Handle<TEvent>(instance => Task.Factory.StartNew(() => instance.Handle(eventToHandle)));
    }

    public static void Raise<TEvent>(TEvent eventToHandle) where TEvent : IEvent
    {
        Handle<TEvent>(instance => instance.Handle(eventToHandle));
    }

    private static bool IsAssignableToGenericType(Type givenType, Type genericType)
    {
        var interfaceTypes = givenType.GetInterfaces();

        if (interfaceTypes.Any(it => it.IsGenericType && it.GetGenericTypeDefinition() == genericType))
            return true;

        if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
            return true;

        var baseType = givenType.BaseType;
        return baseType != null && IsAssignableToGenericType(baseType, genericType);
    }

    private static void Handle<TEvent>(Action<IEventHandler<TEvent>> func) where TEvent : IEvent
    {
        if (_container == null) 
            throw new Exception("Event Manager not initialized");

        var handlers = _handlers.Where(t => t.GetInterfaces()
                            .Contains(typeof(IEventHandler<TEvent>))).ToList();

        if (handlers.Count == 0) 
            throw new Exception(string.Format("No handler for {0} found", typeof(TEvent)));

        handlers.Select(handler => (IEventHandler<TEvent>)_container.Resolve(handler))
            .ForEach(func);
    }
}

public interface IEventHandler<in TEventType> where TEventType : IEvent  
{
    void Handle(TEventType eventToHandle);
}

public interface IEvent  
{
}

Then we simply invoke like this.

EventManager.Raise(new EventType { Something = "345" });  
EventManager.RaiseAsync(new EventType { Something = "345" });  

Some code borrowed from http://stackoverflow.com/questions/74616/how-to-detect-if-type-is-another-generic-type

japanese, travel, japan

Watashi wa san-gatsu ni Miyuki san to Kyoto ni ikimashita
わたしはさんがつにみゆきさんときょうとにいきました

Watashitachi wa Nijo-jo ni ikimashita
Atsukatta desu soshite omoshirokatta desu
わたしたちはにじょじょにいきました あつかったですそしておもしろかったです

Watashitachi wa kinkaku-ji ni ikimashita
totemo kirei deshita
nigiyaka deshita
わたしたちはきんかくじにいきました とてもきれいでした にぎやかでした

Watashitachi wa Kaiseki-ryori wo tabemashita
biiru wo nomimashita
oishikatta desu soshite takakatta desu
わたしたちは かいせきりょうりをたべました ビールをのみました おいしかったですそしてたかかったです

keeki wo tabemashita
koohii wo nomimashita
totemo tanoshikatta desu
ケーキをたべました コーヒーをのみました とてもたのしかったです