diff --git a/Libraries/Esiur/Data/DataSerializer.cs b/Libraries/Esiur/Data/DataSerializer.cs index 940cdbf..b408dbf 100644 --- a/Libraries/Esiur/Data/DataSerializer.cs +++ b/Libraries/Esiur/Data/DataSerializer.cs @@ -380,9 +380,11 @@ public static class DataSerializer var typeDef = warehouse.GetLocalTypeDefByType(valueType); - var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode()); + //var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode()); + var intVal = Convert.ToInt32((Enum)value);//, (value as Enum).GetTypeCode()); - var ct = typeDef.Constants.FirstOrDefault(x => x.Value.Equals(intVal)); + //var ct = typeDef.Constants.FirstOrDefault(x => x.Value.Equals(intVal)); + var ct = typeDef.Constants.FirstOrDefault(x => Convert.ToInt32(x.Value) == intVal); if (ct == null) return new Tdu(TduIdentifier.Null, null, 0, null, null); @@ -718,8 +720,8 @@ public static class DataSerializer var all = DC.Combine(keysTdu, 0, (uint)keysTdu.Length, valuesTdu, 0, (uint)valuesTdu.Length); return new Tdu(TduIdentifier.Typed, all, (uint)all.Length, - new TruComposite(TruIdentifier.TypedMap, false, new Tru[] { kt, vt }, - value.GetType()), + new TruComposite(TruIdentifier.TypedMap, false, new Tru[] { kt, vt }, + value.GetType()), connection); @@ -864,7 +866,7 @@ public static class DataSerializer var rt = new List(); var record = (IRecord)value; - var recordTru = Tru.FromType(value.GetType(), warehouse) ; + var recordTru = Tru.FromType(value.GetType(), warehouse); TypeDef typeDef = null; @@ -882,6 +884,7 @@ public static class DataSerializer throw new Exception("Unsupported."); } + foreach (var pt in typeDef.Properties) { var propValue = pt.PropertyInfo.GetValue(record, null); diff --git a/Libraries/Esiur/Data/Tru.cs b/Libraries/Esiur/Data/Tru.cs index 2d397f6..c9c0a82 100644 --- a/Libraries/Esiur/Data/Tru.cs +++ b/Libraries/Esiur/Data/Tru.cs @@ -151,7 +151,7 @@ namespace Esiur.Data public abstract void SetNotNull(byte flag); - public abstract Type RuntimeType { get; protected set; } + public abstract Type RuntimeType { get; } //public Type? GetRuntimeType(Warehouse warehouse, string domain) //{ @@ -373,7 +373,9 @@ namespace Esiur.Data if (remoteAttr != null) { - var typeDef = warehouse.GetRemoteTypeDefByName(remoteAttr.Domains, remoteAttr.FullName); + var typeDef = warehouse.FindProxyTypeDef(remoteAttr.FullName, remoteAttr.Domains); + + return new TruTypeDef(nullable, typeDef); } else { diff --git a/Libraries/Esiur/Data/TruComposite.cs b/Libraries/Esiur/Data/TruComposite.cs index e876e1e..8d59578 100644 --- a/Libraries/Esiur/Data/TruComposite.cs +++ b/Libraries/Esiur/Data/TruComposite.cs @@ -11,14 +11,16 @@ namespace Esiur.Data { public Tru[] SubTypes; - public override Type RuntimeType { get; protected set; } + Type _runtimeType; + + public override Type RuntimeType => _runtimeType; public TruComposite(TruIdentifier identifier, bool nullable, Tru[] subTypes, Type? type) { Identifier = identifier; Nullable = nullable; SubTypes = subTypes; - RuntimeType = type; + _runtimeType = type; //_runtimeType = typeof(Tuple).MakeGenericType(subTypes.Select(x => x.RuntimeType).ToArray()); } diff --git a/Libraries/Esiur/Data/TruPrimitive.cs b/Libraries/Esiur/Data/TruPrimitive.cs index d335237..b5e1b0a 100644 --- a/Libraries/Esiur/Data/TruPrimitive.cs +++ b/Libraries/Esiur/Data/TruPrimitive.cs @@ -8,7 +8,9 @@ namespace Esiur.Data { public class TruPrimitive:Tru { - public override Type RuntimeType { get; protected set; } + Type _runtimeType; + + public override Type RuntimeType => _runtimeType; public override string ToString() { @@ -19,7 +21,7 @@ namespace Esiur.Data { Identifier = identifier; Nullable = nullable; - RuntimeType = type; + _runtimeType = type; } public override void SetNull(List flags) diff --git a/Libraries/Esiur/Data/TruTypeDef.cs b/Libraries/Esiur/Data/TruTypeDef.cs index f544b03..a6a7344 100644 --- a/Libraries/Esiur/Data/TruTypeDef.cs +++ b/Libraries/Esiur/Data/TruTypeDef.cs @@ -3,6 +3,7 @@ using Esiur.Protocol; using Esiur.Resource; using System; using System.Collections.Generic; +using System.Runtime.InteropServices.ComTypes; using System.Text; namespace Esiur.Data @@ -11,7 +12,22 @@ namespace Esiur.Data { public TypeDef? TypeDef; - public override Type RuntimeType { get; protected set; } + Type _runtimeType = null; + + public override Type RuntimeType => _runtimeType ?? UpdateRuntimeType(); + + + private Type UpdateRuntimeType() + { + if (TypeDef is LocalTypeDef localTypeDef) + _runtimeType = localTypeDef.DefinedType ?? typeof(EpResource); + else if (TypeDef is RemoteTypeDef remoteTypeDef) + { + _runtimeType = remoteTypeDef.ProxyType ?? typeof(object); + } + + return _runtimeType ?? typeof(object); + } public override void SetNull(List flags) { @@ -28,11 +44,7 @@ namespace Esiur.Data Nullable = nullable; TypeDef = typeDef; - if (typeDef is LocalTypeDef localTypeDef) - RuntimeType = localTypeDef.DefinedType ?? typeof(EpResource); - else if (typeDef is RemoteTypeDef remoteTypeDef) - RuntimeType = remoteTypeDef.ProxyType ?? typeof(IResource); - + UpdateRuntimeType(); } public override void SetNull(byte flag) diff --git a/Libraries/Esiur/Data/Types/RemoteTypeDef.cs b/Libraries/Esiur/Data/Types/RemoteTypeDef.cs index b6e5c43..6f06189 100644 --- a/Libraries/Esiur/Data/Types/RemoteTypeDef.cs +++ b/Libraries/Esiur/Data/Types/RemoteTypeDef.cs @@ -127,6 +127,35 @@ public class RemoteTypeDef:TypeDef // try to get proxy type od._proxyType = connection.Instance?.Warehouse?.TryGetProxyType(od.Kind, od.Domain, od.Name); + if (od._proxyType == null) + Console.WriteLine("Proxy type not found " + od.Name); + + if (od._proxyType != null) + { + Console.WriteLine("Updating : " + od.Name); + + // update PropertyInfo, MethodInfo, EventInfo, FieldInfo + // @TODO Check signature match as well, not only name, to avoid conflicts + + foreach (var prop in od.Properties) + prop.PropertyInfo = od._proxyType.GetProperty(prop.Name); + + foreach (var func in od.Functions) + func.MethodInfo = od._proxyType.GetMethod(func.Name); + + foreach (var evnt in od.Events) + evnt.EventInfo = od._proxyType.GetEvent(evnt.Name); + + foreach(var cons in od.Constants) + cons.FieldInfo = od._proxyType.GetField(cons.Name); + + + } + + // register in warehouse + // @TOOD check who is the initiator + connection.Instance?.Warehouse?.TryRegisterRemoteTypeDef(connection.RemoteDomain, od); + return od; } } diff --git a/Libraries/Esiur/Resource/Warehouse.cs b/Libraries/Esiur/Resource/Warehouse.cs index a1c9546..44d22d4 100644 --- a/Libraries/Esiur/Resource/Warehouse.cs +++ b/Libraries/Esiur/Resource/Warehouse.cs @@ -848,12 +848,20 @@ public class Warehouse return _remoteTypeDefs[domain].Values.FirstOrDefault(x => x.Name == typeName); } - public TypeDef GetProxyTypeDef(string domain, string typeName, TypeDefKind? typeDefKind = null) + public TypeDef FindProxyTypeDef(string typeName, string[] domains) { - if (!string.IsNullOrEmpty(domain) || !_remoteTypeDefs.ContainsKey(domain)) - return null; - sdcsdc - return _remoteTypeDefs[domain].Values.FirstOrDefault(x => x.Name == typeName); + // @TODO: this might cause problems if there are multiple remote type defs with the same name in different domains, we should find a way to handle this case, maybe by adding the domain to the type name or by adding a namespace to the proxy types. + foreach (var domain in domains) + { + if (!_remoteTypeDefs.ContainsKey(domain)) + continue; + + var typeDef = _remoteTypeDefs[domain].Values.FirstOrDefault(x => x.Name == typeName); + if (typeDef != null) + return typeDef; + } + + return null; } //public TypeDef GetRemoteTypeDefByType(Type type)