c # Перехватить параметры конструктора - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь написать систему очередей заданий, используя C #.

Предположим, у меня есть следующий класс, который представляет задание, которое нужно выполнить позже:

  public class TestJob : QueuableJob
    {
        private readonly string _t;
        private readonly string _e;
        public TestJob(string t, string e)
        {
            _t = t;
            _e = e;

        }
        public Task PerformWork(ITestService testService)
        {
            testService.Message($"Hello: {_t} {_e}");
            return Task.CompletedTask;
        }
    }

Я хотел бы иметь возможность назвать что-то вроде:

JobQueueService.EnqueueJob(new TestJob("value1", "value2"));

Чтобы поставить в очередь задание, мне нужно сериализовать параметры, переданные конструктору TestJob, чтобы я мог сохранить их на постоянном уровне (например, в базе данных) и затем десериализовать их. Затем я могу создать экземпляр класса и выполнить PerformWork. Я хотел бы как можно проще справиться с этим в моей библиотеке, чтобы конечный пользователь, пишущий свои классы "Job", не заботился о добавлении определенных вещей для сериализации.

Я не могу найти способ «перехватить» параметры, передаваемые классу TestJob, без потери строгой типизации (например, я мог бы использовать params object[] parameters) или без принуждения конечного пользователя реализовать какой-то другой код, чтобы помочь с сериализации.

В настоящее время самое элегантное решение, которое я могу придумать (для конечного пользователя), выглядит примерно так:

public class TestJob : QueuableJob
    {
        private readonly string _t;
        private readonly string _e;
        public TestJob(string t, string e) : base(t,e)
        {
            _t = t;
            _e = e;

        }
        public Task PerformWork(ITestService testService)
        {
            testService.Message($"Hello: {_t} {_e}");
            return Task.CompletedTask;
        }
    }

Однако для этого необходимо, чтобы разработчик не забывал передавать все свои параметры в base () (как base(t,e) в приведенном выше примере). Компилятор не будет жаловаться, если они забудут это сделать, так что это может быть источником хитрых ошибок. Я также пытался получить информацию, используя System.Diagnostics.StackTrace в конструкторе QueuableJob, однако не уверен, что смогу получить значения параметров из стека.

Можно ли как-нибудь использовать отражение, чтобы "перехватить" то, что передается в конструктор TestJob?

1 Ответ

0 голосов
/ 13 марта 2019

Я не уверен, что думаю, что это лучший способ решить проблему, но, поскольку вы знаете об этой проблеме больше, чем я, вот способ получить имена параметров конструктора для типа:

var constructors = typeof(TestJob).GetConstructors();
var constructor = constructors[0];
foreach (var param in constructor.GetParameters())
{
    Console.WriteLine($"Argument: {param.Position} is called {param.Name} and is a {param.ParameterType}");
}

Аналогично, вы можете использовать отражение, чтобы получить значения во время выполнения, и использовать Activator.CreateInstance, чтобы снова создать экземпляр объекта.

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