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);
}
}
}