How can the BinarySerializer be configured, to use a SubtypeFactory instance which needs a constructor with parameters?
I have the following scenario in my application. In the first approach, only the deserialization would be required.
public enum MyDataType: UInt32
{
Datatype_Invalid = 0,
Datatype_Bool = 1,
Datatype_Byte = 2,
Datatype_Word = 3,
Datatype_DWord = 4,
Datatype_Float = 5,
Datatype_Int16 = 6,
Datatype_Int32 = 7,
Datatype_String = 8,
Datatype_Double = 9,
Datatype_Spline = 10
}
public interface IItemSubtype
{
}
public class ItemTypeByte : IItemSubtype
{
public byte Value { get; set; }
}
public class ItemTypeInt16 : IItemSubtype
{
public short Value { get; set; }
}
public class ItemTypeFloat : IItemSubtype
{
public float Value { get; set; }
}
public class ItemTypeDouble : IItemSubtype
{
public double Value { get; set; }
}
public class DefaultItemType : IItemSubtype
{
public byte[] Data { get; set; }
}
public class MyItemSubtypeFactory : ISubtypeFactory
{
private IDictionary<string, MyDataType> myDict;
// how to inject this constructor ???
public MyItemSubtypeFactory(IDictionary<string, MyDataType> dict)
{
myDict = dict;
}
public MyItemSubtypeFactory()
{
}
// will not be used, only deserialization is necessary at this point (maybe later)
public bool TryGetKey(Type valueType, out object key)
{
key = null;
return false;
}
public bool TryGetType(object key, out Type type)
{
MyDataType keyVal = 0;
bool keySuccess = myDict.TryGetValue((string)key, out keyVal);
switch (keyVal)
{
case MyDataType.Datatype_Byte:
type = typeof(ItemTypeByte);
break;
case MyDataType.Datatype_Int16:
type = typeof(ItemTypeInt16);
break;
case MyDataType.Datatype_Float:
type = typeof(ItemTypeFloat);
break;
case MyDataType.Datatype_Double:
type = typeof(ItemTypeDouble);
break;
case MyDataType.Datatype_Spline:
// complex data-type, to be implemented later
type = null;
return false;
default:
type = null;
return false;
}
return true;
}
}
public class MyClassWithItemSubtypeFactory
{
[FieldOrder(0)]
[FieldLength(4)]
public string Key { get; set; }
[FieldOrder(1)]
[ItemSubtypeFactory(nameof(Key), typeof(MyItemSubtypeFactory))]
[ItemSubtypeDefault(typeof(DefaultItemType))]
public List<IItemSubtype> Items { get; set; }
}
And the usage:
// how to inject it into the SubtypeFactory constructor ?
var dataTypeDictionary = new Dictionary<string, MyDataType>
{
{ "abc", MyDataType.Datatype_Byte },
{ "def", MyDataType.Datatype_Int16 },
{ "ghi", MyDataType.Datatype_Float }
};
var data = new byte[] { 97, 98, 99, 0, 17, 100, 101, 102, 0, 1, 12, 103, 104, 105, 0, 0x40, 0xb6, 0x66, 0x66 };
var deserData = binSer.Deserialize<MyClassWithItemSubtypeFactory>(data);
The actual BinarySerializer implementation for TypeNode has only the option to choose the default constructor
var subtypeFactoryAttribute = attributes.OfType<SubtypeFactoryAttribute>().SingleOrDefault();
if (subtypeFactoryAttribute != null)
{
SubtypeFactoryBinding = GetBinding(subtypeFactoryAttribute);
SubtypeFactory =
(ISubtypeFactory) subtypeFactoryAttribute.FactoryType.GetConstructor(Type.EmptyTypes)?.Invoke(null);
}
Maybe there is a possibility to call GetConstructors() to iterate the constructors and choose one of them according to some configuration. Or is it possible to inject somehow into the BinarySerializer an instance of the SubtypeFactory custom implementation?
How can the BinarySerializer be configured, to use a SubtypeFactory instance which needs a constructor with parameters? I have the following scenario in my application. In the first approach, only the deserialization would be required.
And the usage:
The actual BinarySerializer implementation for TypeNode has only the option to choose the default constructor
Maybe there is a possibility to call GetConstructors() to iterate the constructors and choose one of them according to some configuration. Or is it possible to inject somehow into the BinarySerializer an instance of the SubtypeFactory custom implementation?