LateBoundConcerns<TConcern>
Lifetime concern that works for components that don't have their actual type determined upfront
            
                using Castle.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
namespace Castle.MicroKernel.LifecycleConcerns
{
    [Serializable]
    public abstract class LateBoundConcerns<TConcern>
    {
        private IDictionary<Type, TConcern> concerns;
        private ConcurrentDictionary<Type, List<TConcern>> concernsCache;
        public bool HasConcerns => concerns != null;
        public void AddConcern<TForType>(TConcern lifecycleConcern)
        {
            if (this.concerns == null) {
                this.concerns = new Dictionary<Type, TConcern>(2);
                this.concernsCache = new ConcurrentDictionary<Type, List<TConcern>>(2, 2);
            }
            this.concerns.Add(typeof(TForType), lifecycleConcern);
        }
        public abstract void Apply(ComponentModel model, object component);
        private List<TConcern> BuildConcernCache(Type type)
        {
            List<TConcern> list = new List<TConcern>(concerns.Count);
            foreach (KeyValuePair<Type, TConcern> concern in concerns) {
                if (concern.Key.GetTypeInfo().IsAssignableFrom(type))
                    list.Add(concern.Value);
            }
            return list;
        }
        protected List<TConcern> GetComponentConcerns(Type type)
        {
            return concernsCache.GetOrAdd(type, BuildConcernCache);
        }
    }
}