Универсальный класс с универсальными свойствами? - PullRequest
1 голос
/ 01 марта 2011

У меня есть сценарий, в котором у меня есть куча заданий, которые я планирую запускать в разное время, сами задания уже обрабатываются в общем, и это здорово. И у меня есть абстрактный класс BaseJob, который они все наследуют от того, что я использую для общих вещей (таких как jobPK, startTime, регистрация исключений, создание отчетов и т. Д.). Но помимо этого задания сильно различаются, они имеют разные свойства и связанные с ними данные, которые очень специфичны для них (я называю эти свойства JobDetails). Так, например:

JobDetails for Job1
-customerId int
-cost double
-sku string
-userDefinedProperties SomeCustomObjectType

JobDetails for Job2
-name string
-executionDate DateTime
-otherProperties SomeOtherCustomObjectType

В базовом классе я хотел бы иметь возможность хранить ссылку на эти JobDetails как можно более обобщенно (поэтому, другими словами, я не хочу просто сохранять его как объект), чтобы минимизировать накладные расходы на бокс / распаковка. Затем я хочу, чтобы класс BaseJob обрабатывал многие общие функциональные возможности, необходимые для приложения, поэтому, например, в случае сбоя задания я хочу сохранить его JobDetails в базе данных, чтобы его можно было перезапустить, я также хочу регистрировать любые ошибки, которые могли произойти с данной работой. Для этого мне нужно иметь возможность извлечь эти JobDetails и использовать их.

Похоже, мне нужно использовать универсальные .NET и иметь класс универсальных свойств, в которые я могу добавить что угодно, и мне не нужно беспокоиться о наборе текста. Какой лучший способ справиться с этим и сделать его эффективным и гибким?

Надеюсь, это понятно, спасибо за помощь

Ответы [ 2 ]

1 голос
/ 01 марта 2011

Вы можете заставить JobDetails реализовать интерфейс и позволить BaseJob иметь абстрактную ссылку на него. Затем в реальных заданиях вы реализуете абстрактную JobDetails с нужной вам реализацией. Затем позвольте интерфейсу JobDetails определить методы, с которыми BaseJob должен работать. Это небольшое изменение шаблона проектирования Template Method . Это будет выглядеть примерно так:

public interface IJobDetails {
    void DoSomeWork();
}

public abstract BaseJob {

    protected abstract IJobDetails JobDetails { get; set; }

    public ExecuteJob {
        //execute the job
        JobDetails.DoSomeWork();
    }
}

public Job1 : BaseJob {

    public Job1() {
        JobDetails = new ConcreteJobDetails();
    }

    protected override IJobDetails JobDetails { get; set; }
}
0 голосов
/ 01 марта 2011

Как насчет чего-то вроде ...

public abstract class JobBase<TDetails>
{
    private TDetails details;
    protected TDetails Details
    {
        get
        {
            if (details == null)
            {
                this.details = this.LoadDetails();
            }

            return this.details;
        }
    }

    protected virtual TDetails LoadDetails()
    {
        // Some kind of deserialization of TDetails from your DB storage.
    }
}

public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
    public class ExampleJobDetails
    {
        public string ExampleProperty { get; set; }
        public int AnotherProperty { get; set; }
    }
}

Вы бы хотели иметь таблицы для каждого типа, используемого в качестве TDetails, или одну большую таблицу на основе ключей / значений для всех них. Есть плюсы / минусы для обоих. Если вы супер параноик по поводу бокса, нет никаких причин, по которым TDetails не может быть ограничен и структурой.

Редактировать: Вернулось назад, вы хотите сохранить подробности о сбое. Как насчет ...

public abstract class JobBase<TDetails>
{
    protected TDetails Details { get; private set; }

    public JobBase()
    {
        this.Details = this.CreateDetails();
    }

    protected abstract TDetails CreateDetails();

    protected void SaveDetails()
    {
        // Generic save to database.
    }
}

public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
    public class ExampleJobDetails
    {
        public string ExampleProperty { get; set; }
        public int AnotherProperty { get; set; }
    }

    protected override ExampleJobDetails CreateDetails()
    {
        return new ExampleJobDetails() { ExampleProperty = "Hi.", AnotherProperty = 1 };
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...