From 443623d8df786c4f71e972d2f5e020ca183544ae Mon Sep 17 00:00:00 2001 From: Ahmed Zamil Date: Mon, 27 Apr 2020 08:32:10 +0300 Subject: [PATCH] EF Core --- Esyur.Stores.EntityCore/EntityResource.cs | 3 + Esyur.Stores.EntityCore/EntityStore.cs | 78 +++++++----- .../Esyur.Stores.EntityCore.csproj | 10 +- .../EsyurExtensionOptions.cs | 1 + Esyur.Stores.EntityCore/EsyurExtensions.cs | 28 +++-- Esyur.Stores.EntityCore/EsyurProxyRewrite.cs | 51 ++++---- Esyur/Esyur.csproj | 8 +- .../Net/IIP/DistributedConnectionProtocol.cs | 119 ++++++++++-------- Esyur/Net/IIP/DistributedPropertyContext.cs | 3 + Esyur/Net/IIP/DistributedResource.cs | 2 +- Esyur/Net/IIP/DistributedServer.cs | 4 - Esyur/Proxy/ResourceProxy.cs | 5 + Esyur/Resource/IResource.cs | 2 + Esyur/Resource/Instance.cs | 24 +++- Esyur/Resource/ResourceEventHandler.cs | 4 +- Esyur/Resource/Warehouse.cs | 12 +- 16 files changed, 207 insertions(+), 147 deletions(-) diff --git a/Esyur.Stores.EntityCore/EntityResource.cs b/Esyur.Stores.EntityCore/EntityResource.cs index 6a26df9..6aa9721 100644 --- a/Esyur.Stores.EntityCore/EntityResource.cs +++ b/Esyur.Stores.EntityCore/EntityResource.cs @@ -36,6 +36,9 @@ namespace Esyur.Stores.EntityCore { public class EntityResource : IResource { + [NotMapped] + internal int _PrimaryId; + public event DestroyedEvent OnDestroy; public event PropertyChangedEventHandler PropertyChanged; diff --git a/Esyur.Stores.EntityCore/EntityStore.cs b/Esyur.Stores.EntityCore/EntityStore.cs index eb2f7d8..d042875 100644 --- a/Esyur.Stores.EntityCore/EntityStore.cs +++ b/Esyur.Stores.EntityCore/EntityStore.cs @@ -45,7 +45,9 @@ namespace Esyur.Stores.EntityCore public event DestroyedEvent OnDestroy; - struct TypeInfo + Dictionary> DB = new Dictionary>(); + + internal struct TypeInfo { public string Name; public IEntityType Type; @@ -53,55 +55,57 @@ namespace Esyur.Stores.EntityCore } Dictionary TypesByName = new Dictionary(); - Dictionary TypesByType = new Dictionary(); - - /* - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - var extension = optionsBuilder.Options.FindExtension() - ?? new EsyurExtension(); - - - ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); - //optionsBuilder.UseLazyLoadingProxies(); - base.OnConfiguring(optionsBuilder); - } - */ - - /* - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - //modelBuilder.Entity().ToTable("Series"); - //modelBuilder.Entity().ToTable("Episodes").; - //modelBuilder.Ignore - // modelBuilder.Entity(x=>x.Property(p=>p.Instance).HasConversion(v=>v.Managers.) - Console.WriteLine("OnModelCreating"); - //modelBuilder.Entity() + internal Dictionary TypesByType = new Dictionary(); - base.OnModelCreating(modelBuilder); - }*/ + bool Loaded; public async AsyncReply Get(string path) { var p = path.Split('/'); var ti = TypesByName[p[0]]; var id = Convert.ToInt32(p[1]); - return DbContext.Find(ti.Type.ClrType, id) as IResource; + return DbContextProvider().Find(ti.Type.ClrType, id) as IResource; } public async AsyncReply Put(IResource resource) { + if (resource is EntityStore) + return false; + + var type = ResourceProxy.GetBaseType(resource);//.GetType().; + + var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"]; + + if (DB[type].ContainsKey(eid)) + DB[type].Remove(eid); + + DB[type].Add(eid, new WeakReference(resource)); + return true; } + public IResource GetById(Type type, int id) + { + if (!DB[type].ContainsKey(id)) + return null; + + if (!DB[type][id].IsAlive) + return null; + + return DB[type][id].Target as IResource; + } + [Attribute] - public EsyurExtensionOptions Options { get; set; } + public Func DbContextProvider { get; set; } + + [Attribute] + public DbContextOptionsBuilder Options { get; set; } //DbContext dbContext; - [Attribute] - public DbContext DbContext { get; set; } + //[Attribute] + //public DbContext DbContext { get; set; } public string Link(IResource resource) { @@ -178,9 +182,15 @@ namespace Esyur.Stores.EntityCore public AsyncReply Trigger(ResourceTrigger trigger) { - if (trigger == ResourceTrigger.SystemInitialized && DbContext != null) + if (trigger == ResourceTrigger.Initialize)// SystemInitialized && DbContext != null) { - var types = DbContext.Model.GetEntityTypes(); + + if (DbContextProvider == null) + DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext; + + var context = Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext; + + var types = context.Model.GetEntityTypes(); foreach (var t in types) { var ti = new TypeInfo() @@ -192,6 +202,8 @@ namespace Esyur.Stores.EntityCore TypesByName.Add(t.ClrType.Name, ti); TypesByType.Add(t.ClrType, ti); + + DB.Add(t.ClrType, new Dictionary()); } } diff --git a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj index c018ff9..2430544 100644 --- a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj +++ b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj @@ -11,14 +11,14 @@ - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs b/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs index cb60eba..70fd4f6 100644 --- a/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs +++ b/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs @@ -57,6 +57,7 @@ namespace Esyur.Stores.EntityCore public EntityStore Store => _store; + public void ApplyServices(IServiceCollection services) { services.AddEntityFrameworkProxies(); diff --git a/Esyur.Stores.EntityCore/EsyurExtensions.cs b/Esyur.Stores.EntityCore/EsyurExtensions.cs index 4dbd525..eeb7291 100644 --- a/Esyur.Stores.EntityCore/EsyurExtensions.cs +++ b/Esyur.Stores.EntityCore/EsyurExtensions.cs @@ -60,11 +60,11 @@ namespace Esyur.Stores.EntityCore } public static DbContextOptionsBuilder UseEsyur(this DbContextOptionsBuilder optionsBuilder, - DbContext context, + //DbContext context, string name = null, - IResource parent = null, - IPermissionsManager manager = null - + IResource parent = null, + IPermissionsManager manager = null, + Func dbContextProvider = null ) { var extension = optionsBuilder.Options.FindExtension(); @@ -72,10 +72,10 @@ namespace Esyur.Stores.EntityCore if (extension == null) { - var store = Warehouse.New(name, null, parent, manager); + var store = Warehouse.New(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }); extension = new EsyurExtensionOptions(store); - store.Options = extension; - store.DbContext = context; + //store.Options = optionsBuilder; + //store.DbContext = context; } ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); @@ -86,22 +86,24 @@ namespace Esyur.Stores.EntityCore public static DbContextOptionsBuilder UseEsyur( this DbContextOptionsBuilder optionsBuilder, - DbContext context, + //DbContext context, string name = null, IResource parent = null, - IPermissionsManager manager = null) + IPermissionsManager manager = null, + Func dbContextProvider = null) where TContext : DbContext { var extension = optionsBuilder.Options.FindExtension(); - + if (extension == null) { - var store = Warehouse.New(name, null, parent, manager); + var store = Warehouse.New(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }); extension = new EsyurExtensionOptions(store); - store.Options = extension; - store.DbContext = context; + //store.Options = optionsBuilder; + //store.Options = extension; + //store.DbContext = context; } diff --git a/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs b/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs index dc035e1..c71ff1e 100644 --- a/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs +++ b/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs @@ -24,10 +24,12 @@ SOFTWARE. using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text; using Esyur.Proxy; using Esyur.Resource; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; @@ -48,40 +50,39 @@ namespace Esyur.Stores.EntityCore public static object CreateInstance( IDbContextOptions dbContextOptions, IEntityType entityType, - ILazyLoader loader, - object[] constructorArguments) + // ILazyLoader loader, + object[] constructorArguments, + DbContext context, + int id = 0 +) { var options = dbContextOptions.FindExtension(); + var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null; - return CreateInstance2( - options, - entityType, - loader, - constructorArguments); + var cache = options.Store.GetById(entityType.ClrType, id); + + if (cache != null) + return cache; + + // check if the object exists + var obj = Warehouse.New(entityType.ClrType) as EntityResource;//, "", options.Store, null, manager); + obj._PrimaryId = id; + options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); + Warehouse.Put(obj, id.ToString(), options.Store, null, null, 0, manager); + +// obj.Instance.IntVal = id;//.Variables.Add("eid", id); + + return obj; } - public static object CreateInstance2( - EsyurExtensionOptions options, - IEntityType entityType, - ILazyLoader loader, - object[] constructorArguments) - { - //var key = entityType.FindPrimaryKey(); - //options.AddType(entityType); - - var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null; - return Warehouse.New(entityType.ClrType, "", options.Store, null, manager); - } - - - public EsyurProxyRewrite(EsyurExtensionOptions ext, ProviderConventionSetBuilderDependencies conventionSetBuilderDependencies) { _directBindingConvention = new ConstructorBindingConvention(conventionSetBuilderDependencies); } + public void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) @@ -108,8 +109,10 @@ namespace Esyur.Stores.EntityCore { new DependencyInjectionParameterBinding(typeof(IDbContextOptions), typeof(IDbContextOptions)), new EntityTypeParameterBinding(), - new DependencyInjectionParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader)), - new ObjectArrayParameterBinding(binding.ParameterBindings) + //new DependencyInjectionParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader)), + new ObjectArrayParameterBinding(binding.ParameterBindings), + new ContextParameterBinding(typeof(DbContext)), + new PropertyParameterBinding(entityType.FindPrimaryKey().Properties.FirstOrDefault()) }, proxyType)); } diff --git a/Esyur/Esyur.csproj b/Esyur/Esyur.csproj index 82b6558..f713aa5 100644 --- a/Esyur/Esyur.csproj +++ b/Esyur/Esyur.csproj @@ -50,12 +50,12 @@ - + - - - + + + \ No newline at end of file diff --git a/Esyur/Net/IIP/DistributedConnectionProtocol.cs b/Esyur/Net/IIP/DistributedConnectionProtocol.cs index 0397215..3cc2a4a 100644 --- a/Esyur/Net/IIP/DistributedConnectionProtocol.cs +++ b/Esyur/Net/IIP/DistributedConnectionProtocol.cs @@ -416,7 +416,7 @@ namespace Esyur.Net.IIP parent.children.Remove(child); child.parents.Remove(parent); -// parent.Instance.Children.Remove(child); + // parent.Instance.Children.Remove(child); }); }); } @@ -445,7 +445,7 @@ namespace Esyur.Net.IIP void IIPRequestAttachResource(uint callback, uint resourceId) { - + Warehouse.GetById(resourceId).Then((res) => { if (res != null) @@ -460,6 +460,7 @@ namespace Esyur.Net.IIP // unsubscribe r.Instance.ResourceEventOccurred -= Instance_EventOccurred; + r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred; r.Instance.ResourceModified -= Instance_PropertyModified; r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed; // r.Instance.Children.OnAdd -= Children_OnAdd; @@ -501,6 +502,7 @@ namespace Esyur.Net.IIP // subscribe r.Instance.ResourceEventOccurred += Instance_EventOccurred; + r.Instance.CustomResourceEventOccurred += Instance_CustomEventOccurred; r.Instance.ResourceModified += Instance_PropertyModified; r.Instance.ResourceDestroyed += Instance_ResourceDestroyed; //r.Instance.Children.OnAdd += Children_OnAdd; @@ -581,20 +583,22 @@ namespace Esyur.Net.IIP var r = res as IResource; // unsubscribe r.Instance.ResourceEventOccurred -= Instance_EventOccurred; + r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred; r.Instance.ResourceModified -= Instance_PropertyModified; r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed; //r.Instance.Children.OnAdd -= Children_OnAdd; //r.Instance.Children.OnRemoved -= Children_OnRemoved; - + //r.Instance.Attributes.OnModified -= Attributes_OnModified; // subscribe r.Instance.ResourceEventOccurred += Instance_EventOccurred; + r.Instance.CustomResourceEventOccurred += Instance_CustomEventOccurred; r.Instance.ResourceModified += Instance_PropertyModified; r.Instance.ResourceDestroyed += Instance_ResourceDestroyed; //r.Instance.Children.OnAdd += Children_OnAdd; //r.Instance.Children.OnRemoved += Children_OnRemoved; - + //r.Instance.Attributes.OnModified += Attributes_OnModified; // reply ok @@ -619,6 +623,7 @@ namespace Esyur.Net.IIP { var r = res as IResource; r.Instance.ResourceEventOccurred -= Instance_EventOccurred; + r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred; r.Instance.ResourceModified -= Instance_PropertyModified; r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed; @@ -1190,7 +1195,7 @@ namespace Esyur.Net.IIP } catch (Exception ex) { - SendError(ErrorType.Exception, callback, 0, + SendError(ErrorType.Exception, callback, 0, ex.InnerException != null ? ex.InnerException.ToString() : ex.ToString()); return; } @@ -1207,7 +1212,7 @@ namespace Esyur.Net.IIP .AddUInt8((byte)DataType.Void) .Done(); } - catch(Exception ex) + catch (Exception ex) { SendError(ErrorType.Exception, callback, 0, ex.ToString()); } @@ -1231,7 +1236,7 @@ namespace Esyur.Net.IIP //SendParams((byte)0x90, callback, Codec.Compose(res, this)); } else if (rt is AsyncReply)// Codec.ImplementsInterface(rt.GetType(), typeof(IAsyncReply<>)))// rt.GetType().GetTypeInfo().IsGenericType - //&& rt.GetType().GetGenericTypeDefinition() == typeof(IAsyncReply<>)) + //&& rt.GetType().GetGenericTypeDefinition() == typeof(IAsyncReply<>)) { (rt as AsyncReply).Then(res => { @@ -1306,18 +1311,18 @@ namespace Esyur.Net.IIP else { - // function not found on a distributed object - } + // function not found on a distributed object + } } else { #if NETSTANDARD - var fi = r.GetType().GetTypeInfo().GetMethod(ft.Name); + var fi = r.GetType().GetTypeInfo().GetMethod(ft.Name); #else var fi = r.GetType().GetMethod(ft.Name); #endif - if (fi != null) + if (fi != null) { if (r.Instance.Applicable(session, ActionType.Execute, ft) == Ruling.Denied) { @@ -1326,8 +1331,8 @@ namespace Esyur.Net.IIP return; } - // cast arguments - ParameterInfo[] pi = fi.GetParameters(); + // cast arguments + ParameterInfo[] pi = fi.GetParameters(); object[] args = new object[pi.Length]; @@ -1379,34 +1384,34 @@ namespace Esyur.Net.IIP (rt as Task).ContinueWith(t => { #if NETSTANDARD - var res = t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t); + var res = t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t); #else var res = t.GetType().GetProperty("Result").GetValue(t); #endif - SendReply(IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments, callback) - .AddUInt8Array(Codec.Compose(res, this)) - .Done(); + SendReply(IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments, callback) + .AddUInt8Array(Codec.Compose(res, this)) + .Done(); }); } - else if (rt is AsyncReply) + else if (rt is AsyncReply) { (rt as AsyncReply).Then(res => { - SendReply(IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments, callback) - .AddUInt8Array(Codec.Compose(res, this)) - .Done(); + SendReply(IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments, callback) + .AddUInt8Array(Codec.Compose(res, this)) + .Done(); - }).Error(ex => - { - SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); - }).Progress((pt, pv, pm) => - { - SendProgress(callback, pv, pm); - }).Chunk(v => - { - SendChunk(callback, v); - }); + }).Error(ex => + { + SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); + }).Progress((pt, pv, pm) => + { + SendProgress(callback, pv, pm); + }).Chunk(v => + { + SendChunk(callback, v); + }); } else { @@ -1417,14 +1422,14 @@ namespace Esyur.Net.IIP } else { - // ft found, fi not found, this should never happen - } + // ft found, fi not found, this should never happen + } } } else { - // no function at this index - } + // no function at this index + } }); } else @@ -1843,7 +1848,7 @@ namespace Esyur.Net.IIP { //if (filter != null) - // ar = ar?.Where(filter).ToArray(); + // ar = ar?.Where(filter).ToArray(); // MISSING: should dispatch the unused resources. if (ar?.Length > 0) @@ -1852,7 +1857,7 @@ namespace Esyur.Net.IIP rt.Trigger(null); }).Error(ex => rt.TriggerError(ex)); - + return rt; /* @@ -1921,7 +1926,7 @@ namespace Esyur.Net.IIP return new AsyncReply(resource); } - + var reply = new AsyncReply(); resourceRequests.Add(id, reply); @@ -2139,7 +2144,7 @@ namespace Esyur.Net.IIP Codec.ParseResourceArray(content, 0, (uint)content.Length, this) .Then(resources => reply.Trigger(resources)); - }).Error(ex=>reply.TriggerError(ex)); + }).Error(ex => reply.TriggerError(ex)); return reply; } @@ -2210,26 +2215,15 @@ namespace Esyur.Net.IIP // private void Instance_EventOccurred(IResource resource, string name, string[] users, DistributedConnection[] connections, object[] args) - private void Instance_EventOccurred(IResource resource, object issuer, Session[] receivers, string name, object[] args) + private void Instance_CustomEventOccurred(IResource resource, object issuer, Func receivers, string name, object[] args) { var et = resource.Instance.Template.GetEventTemplateByName(name); if (et == null) return; - /* - if (users != null) - if (!users.Contains(RemoteUsername)) - return; - - if (connections != null) - if (!connections.Contains(this)) - return; - */ - - if (receivers != null) - if (!receivers.Contains(this.session)) - return; + if (!receivers(this.session)) + return; if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, issuer) == Ruling.Denied) return; @@ -2241,5 +2235,24 @@ namespace Esyur.Net.IIP .AddUInt8Array(Codec.ComposeVarArray(args, this, true)) .Done(); } + + private void Instance_EventOccurred(IResource resource, string name, object[] args) + { + var et = resource.Instance.Template.GetEventTemplateByName(name); + + if (et == null) + return; + + + if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, null) == Ruling.Denied) + return; + + // compose the packet + SendEvent(IIPPacket.IIPPacketEvent.EventOccurred) + .AddUInt32(resource.Instance.Id) + .AddUInt8((byte)et.Index) + .AddUInt8Array(Codec.ComposeVarArray(args, this, true)) + .Done(); + } } } diff --git a/Esyur/Net/IIP/DistributedPropertyContext.cs b/Esyur/Net/IIP/DistributedPropertyContext.cs index 42c1747..ec5202e 100644 --- a/Esyur/Net/IIP/DistributedPropertyContext.cs +++ b/Esyur/Net/IIP/DistributedPropertyContext.cs @@ -20,5 +20,8 @@ namespace Esyur.Net.IIP { this.Method = method; } + + public static implicit operator DistributedPropertyContext(Func method) + => new DistributedPropertyContext(method); } } diff --git a/Esyur/Net/IIP/DistributedResource.cs b/Esyur/Net/IIP/DistributedResource.cs index 13b39eb..b34e353 100644 --- a/Esyur/Net/IIP/DistributedResource.cs +++ b/Esyur/Net/IIP/DistributedResource.cs @@ -214,7 +214,7 @@ namespace Esyur.Net.IIP { var et = Instance.Template.GetEventTemplateByIndex(index); events[index]?.Invoke(this, args); - Instance.EmitResourceEvent(null, null, et.Name, args); + Instance.EmitResourceEvent(et.Name, args); } public AsyncReply _InvokeByNamedArguments(byte index, Structure namedArgs) diff --git a/Esyur/Net/IIP/DistributedServer.cs b/Esyur/Net/IIP/DistributedServer.cs index f1e5243..8064417 100644 --- a/Esyur/Net/IIP/DistributedServer.cs +++ b/Esyur/Net/IIP/DistributedServer.cs @@ -140,11 +140,7 @@ namespace Esyur.Net.IIP protected override void ClientDisconnected(DistributedConnection sender) { - sender.Destroy(); - Warehouse.Remove(sender); - - //Console.WriteLine("DistributedConnection Client Disconnected"); } } } diff --git a/Esyur/Proxy/ResourceProxy.cs b/Esyur/Proxy/ResourceProxy.cs index 736acff..15888ad 100644 --- a/Esyur/Proxy/ResourceProxy.cs +++ b/Esyur/Proxy/ResourceProxy.cs @@ -29,6 +29,11 @@ namespace Esyur.Proxy public static Type GetBaseType(Type type) { + if (type.Assembly.IsDynamic) + return type.GetTypeInfo().BaseType; + else + return type; + if (type.FullName.Contains("Esyur.Proxy.T")) #if NETSTANDARD return type.GetTypeInfo().BaseType; diff --git a/Esyur/Resource/IResource.cs b/Esyur/Resource/IResource.cs index 1f2908a..98f1ffc 100644 --- a/Esyur/Resource/IResource.cs +++ b/Esyur/Resource/IResource.cs @@ -44,5 +44,7 @@ namespace Esyur.Resource get; set; } + + } } diff --git a/Esyur/Resource/Instance.cs b/Esyur/Resource/Instance.cs index d2b6b19..c8913ef 100644 --- a/Esyur/Resource/Instance.cs +++ b/Esyur/Resource/Instance.cs @@ -20,6 +20,8 @@ namespace Esyur.Resource { string name; + // public int IntVal { get; set; } + WeakReference resource; IStore store; ResourceTemplate template; @@ -27,11 +29,15 @@ namespace Esyur.Resource public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue); - public delegate void ResourceEventOccurredEvent(IResource resource, object issuer, Session[] receivers, string eventName, object[] args); + public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, object[] args); + + public delegate void CustomResourceEventOccurredEvent(IResource resource, object issuer, Func receivers, string eventName, object[] args); + public delegate void ResourceDestroyedEvent(IResource resource); public event ResourceModifiedEvent ResourceModified; public event ResourceEventOccurredEvent ResourceEventOccurred; + public event CustomResourceEventOccurredEvent CustomResourceEventOccurred; public event ResourceDestroyedEvent ResourceDestroyed; bool loading = false; @@ -582,13 +588,21 @@ namespace Esyur.Resource // internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args) - internal void EmitResourceEvent(object issuer, Session[] receivers, string name, object[] args) + internal void EmitCustomResourceEvent(object issuer, Func receivers, string name, object[] args) { IResource res; if (this.resource.TryGetTarget(out res)) { + CustomResourceEventOccurred?.Invoke(res, issuer, receivers, name, args); + } + } - ResourceEventOccurred?.Invoke(res, issuer, receivers, name, args); + internal void EmitResourceEvent(string name, object[] args) + { + IResource res; + if (this.resource.TryGetTarget(out res)) + { + ResourceEventOccurred?.Invoke(res, name, args); } } @@ -891,7 +905,7 @@ namespace Esyur.Resource // if (ca.Length == 0) // continue; - ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args); + ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(evt.Name, args); evt.Info.AddEventHandler(resource, proxyDelegate); } @@ -901,7 +915,7 @@ namespace Esyur.Resource //if (ca.Length == 0) // continue; - CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitResourceEvent(issuer, receivers, evt.Name, args); + CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt.Name, args); evt.Info.AddEventHandler(resource, proxyDelegate); } diff --git a/Esyur/Resource/ResourceEventHandler.cs b/Esyur/Resource/ResourceEventHandler.cs index 75f5015..d86ff9c 100644 --- a/Esyur/Resource/ResourceEventHandler.cs +++ b/Esyur/Resource/ResourceEventHandler.cs @@ -34,11 +34,11 @@ using System.Threading.Tasks; namespace Esyur.Resource { public delegate void ResourceEventHanlder(params object[] args); - // public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args); + // public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args); //public delegate void CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args); //public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args); - public delegate void CustomResourceEventHanlder(object issuer, Session[] receivers, params object[] args); + public delegate void CustomResourceEventHanlder(object issuer, Func receivers, params object[] args);// object issuer, Session[] receivers, params object[] args); // public delegate void CustomReceiversEventHanlder(string[] usernames, DistributedConnection[] connections, params object[] args); diff --git a/Esyur/Resource/Warehouse.cs b/Esyur/Resource/Warehouse.cs index 527def1..2fe8c7f 100644 --- a/Esyur/Resource/Warehouse.cs +++ b/Esyur/Resource/Warehouse.cs @@ -115,6 +115,9 @@ namespace Esyur.Resource /// True, if no problem occurred. public static async AsyncReply Open() { + if (warehouseIsOpen) + return false; + warehouseIsOpen = true; var resSnap = resources.Select(x => @@ -526,7 +529,7 @@ namespace Esyur.Resource } - public static IResource New(Type type, string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null) + public static IResource New(Type type, string name = null, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null) { type = ResourceProxy.GetProxy(type); @@ -618,12 +621,15 @@ namespace Esyur.Resource /// Resource template. public static ResourceTemplate GetTemplate(Type type) { + + var baseType = ResourceProxy.GetBaseType(type); + // loaded ? foreach (var t in templates.Values) - if (t.ClassName == type.FullName) + if (t.ClassName == baseType.FullName) return t; - var template = new ResourceTemplate(type); + var template = new ResourceTemplate(baseType); templates.Add(template.ClassId, template); return template;