diff --git a/Esiur.Stores.EntityCore/EntityResource.cs b/Esiur.Stores.EntityCore/EntityResource.cs index 44196fa..930c5fa 100644 --- a/Esiur.Stores.EntityCore/EntityResource.cs +++ b/Esiur.Stores.EntityCore/EntityResource.cs @@ -34,6 +34,7 @@ using System.Runtime.CompilerServices; namespace Esiur.Stores.EntityCore { + public class EntityResource : IResource { //[NotMapped] diff --git a/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj b/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj index 6cedbd2..874d12a 100644 --- a/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj +++ b/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj @@ -9,9 +9,17 @@ Esiur Entity Framework Extension true Esiur.Stores.EntityCore - 1.0.2 + 1.1.0 + + + + + + + + diff --git a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs index 59b89a4..8f04468 100644 --- a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs +++ b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs @@ -76,7 +76,7 @@ namespace Esiur.Stores.EntityCore return cache; // check if the object exists - var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager); + var obj = Warehouse.New(entityType.ClrType).Wait() as IResource;//, "", options.Store, null, manager); //obj._PrimaryId = id; options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait(); diff --git a/Esiur.Stores.MongoDB/Esiur.Stores.MongoDB.csproj b/Esiur.Stores.MongoDB/Esiur.Stores.MongoDB.csproj index cd17db4..ebe3330 100644 --- a/Esiur.Stores.MongoDB/Esiur.Stores.MongoDB.csproj +++ b/Esiur.Stores.MongoDB/Esiur.Stores.MongoDB.csproj @@ -11,13 +11,13 @@ http://www.esiur.com https://github.com/esiur/esiur-dotnet/ True - 1.4.1 + 1.5.0 Esiur.Stores.MongoDB - - + + diff --git a/Esiur.Stores.MongoDB/MongoDBStore.cs b/Esiur.Stores.MongoDB/MongoDBStore.cs index 04849e3..93d0526 100644 --- a/Esiur.Stores.MongoDB/MongoDBStore.cs +++ b/Esiur.Stores.MongoDB/MongoDBStore.cs @@ -159,7 +159,7 @@ namespace Esiur.Stores.MongoDB resources.Add(id, new WeakReference(resource)); //@TODO this causes store.put to be invoked, need fix - await Warehouse.Put(resource, document["name"].AsString, this); + await Warehouse.Put(document["name"].AsString, resource, this); var parents = document["parents"].AsBsonArray; diff --git a/Esiur/Core/ExceptionLevel.cs b/Esiur/Core/ExceptionLevel.cs new file mode 100644 index 0000000..78117d8 --- /dev/null +++ b/Esiur/Core/ExceptionLevel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esiur.Core +{ + public enum ExceptionLevel + { + Code = 0x1, + Message = 0x2, + Source = 0x4, + Trace = 0x8 + } +} diff --git a/Esiur/Esiur.csproj b/Esiur/Esiur.csproj index 1f00c4b..87d95d2 100644 --- a/Esiur/Esiur.csproj +++ b/Esiur/Esiur.csproj @@ -7,12 +7,12 @@ https://github.com/Esiur/Esiur-dotnet/blob/master/LICENSE http://www.esiur.com true - 1.6.1 + 1.7.1 https://github.com/esiur/esiur-dotnet Ahmed Kh. Zamil - 1.6.0 + 1.7.1 Esiur Foundation - 1.6.0 + 1.7.1 Esiur Esiur Esiur @@ -57,6 +57,7 @@ + @@ -72,4 +73,9 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/Esiur/Net/IIP/DistributedConnectionProtocol.cs b/Esiur/Net/IIP/DistributedConnectionProtocol.cs index bb8f05a..0f20ee2 100644 --- a/Esiur/Net/IIP/DistributedConnectionProtocol.cs +++ b/Esiur/Net/IIP/DistributedConnectionProtocol.cs @@ -1164,6 +1164,22 @@ namespace Esiur.Net.IIP } + [Attribute] + public ExceptionLevel ExceptionLevel { get; set; } + = ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace; + + private Tuple SummerizeException(Exception ex) + { + ex = ex.InnerException != null ? ex.InnerException : ex; + + var code = (ExceptionLevel & ExceptionLevel.Code) == 0 ? 0 : ex is AsyncException ae ? ae.Code : 0; + var msg = (ExceptionLevel & ExceptionLevel.Message) == 0 ? "" : ex.Message; + var source = (ExceptionLevel & ExceptionLevel.Source) == 0 ? "" : ex.Source; + var trace = (ExceptionLevel & ExceptionLevel.Trace) == 0 ? "" : ex.StackTrace; + + return new Tuple((ushort)code, $"{source}: {msg}\n{trace}"); + } + void IIPRequestInvokeFunctionArrayArguments(uint callback, uint resourceId, byte index, byte[] content) { //Console.WriteLine("IIPRequestInvokeFunction " + callback + " " + resourceId + " " + index); @@ -1247,8 +1263,8 @@ namespace Esiur.Net.IIP } catch (Exception ex) { - SendError(ErrorType.Exception, callback, 0, - ex.InnerException != null ? ex.InnerException.ToString() : ex.ToString()); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); return; } @@ -1266,7 +1282,8 @@ namespace Esiur.Net.IIP } catch (Exception ex) { - SendError(ErrorType.Exception, callback, 0, ex.ToString()); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); } } @@ -1297,7 +1314,8 @@ namespace Esiur.Net.IIP .Done(); }).Error(ex => { - SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); }).Progress((pt, pv, pm) => { SendProgress(callback, pv, pm); @@ -1412,7 +1430,8 @@ namespace Esiur.Net.IIP } catch (Exception ex) { - SendError(ErrorType.Exception, callback, 0, ex.ToString()); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); return; } @@ -1431,7 +1450,8 @@ namespace Esiur.Net.IIP } catch (Exception ex) { - SendError(ErrorType.Exception, callback, 0, ex.ToString()); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); } } else if (rt is Task) @@ -1459,7 +1479,8 @@ namespace Esiur.Net.IIP }).Error(ex => { - SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); + var (code, msg) = SummerizeException(ex); + SendError(ErrorType.Exception, callback, code, msg); }).Progress((pt, pv, pm) => { SendProgress(callback, pv, pm); diff --git a/Esiur/Net/IIP/DistributedServer.cs b/Esiur/Net/IIP/DistributedServer.cs index 2567de5..81006cf 100644 --- a/Esiur/Net/IIP/DistributedServer.cs +++ b/Esiur/Net/IIP/DistributedServer.cs @@ -67,7 +67,14 @@ namespace Esiur.Net.IIP set; } - + + [Attribute] + public ExceptionLevel ExceptionLevel { get; set; } + = ExceptionLevel.Code + | ExceptionLevel.Source + | ExceptionLevel.Message + | ExceptionLevel.Trace; + public Instance Instance { @@ -147,6 +154,7 @@ namespace Esiur.Net.IIP public override void Add(DistributedConnection connection) { connection.Server = this; + connection.ExceptionLevel = ExceptionLevel; base.Add(connection); } diff --git a/Esiur/Proxy/ResourceGenerator.cs b/Esiur/Proxy/ResourceGenerator.cs index ae7b7a6..87882de 100644 --- a/Esiur/Proxy/ResourceGenerator.cs +++ b/Esiur/Proxy/ResourceGenerator.cs @@ -24,47 +24,57 @@ namespace Esiur.Proxy if (!(context.SyntaxContextReceiver is ResourceGeneratorReceiver receiver)) return; -//#if DEBUG -// if (!Debugger.IsAttached) -// { -// Debugger.Launch(); -// } -//#endif - - //var toImplement = receiver.Classes.Where(x => x.Fields.Length > 0); - - foreach (var ci in receiver.Classes) + try { - var code = @$"using Esiur.Resource; + //#if DEBUG + // if (!Debugger.IsAttached) + // { + // Debugger.Launch(); + // } + //#endif + + //var toImplement = receiver.Classes.Where(x => x.Fields.Length > 0); + + foreach (var ci in receiver.Classes) + { + var code = @$"using Esiur.Resource; using Esiur.Core; namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{ "; - if (ci.ImplementInterface) - code += $"public partial class {ci.Name} {{"; - else - { - code += @$"public partial class {ci.Name} : IResource {{ + if (ci.ImplementInterface) + code += $"public partial class {ci.Name} {{"; + else + { + code += @$"public partial class {ci.Name} : IResource {{ public Instance Instance {{ get; set; }} public event DestroyedEvent OnDestroy; public virtual void Destroy() {{ OnDestroy?.Invoke(this); }} "; - if (!ci.ImplementTrigger) - code += "public AsyncReply Trigger(ResourceTrigger trigger) => new AsyncReply(true);"; + if (!ci.ImplementTrigger) + code += "public AsyncReply Trigger(ResourceTrigger trigger) => new AsyncReply(true);\r\n"; + } + + foreach (var f in ci.Fields) + { + var fn = f.Name; + var pn = fn.Substring(0, 1).ToUpper() + fn.Substring(1); + + // copy attributes + var attrs = string.Join(" ", f.GetAttributes().Select(x => $"[{x.ToString()}]")); + code += $"{attrs} public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance?.Modified(); }} }}\r\n"; + } + + code += "}}\r\n"; + + //System.IO.File.WriteAllText("c:\\gen\\" + ci.Name + "_esiur.cs", code); + context.AddSource(ci.Name + "_esiur.cs", code); } - - foreach (var f in ci.Fields) - { - var fn = f.Name; - var pn = fn.Substring(0, 1).ToUpper() + fn.Substring(1); - code += $@"[Public] public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance.Modified(); }} }}"; - } - - code += "}}"; - - //System.IO.File.WriteAllText("C:\\www\\class.cs", code); - context.AddSource(ci.Name + "_esiur.cs", code); + } + catch //(Exception ex) + { + //System.IO.File.AppendAllText("c:\\gen\\error.log", ex.ToString() + "\r\n"); } } } diff --git a/Esiur/Proxy/GenerationInfo.cs b/Esiur/Proxy/ResourceGeneratorClassInfo.cs similarity index 91% rename from Esiur/Proxy/GenerationInfo.cs rename to Esiur/Proxy/ResourceGeneratorClassInfo.cs index 8edc25c..9d95eb2 100644 --- a/Esiur/Proxy/GenerationInfo.cs +++ b/Esiur/Proxy/ResourceGeneratorClassInfo.cs @@ -6,7 +6,7 @@ using System.Text; namespace Esiur.Proxy { - public struct GenerationInfo + public struct ResourceGeneratorClassInfo { public string Name { get; set; } public bool ImplementInterface { get; set; } @@ -16,5 +16,6 @@ namespace Esiur.Proxy public ITypeSymbol ClassSymbol { get; set; } public ClassDeclarationSyntax ClassDeclaration { get; set; } + } } diff --git a/Esiur/Proxy/ResourceGeneratorFieldInfo.cs b/Esiur/Proxy/ResourceGeneratorFieldInfo.cs new file mode 100644 index 0000000..c65d46b --- /dev/null +++ b/Esiur/Proxy/ResourceGeneratorFieldInfo.cs @@ -0,0 +1,13 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esiur.Proxy +{ + public struct ResourceGeneratorFieldInfo + { + public IFieldSymbol FieldSymbol { get; set; } + public string[] Attributes { get; set; } + } +} diff --git a/Esiur/Proxy/ResourceGeneratorReceiver.cs b/Esiur/Proxy/ResourceGeneratorReceiver.cs index a1d31e7..37a39fe 100644 --- a/Esiur/Proxy/ResourceGeneratorReceiver.cs +++ b/Esiur/Proxy/ResourceGeneratorReceiver.cs @@ -11,7 +11,7 @@ namespace Esiur.Proxy public class ResourceGeneratorReceiver : ISyntaxContextReceiver { - public List Classes { get; } = new(); + public List Classes { get; } = new(); public void OnVisitSyntaxNode(GeneratorSyntaxContext context) { @@ -23,11 +23,8 @@ namespace Esiur.Proxy if (cls.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute")) { - //if (!Debugger.IsAttached) - //{ - // Debugger.Launch(); - //} - + + var hasTrigger = cds.Members .Where(x => x is MethodDeclarationSyntax) .Select(x => context.SemanticModel.GetDeclaredSymbol(x) as IMethodSymbol) @@ -40,9 +37,16 @@ namespace Esiur.Proxy .Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute")) .ToArray(); + //if (!Debugger.IsAttached) + //{ + // if (cls.Name == "User") + // Debugger.Launch(); + //} + + // get fields - Classes.Add(new GenerationInfo() + Classes.Add(new ResourceGeneratorClassInfo() { Name = cls.Name, ClassDeclaration = cds, diff --git a/Esiur/Resource/AnnotationAttribute.cs b/Esiur/Resource/AnnotationAttribute.cs index 35e2531..511b5c2 100644 --- a/Esiur/Resource/AnnotationAttribute.cs +++ b/Esiur/Resource/AnnotationAttribute.cs @@ -5,7 +5,7 @@ using System.Text; namespace Esiur.Resource { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event)] + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event)] public class AnnotationAttribute : Attribute { diff --git a/Esiur/Resource/IResource.cs b/Esiur/Resource/IResource.cs index 9fbad4b..9ca5c58 100644 --- a/Esiur/Resource/IResource.cs +++ b/Esiur/Resource/IResource.cs @@ -30,6 +30,7 @@ using Esiur.Data; using Esiur.Core; using System.ComponentModel; using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations.Schema; namespace Esiur.Resource { @@ -41,6 +42,8 @@ namespace Esiur.Resource { AsyncReply Trigger(ResourceTrigger trigger); + + [NotMapped] Instance Instance { get; diff --git a/Esiur/Resource/Instance.cs b/Esiur/Resource/Instance.cs index 376ed99..017773f 100644 --- a/Esiur/Resource/Instance.cs +++ b/Esiur/Resource/Instance.cs @@ -14,9 +14,11 @@ using Esiur.Security.Authority; using Esiur.Proxy; using Esiur.Core; using System.Text.Json; +using System.ComponentModel.DataAnnotations.Schema; namespace Esiur.Resource { + [NotMapped] public class Instance { string name;