OneTrueError - Automated exception handling

Simplified autofac registrations

I’m building an application which will monitor other applications (memory using, start them if they crash etc). I’m trying to stop re-inventing the wheel (ohhh it’s fun to do everything yourself) and start using other components. This time I needed a IoC container and autofac seemed like a good match for me.

To simplify IoC registration I created an attribute which I use on all my components. In this way I don’t have to remember to register each component, it’s done by the help of the attribute.

Using the attribute without constructor parameters will register the component with all interfaces.

    [Component]
    class MyComponent : IConsumer<MonitorEvent>, ISomeService
    {
        //[....]
    }

While using the constructor will only register one interface.

    [Component(typeof(ISomeService)]
    class MyComponent : IConsumer<MonitorEvent>, ISomeService
    {
        //[....]
    }

The autofac registration looks like this:

    internal class Program
    {
        public static IContainer Components { get; private set; }

        private static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            //i = interface type, c = concrete type
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            assemblies.Each(assembly => assembly.FindComponents((i, c) => builder.RegisterType(c).As(i).SingleInstance()));

            Components = builder.Build();
        }
    }

Quite smooth, huh?

Extension methods making it possible:

public static class ComponentFinder
    {
        public static void Each<T>(this IEnumerable<T> enumerable, Action<T> action)
        {
            foreach (T item in enumerable)
                action(item);
        }

        public static void FindComponents(this Assembly assembly, Action<Type, Type> action)
        {
            Type componentAttribute = typeof (ComponentAttribute);
            foreach (Type type in assembly.GetTypes())
            {
                object[] attributes = type.GetCustomAttributes(componentAttribute, false);
                if (attributes.Length == 0)
                {
                    type.GetInterfaces().Each(i => action(i, type));
                    continue;
                }

                foreach (object attribute in attributes)
                {
                    Type interfaceType = ((ComponentAttribute) attribute).InterfaceType ?? type;
                    action(interfaceType, type);
                }
            }
        }
    }

Getting components is done by the resolve method:

Program.Components.Resolve<IMyService>.SendMessage("Hello world");
This entry was posted in Architecture and tagged , . Bookmark the permalink.