mirror of
				https://github.com/esiur/esiur-dotnet.git
				synced 2025-10-30 07:31:35 +00:00 
			
		
		
		
	Generics workaround
This commit is contained in:
		| @@ -284,7 +284,17 @@ public static class Codec | |||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             if (type.IsGenericType) |             if (Codec.ImplementsInterface(type, typeof(IResource))) | ||||||
|  |             { | ||||||
|  |                 var (hdr, data) = DataSerializer.ResourceComposer(valueOrSource, connection); | ||||||
|  |                 return TransmissionType.Compose(hdr, data); | ||||||
|  |             } | ||||||
|  |             else if (Codec.ImplementsInterface(type, typeof(IRecord))) | ||||||
|  |             { | ||||||
|  |                 var (hdr, data) = DataSerializer.RecordComposer(valueOrSource, connection); | ||||||
|  |                 return TransmissionType.Compose(hdr, data); | ||||||
|  |             } | ||||||
|  |             else if (type.IsGenericType) | ||||||
|             { |             { | ||||||
|                 var genericType = type.GetGenericTypeDefinition(); |                 var genericType = type.GetGenericTypeDefinition(); | ||||||
|                 if (genericType == typeof(List<>)) |                 if (genericType == typeof(List<>)) | ||||||
| @@ -327,16 +337,6 @@ public static class Codec | |||||||
|  |  | ||||||
|                 //} |                 //} | ||||||
|             }  |             }  | ||||||
|             else if (Codec.ImplementsInterface(type, typeof(IResource))) |  | ||||||
|             { |  | ||||||
|                 var (hdr, data) = DataSerializer.ResourceComposer(valueOrSource, connection); |  | ||||||
|                 return TransmissionType.Compose(hdr, data); |  | ||||||
|             } |  | ||||||
|             else if (Codec.ImplementsInterface(type, typeof(IRecord))) |  | ||||||
|             { |  | ||||||
|                 var (hdr, data) = DataSerializer.RecordComposer(valueOrSource, connection); |  | ||||||
|                 return TransmissionType.Compose(hdr, data); |  | ||||||
|             } |  | ||||||
|             else if (type.IsEnum) |             else if (type.IsEnum) | ||||||
|             { |             { | ||||||
|                 var (hdr, data) = DataSerializer.EnumComposer(valueOrSource, connection); |                 var (hdr, data) = DataSerializer.EnumComposer(valueOrSource, connection); | ||||||
|   | |||||||
| @@ -168,13 +168,11 @@ namespace Esiur.Data | |||||||
|  |  | ||||||
|         public RepresentationType?[] SubTypes = new RepresentationType[3]; |         public RepresentationType?[] SubTypes = new RepresentationType[3]; | ||||||
|  |  | ||||||
|         public static RepresentationType? FromType(Type type)//, bool forceNullable = false) |         public static RepresentationType? FromType(Type type)  | ||||||
|         { |         { | ||||||
|  |  | ||||||
|             var nullable = false;// = forceNullable; |             var nullable = false;  | ||||||
|   |   | ||||||
|             //if (!forceNullable) |  | ||||||
|             //{ |  | ||||||
|             var nullType = System.Nullable.GetUnderlyingType(type); |             var nullType = System.Nullable.GetUnderlyingType(type); | ||||||
|  |  | ||||||
|             if (nullType != null) |             if (nullType != null) | ||||||
| @@ -182,9 +180,30 @@ namespace Esiur.Data | |||||||
|                 type = nullType; |                 type = nullType; | ||||||
|                 nullable = true; |                 nullable = true; | ||||||
|             } |             } | ||||||
|             //} |  | ||||||
|  |  | ||||||
|             if (type.IsGenericType) |             if (type == typeof(IResource)) | ||||||
|  |                 return new RepresentationType(RepresentationTypeIdentifier.Resource, nullable); | ||||||
|  |             else if (type == typeof(IRecord) || type == typeof(Record)) | ||||||
|  |                 return new RepresentationType(RepresentationTypeIdentifier.Record, nullable); | ||||||
|  |             else if (type == typeof(Map<object, object>)) | ||||||
|  |                 return new RepresentationType(RepresentationTypeIdentifier.Map, nullable); | ||||||
|  |             else if (Codec.ImplementsInterface(type, typeof(IResource))) | ||||||
|  |             { | ||||||
|  |                 return new RepresentationType( | ||||||
|  |                    RepresentationTypeIdentifier.TypedResource, | ||||||
|  |                    nullable, | ||||||
|  |                    TypeTemplate.GetTypeGuid(type) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             else if (Codec.ImplementsInterface(type, typeof(IRecord))) | ||||||
|  |             { | ||||||
|  |                 return new RepresentationType( | ||||||
|  |                    RepresentationTypeIdentifier.TypedRecord, | ||||||
|  |                    nullable, | ||||||
|  |                    TypeTemplate.GetTypeGuid(type) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             else if (type.IsGenericType) | ||||||
|             { |             { | ||||||
|                 var genericType = type.GetGenericTypeDefinition(); |                 var genericType = type.GetGenericTypeDefinition(); | ||||||
|                 if (genericType == typeof(List<>)) |                 if (genericType == typeof(List<>)) | ||||||
| @@ -327,28 +346,6 @@ namespace Esiur.Data | |||||||
|  |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else if (type == typeof(IResource)) |  | ||||||
|                 return new RepresentationType(RepresentationTypeIdentifier.Resource, nullable); |  | ||||||
|             else if (type == typeof(IRecord) || type == typeof(Record)) |  | ||||||
|                 return new RepresentationType(RepresentationTypeIdentifier.Record, nullable); |  | ||||||
|             else if (type == typeof(Map<object, object>)) |  | ||||||
|                 return new RepresentationType(RepresentationTypeIdentifier.Map, nullable); |  | ||||||
|             else if (Codec.ImplementsInterface(type, typeof(IResource))) |  | ||||||
|             { |  | ||||||
|                 return new RepresentationType( |  | ||||||
|                    RepresentationTypeIdentifier.TypedResource, |  | ||||||
|                    nullable, |  | ||||||
|                    TypeTemplate.GetTypeGuid(type) |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             else if (Codec.ImplementsInterface(type, typeof(IRecord))) |  | ||||||
|             { |  | ||||||
|                 return new RepresentationType( |  | ||||||
|                    RepresentationTypeIdentifier.TypedRecord, |  | ||||||
|                    nullable, |  | ||||||
|                    TypeTemplate.GetTypeGuid(type) |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             else if (type.IsEnum) |             else if (type.IsEnum) | ||||||
|             { |             { | ||||||
|                 return new RepresentationType(RepresentationTypeIdentifier.Enum, nullable, TypeTemplate.GetTypeGuid(type)); |                 return new RepresentationType(RepresentationTypeIdentifier.Enum, nullable, TypeTemplate.GetTypeGuid(type)); | ||||||
|   | |||||||
| @@ -190,19 +190,6 @@ public class HTTPServer : NetworkServer<HTTPConnection>, IResource | |||||||
|         set; |         set; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //[Attribute] |  | ||||||
|     //public virtual uint Timeout |  | ||||||
|     //{ |  | ||||||
|     //    get; |  | ||||||
|     //    set; |  | ||||||
|     //} |  | ||||||
|  |  | ||||||
|     //[Attribute] |  | ||||||
|     //public virtual uint Clock |  | ||||||
|     //{ |  | ||||||
|     //    get; |  | ||||||
|     //    set; |  | ||||||
|     //} |  | ||||||
|   |   | ||||||
|     [Attribute] |     [Attribute] | ||||||
|     public virtual uint MaxPost |     public virtual uint MaxPost | ||||||
|   | |||||||
| @@ -158,7 +158,7 @@ public class TypeTemplate | |||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     public static Guid GetTypeGuid(Type type) => GetTypeGuid(type.FullName); |     public static Guid GetTypeGuid(Type type) => GetTypeGuid(GetTypeClassName(type)); | ||||||
|  |  | ||||||
|     public static Guid GetTypeGuid(string typeName) |     public static Guid GetTypeGuid(string typeName) | ||||||
|     { |     { | ||||||
| @@ -174,6 +174,11 @@ public class TypeTemplate | |||||||
|             return GetDistributedTypes(type.GetElementType()); |             return GetDistributedTypes(type.GetElementType()); | ||||||
|         else if (type.IsEnum) |         else if (type.IsEnum) | ||||||
|             return new Type[] { type }; |             return new Type[] { type }; | ||||||
|  |         else if (Codec.ImplementsInterface(type, typeof(IRecord)) | ||||||
|  |                 || Codec.ImplementsInterface(type, typeof(IResource))) | ||||||
|  |         { | ||||||
|  |             return new Type[] { type }; | ||||||
|  |         } | ||||||
|         else if (type.IsGenericType) |         else if (type.IsGenericType) | ||||||
|         { |         { | ||||||
|             var genericType = type.GetGenericTypeDefinition(); |             var genericType = type.GetGenericTypeDefinition(); | ||||||
| @@ -199,11 +204,7 @@ public class TypeTemplate | |||||||
|                 return rt.ToArray(); |                 return rt.ToArray(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (Codec.ImplementsInterface(type, typeof(IRecord)) |           | ||||||
|                 || Codec.ImplementsInterface(type, typeof(IResource))) |  | ||||||
|         { |  | ||||||
|             return new Type[] { type }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return new Type[0]; |         return new Type[0]; | ||||||
|     } |     } | ||||||
| @@ -354,6 +355,22 @@ public class TypeTemplate | |||||||
|             return type.Name + "?"; |             return type.Name + "?"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static string GetTypeClassName(Type type, string separator = ".") | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         if (type.IsGenericType) | ||||||
|  |         { | ||||||
|  |             var index = type.Name.IndexOf("`"); | ||||||
|  |             var name = $"{type.Namespace}{separator}{((index > -1) ? type.Name.Substring(0, index) : type.Name)}Of"; | ||||||
|  |             foreach (var t in type.GenericTypeArguments) | ||||||
|  |                 name += GetTypeClassName(t, "_"); | ||||||
|  |  | ||||||
|  |             return name; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |             return $"{type.Namespace}{separator}{type.Name}"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public TypeTemplate(Type type, bool addToWarehouse = false) |     public TypeTemplate(Type type, bool addToWarehouse = false) | ||||||
|     { |     { | ||||||
|         if (Codec.InheritsClass(type, typeof(DistributedResource))) |         if (Codec.InheritsClass(type, typeof(DistributedResource))) | ||||||
| @@ -377,7 +394,7 @@ public class TypeTemplate | |||||||
|  |  | ||||||
|         DefinedType = type; |         DefinedType = type; | ||||||
|  |  | ||||||
|         className = type.FullName; |         className = GetTypeClassName(type); | ||||||
|  |  | ||||||
|         // set guid |         // set guid | ||||||
|         classId = GetTypeGuid(className); |         classId = GetTypeGuid(className); | ||||||
| @@ -615,7 +632,6 @@ public class TypeTemplate | |||||||
|             ft.MethodInfo = mi; |             ft.MethodInfo = mi; | ||||||
|             functions.Add(ft); |             functions.Add(ft); | ||||||
|  |  | ||||||
|   |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -761,7 +777,7 @@ public class TypeTemplate | |||||||
|         { |         { | ||||||
|             // find the first parent type that implements IResource |             // find the first parent type that implements IResource | ||||||
|             var ParentDefinedType = ResourceProxy.GetBaseType(type.BaseType); |             var ParentDefinedType = ResourceProxy.GetBaseType(type.BaseType); | ||||||
|             var parentId = GetTypeGuid(ParentDefinedType.FullName); |             var parentId = GetTypeGuid(ParentDefinedType); | ||||||
|  |  | ||||||
|             b.AddUInt8((byte)(0x80 | (byte)templateType)) |             b.AddUInt8((byte)(0x80 | (byte)templateType)) | ||||||
|              .AddGuid(classId) |              .AddGuid(classId) | ||||||
|   | |||||||
| @@ -1,3 +1,2 @@ | |||||||
|  |  | ||||||
| 1- Bin | 1- Generic Records/Resources | ||||||
| 2- clean |  | ||||||
| @@ -19,6 +19,15 @@ public enum SizeEnum:short | |||||||
|     XLarge = 22 |     XLarge = 22 | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public class SearchResults<T> : IRecord where T : IResource | ||||||
|  | { | ||||||
|  |     [Public] public int Offset { get; set; } | ||||||
|  |     [Public] public int Needed { get; set; } | ||||||
|  |     [Public] public int Total { get; set; } | ||||||
|  |     [Public] public T[] Results { get; set; } | ||||||
|  | } | ||||||
|  |  | ||||||
| [Resource] | [Resource] | ||||||
| public partial class MyService | public partial class MyService | ||||||
| { | { | ||||||
| @@ -29,6 +38,12 @@ public partial class MyService | |||||||
|     [Public] bool boolean = true; |     [Public] bool boolean = true; | ||||||
|     [Public] bool[] booleanArray = new bool[] { true, false, true, false, true }; |     [Public] bool[] booleanArray = new bool[] { true, false, true, false, true }; | ||||||
|  |  | ||||||
|  |     [Public] | ||||||
|  |     public SearchResults<MyResource> GetRecords() | ||||||
|  |     { | ||||||
|  |         return new SearchResults<MyResource>() { Needed = 3, Offset = 10, Results = new MyResource[0], Total = 102 }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     [Public] byte uInt8Test = 8; |     [Public] byte uInt8Test = 8; | ||||||
|     [Public] byte? uInt8Null = null; |     [Public] byte? uInt8Null = null; | ||||||
|     [Public] byte[] uInt8Array = new byte[] { 0, 1, 2, 3, 4, 5 }; |     [Public] byte[] uInt8Array = new byte[] { 0, 1, 2, 3, 4, 5 }; | ||||||
| @@ -159,7 +174,8 @@ public partial class MyService | |||||||
|     [Public] |     [Public] | ||||||
|     public (int, string, double, bool) GetTuple4(int a1, string a2, double a3, bool a4) => (a1, a2, a3, a4); |     public (int, string, double, bool) GetTuple4(int a1, string a2, double a3, bool a4) => (a1, a2, a3, a4); | ||||||
|  |  | ||||||
|     [Public] public MyRecord SendRecord(MyRecord record) |     [Public] | ||||||
|  |     public MyRecord SendRecord(MyRecord record) | ||||||
|     { |     { | ||||||
|         Console.WriteLine(record.ToString()); |         Console.WriteLine(record.ToString()); | ||||||
|         return record; |         return record; | ||||||
|   | |||||||
| @@ -45,6 +45,9 @@ using System.Collections.Generic; | |||||||
|  |  | ||||||
| namespace Test | namespace Test | ||||||
| { | { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     class Program |     class Program | ||||||
|     { |     { | ||||||
|          |          | ||||||
| @@ -64,7 +67,7 @@ namespace Test | |||||||
|  |  | ||||||
|             service.Resource = res1; |             service.Resource = res1; | ||||||
|             service.ChildResource = res3; |             service.ChildResource = res3; | ||||||
|             service.Resources = new MyResource[] { res1, res2,  res1 , res3 }; |             service.Resources = new MyResource[] { res1, res2, res1, res3 }; | ||||||
|  |  | ||||||
|             //web.MapGet("/{action}/{age}", (int age, string action, HTTPConnection sender) => |             //web.MapGet("/{action}/{age}", (int age, string action, HTTPConnection sender) => | ||||||
|             //{ |             //{ | ||||||
| @@ -86,25 +89,18 @@ namespace Test | |||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|         enum aa |  | ||||||
|         { |  | ||||||
|             a, |  | ||||||
|             b, |  | ||||||
|             c, |  | ||||||
|             d                 |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public static (int, string) tuple() => (33, "sss"); |  | ||||||
|   |   | ||||||
|         private static async void TestClient(IResource local) |         private static async void TestClient(IResource local) | ||||||
|         { |         { | ||||||
|             dynamic remote = await Warehouse.Get<IResource>("iip://localhost/mem/service"); |             dynamic remote = await Warehouse.Get<IResource>("iip://localhost/mem/service"); | ||||||
|  |  | ||||||
|             TestObjectProps(local, remote); |             TestObjectProps(local, remote); | ||||||
|  |             var r = await remote.GetRecords(); | ||||||
|  |  | ||||||
|             var opt = await remote.Optional(new { a1 = 22, a2 = 33, a4 = "What?" }); |             var opt = await remote.Optional(new { a1 = 22, a2 = 33, a4 = "What?" }); | ||||||
|             Console.WriteLine(opt); |             Console.WriteLine(opt); | ||||||
|  |  | ||||||
|  |  | ||||||
|             await remote.Void(); |             await remote.Void(); | ||||||
|             await remote.Connection("ss", 33); |             await remote.Connection("ss", 33); | ||||||
|             await remote.ConnectionOptional("Test 2", 88); |             await remote.ConnectionOptional("Test 2", 88); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user