Способы создания экземпляра наследника класса в зависимости от данных

a4221bec572b02cf8496aae464aa77b4

У нас есть табличка в базе данных с поставщиками, каждому поставщику соответствует класс обработчика, который является наследником от базового класса. Надо сделать генератор для создания обработчиков.

В голову пришло три способа организации:

  1. switch … case

  2. Добавить в табличку столбец и туда поместить постфиксы, дальше создавать объект на осное имени наследника, который должен включать этот постфикс

  3. Поместить индекс в атрибут класса-наследника и создавать объект, используя это значение

Первый способ:

    public class parcerA: ParcerBace {}

    public class parcerB: ParcerBace {}

    public abstract class ParcerBace
    {
        switch (id)
        {
          case 1: return new parcerA();
          case 2: return new parcerB();
        }
        return null;
    }

Дешево и сердито, но если этих обработчиков много, то мы получаем длинную простыню

Второй способ:

    public class parcerA: ParcerBace {}

    public class parcerB: ParcerBace {}

    public abstract class ParcerBace
    {
        public static ParcerBace creator(string postfix)
        {
            Type tFind = typeof(ParcerBace);
            Type tR = Assembly.GetAssembly(tFind).GetTypes().FirstOrDefault(t => t.IsSubclassOf(tFind) && t.Name== "parcer" + postfix);
            if (tR != null) return (ParcerBace)Activator.CreateInstance(tR);
            return null;
        }
    }

Тут довольно короткий код, но требуется следить за соответствием этих постфиксов в базе и наименованием объектов, что порождает ошибки

Третий способ:

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class IDAttribute : Attribute
    {
        public IDAttribute(int id) 
        {
            this.id = id;
        }
        public int id { get; set; }
    }

    [ID(1)]
    public class parcerA :ParcerBace {}

    [ID(2)]
    public class parcerB : ParcerBace {}

    public abstract class ParcerBace
    {
        public static ParcerBace creator(int id)
        {
            Type tFind = typeof(ParcerBace);
            Type tR = Assembly.GetAssembly(tFind).GetTypes().FirstOrDefault(t => t.IsSubclassOf(tFind) && (t.GetCustomAttribute(typeof(IDAttribute)) as IDAttribute).id == id);
            if (tR != null) return (ParcerBace)Activator.CreateInstance(tR);
            return null;
        }
    }

А вам какой способ кажется более удобным? Может есть более удобный способ?

© Habrahabr.ru