Skip to content

Instantly share code, notes, and snippets.

@zivillian
Last active August 11, 2019 20:04
Show Gist options
  • Select an option

  • Save zivillian/f9a854a4ccbcb7e530e6980cc9ad7b73 to your computer and use it in GitHub Desktop.

Select an option

Save zivillian/f9a854a4ccbcb7e530e6980cc9ad7b73 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using Simple.OData.Client;
public class ODataDerivedTypeCustomConverter
{
private static readonly string AnnotationKey = "__annotations";
private readonly Type _baseType;
private readonly Type[] _derivedTypes;
private ODataDerivedTypeCustomConverter(Type baseType, params Type[] derivedTypes)
{
_baseType = baseType;
_derivedTypes = derivedTypes;
}
public static void Register<TBase, TDerived>() where TDerived:TBase where TBase:class
{
Register<TBase>(typeof (TDerived));
}
public static void Register<TBase, TDerived1, TDerived2>() where TDerived1 : TBase where TDerived2 : TBase where TBase : class
{
Register<TBase>(typeof(TDerived1), typeof(TDerived2));
}
public static void RegisterDerivedFromAssembly<TBase>() where TBase:class
{
var baseType = typeof(TBase);
var derived = baseType.Assembly.GetTypes().Where(x => baseType.IsAssignableFrom(x)).ToArray();
Register<TBase>(derived);
}
public static void Register<TBase>(params Type[] derivedTypes) where TBase : class
{
var baseType = typeof(TBase);
foreach (var type in derivedTypes)
{
if (!baseType.IsAssignableFrom(type))
throw new ArgumentException(String.Format("Type '{0}' is not derived from '{1}'", type.FullName, baseType.Name));
}
Register(new ODataDerivedTypeCustomConverter(baseType, derivedTypes));
}
private static void Register(ODataDerivedTypeCustomConverter converter)
{
CustomConverters.RegisterTypeConverter(converter._baseType, converter.HandleConvert);
}
protected object HandleConvert(IDictionary<string, object> arg)
{
if (arg.ContainsKey(AnnotationKey))
{
var annotations = arg[AnnotationKey] as ODataEntryAnnotations;
if (!String.IsNullOrEmpty(annotations?.TypeName) && annotations.TypeName != _baseType.FullName)
{
var type = _derivedTypes.FirstOrDefault(x => x.FullName == annotations.TypeName);
if (type != null)
{
if (_baseType.IsAssignableFrom(type))
return arg.ToObject(type);
}
}
}
return arg.ToObject(_baseType);
}
}
@weitzhandler
Copy link
Copy Markdown

Hi and thanks for sharing,
Looks like ToObject isn't implemented here, where is directed to or what does it do, does it return the newly created object?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment