samedi 25 septembre 2021

Pattern guidance serialised DTO and Generics

I am looking for some pointer into best pattern regarding the following objective.

I have multiple services that I would like to send Jobs but will contain meta data that will form separate object DataObject. I am thinking the following

public enum JobType
{
    Job1 = 0,
    Job2 = 1,
    Job3 = 2
}

public class BaseJob
{
    /// <summary>
    /// Unique id maybe a guid
    /// </summary>
    public string Id { get; set; }
}


public interface IJob<T>
{
    /// <summary>
    /// Enumeration of a type of job 
    /// </summary>
    JobType Job { get; set; }

    /// <summary>
    /// Serialized object JsonConvert.SerializeObject(data);
    /// </summary>
    string DataObject { get; set; }
    
    /// <summary>
    /// DeSerialized object of Type T;
    /// </summary>
    T Object { get; }

    /// <summary>
    /// Unique id maybe a guid
    /// </summary>
    string Id { get; set; }

    /// <summary>
    /// Create the job object natively
    /// </summary>
    /// <param name="data"></param>
    void SetJobInfo(T data);
}

public class Job<T>: BaseJob, IJob<T>
{
    /// <inheritdoc/>
    public JobType Job { get; set; }

    /// <inheritdoc/>
    public string DataObject { get; set; }

    [JsonIgnore]
    public T Object => JsonConvert.DeserializeObject<T>(DataObject);

    /// <inheritdoc/>
    public void SetJobInfo(T data)
    {
        DataObject = JsonConvert.SerializeObject(data);
    }
}

I can use Factory method to create relevant Jobs from one micro-service, but how would I check what the type is from another service. I am trying to not have logic in multiple places if possible.

What is the best way to define T in the Job type for when I deserialise the DataObject from the Job DTO?

public void GetJob(IJob<dynamic> job)
{
    switch (job.Job)
    {
       case JobType.Job1:
           // How do I get the T of the object
           var object1 = job.Object;

           // I would like to use T to do something..

           break;
        case JobType.Job2:
           break;
       case JobType.Job3:
           break;
       default:
           throw new ArgumentOutOfRangeException(nameof(job), job, null);
     }
}

Thanks

Aucun commentaire:

Enregistrer un commentaire