Шаблон Provider


    public class KeyAttribute : Attribute
    {
        public KeyAttribute(string key)
        {
            Key = key;
        }
        public string Key { get; }
    }
    public interface IProvider<TItem>
    {
        TItem Get(string key);
        void Bind(string key, TItem item);
        void Unbind(string key);
    }
    public abstract class BaseProvider<TItem>: IProvider<TItem>
    {
        protected Dictionary<string, TItem> _items = new Dictionary<string, TItem>();

        public BaseProvider(IEnumerable<TItem> items)
        {
            BindByKeyAttribute(items);
        }

        public virtual TItem Get(string key)
        {
            if (_items.ContainsKey(key))
            {
                return _items[key];
            }
            return default(TItem);
        }

        protected void BindByKeyAttribute(IEnumerable<TItem> items)
        {
            if (items == null)
                return;

            foreach (var item in items)
            {
                var attr = item.GetType().GetCustomAttributes(true).OfType<KeyAttribute>().FirstOrDefault();
                if (attr == null)
                    continue;
                Bind(attr.Key, item);
            }
        }

        public virtual void Bind(string key, TItem item)
        {
            _items.Add(key, item);
        }

        public virtual void Unbind(string key)
        {
            _items.Remove(key);
        }

        public void Clear()
        {
            _items.Clear();
        }
    }

Используем так:

    public class ItemsProvider : BaseProvider<Item>
    {
        public ItemsProvider(IEnumerable<Item> items)
            : base(items)
        {
        }
    }
    public abstract class Item {}
    public class Item1: Item {}
    public class Item2: Item {}

    var item1 = new Item1();
    var items = new Item<string>[] { item1 };
    var itemsProvider = new ItemsProvider<string>(items);

    var item2 = new Item2();
    itemsProvider.Bind("key2", item2);

    Item aItem1 = itemsProvider.Get("key1");
    Item aItem2 = itemsProvider.Get("key2");