Expanding on Mehdi Gholam's solution, here is a real-life example of where the method
ProcessFileType
"discovers" the type of data that it needs to convert to, looks up the type of data, then executes the conversion from JSON string and returns a class structure of a specific type.
private readonly Dictionary<string, Func<JObject, File>> mimeTypes
= new Dictionary<string, Func<JObject, File>>
{
{ "application/vnd.google-apps.folder", Convert<Folder>() },
{ "image/jpeg", Convert<JpgImage>() },
{ "image/png", Convert<PngImage>() },
{ "application/zip", Convert<Zipped>() },
{ "application/x-zip-compressed", Convert<Zipped>() },
{ "video/mp4", Convert<Mp4Video>() },
{ "text/plain", Convert<TxtDocument>() },
{ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
Convert<PptDocument>() },
{ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
Convert<WordDocument>() }
};
private void ProcessFileType(List<File> results, IList<JObject> jObjs, int i)
{
var fileToken = jObjs[i].FindTokens("mimeType");
if (fileToken != null && fileToken.Count > 0)
{
var key = mimeTypes.Keys.FirstOrDefault(x => x.Equals(fileToken[0].ToString()));
if (key != null)
{
results.Add(mimeTypes[key](jObjs[i]));
}
}
}
private static Func<JObject, File> Convert<TModel>() where TModel : File
{
return (jObj) => JsonHelper.ToClass<TModel>(jObj.ToString());
}
To do exactly the same thing slower using Reflection, it would look something like this:
public JsonDataTypeConverter()
{
if (convert == null)
convert = GetType().GetMethod(nameof(Convert),
BindingFlags.Instance | BindingFlags.NonPublic);
}
private static MethodInfo convert;
private static readonly Dictionary<string, Type> mimeTypes = new Dictionary<string, Type>
{
{ "application/vnd.google-apps.folder", typeof(Folder) },
{ "image/jpeg", typeof(JpgImage) },
{ "image/png", typeof(PngImage) },
{ "application/zip", typeof(Zipped) },
{ "application/x-zip-compressed", typeof(Zipped) },
{ "video/mp4", typeof(Mp4Video) },
{ "text/plain", typeof(TxtDocument) },
{ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
typeof(PptDocument) },
{ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
typeof(WordDocument) }
};
private void ProcessFileType(List<File> results, IList<JObject> jObjs, int i)
{
var fileToken = jObjs[i].FindTokens("mimeType");
if (fileToken != null && fileToken.Count > 0)
{
var key = mimeTypes.Keys.FirstOrDefault(x => x.Equals(fileToken[0].ToString()));
if (key != null)
{
var method = convert.MakeGenericMethod(new[] { mimeTypes[key] });
var data = method.Invoke(this, new[] { jObjs[i] });
results.Add((File)data);
}
}
}
private TModel Convert<TModel>(JObject jObj) where TModel : IResourceKind
{
return JsonHelper.ToClass<TModel>(jObj.ToString());
}
If you want to see the code in action, you can download it from this article:
Working with JSON in C# & VB[
^] (Google Drive - File Explorer example)