mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-06-27 13:33:13 +00:00
1.5
This commit is contained in:
18
Esyur/Resource/AnnotationAttribute.cs
Normal file
18
Esyur/Resource/AnnotationAttribute.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event)]
|
||||
public class AnnotationAttribute : Attribute
|
||||
{
|
||||
|
||||
public string Annotation { get; set; }
|
||||
public AnnotationAttribute(string annotation)
|
||||
{
|
||||
this.Annotation = annotation;
|
||||
}
|
||||
}
|
||||
}
|
@ -31,10 +31,10 @@ namespace Esyur.Resource
|
||||
{
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ResourceAttribute : System.Attribute
|
||||
public class AttributeAttribute : System.Attribute
|
||||
{
|
||||
|
||||
public ResourceAttribute()
|
||||
public AttributeAttribute()
|
||||
{
|
||||
|
||||
}
|
@ -176,7 +176,8 @@ namespace Esyur.Resource
|
||||
|
||||
if (at != null)
|
||||
if (at.Info.CanWrite)
|
||||
at.Info.SetValue(res, kv.Value);
|
||||
at.Info.SetValue(res, DC.CastConvert(kv.Value, at.Info.PropertyType));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -442,7 +443,7 @@ namespace Esyur.Resource
|
||||
IResource res;
|
||||
if (resource.TryGetTarget(out res))
|
||||
{
|
||||
var rt = pt.Serilize ? pt.Info.GetValue(res, null) : null;
|
||||
var rt = pt.Info.GetValue(res, null);// pt.Serilize ? pt.Info.GetValue(res, null) : null;
|
||||
|
||||
props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
|
||||
}
|
||||
@ -546,13 +547,14 @@ namespace Esyur.Resource
|
||||
ages[pt.Index] = instanceAge;
|
||||
modificationDates[pt.Index] = now;
|
||||
|
||||
if (pt.Storage == StorageMode.NonVolatile)
|
||||
{
|
||||
store.Modify(res, pt.Name, value, ages[pt.Index], now);
|
||||
}
|
||||
else if (pt.Storage == StorageMode.Recordable)
|
||||
if (pt.Recordable)
|
||||
{
|
||||
store.Record(res, pt.Name, value, ages[pt.Index], now);
|
||||
|
||||
}
|
||||
else //if (pt.Storage == StorageMode.Recordable)
|
||||
{
|
||||
store.Modify(res, pt.Name, value, ages[pt.Index], now);
|
||||
}
|
||||
|
||||
ResourceModified?.Invoke(res, pt.Name, value);
|
||||
@ -839,7 +841,7 @@ namespace Esyur.Resource
|
||||
this.store = store;
|
||||
this.resource = new WeakReference<IResource>(resource);
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.name = name ?? "";
|
||||
this.instanceAge = age;
|
||||
|
||||
//this.attributes = new KeyList<string, object>(this);
|
||||
@ -875,30 +877,32 @@ namespace Esyur.Resource
|
||||
var events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
|
||||
foreach (var evt in events)
|
||||
|
||||
foreach (var evt in template.Events)
|
||||
{
|
||||
//if (evt.EventHandlerType != typeof(ResourceEventHanlder))
|
||||
// continue;
|
||||
|
||||
|
||||
if (evt.EventHandlerType == typeof(ResourceEventHanlder))
|
||||
|
||||
if (evt.Info.EventHandlerType == typeof(ResourceEventHanlder))
|
||||
{
|
||||
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
if (ca.Length == 0)
|
||||
continue;
|
||||
|
||||
// var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
// if (ca.Length == 0)
|
||||
// continue;
|
||||
|
||||
ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args);
|
||||
evt.AddEventHandler(resource, proxyDelegate);
|
||||
evt.Info.AddEventHandler(resource, proxyDelegate);
|
||||
|
||||
}
|
||||
else if (evt.EventHandlerType == typeof(CustomResourceEventHanlder))
|
||||
else if (evt.Info.EventHandlerType == typeof(CustomResourceEventHanlder))
|
||||
{
|
||||
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
if (ca.Length == 0)
|
||||
continue;
|
||||
//var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
//if (ca.Length == 0)
|
||||
// continue;
|
||||
|
||||
CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitResourceEvent(issuer, receivers, evt.Name, args);
|
||||
evt.AddEventHandler(resource, proxyDelegate);
|
||||
evt.Info.AddEventHandler(resource, proxyDelegate);
|
||||
}
|
||||
|
||||
|
||||
|
11
Esyur/Resource/PrivateAttribute.cs
Normal file
11
Esyur/Resource/PrivateAttribute.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
public class PrivateAttribute:Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
22
Esyur/Resource/PublicAttribute.cs
Normal file
22
Esyur/Resource/PublicAttribute.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)]
|
||||
|
||||
public class PublicAttribute : Attribute
|
||||
{
|
||||
|
||||
// public StorageMode Storage { get; set; }
|
||||
|
||||
//public bool Serialize { get; set; }
|
||||
|
||||
public PublicAttribute()//StorageMode storage = StorageMode.NonVolatile, bool serialize = true)
|
||||
{
|
||||
// Storage = storage;
|
||||
//Serialize = serialize;
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ namespace Esyur.Resource
|
||||
return new AsyncReply<bool>(true);
|
||||
}
|
||||
|
||||
public virtual bool Create()
|
||||
protected virtual bool Create()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
16
Esyur/Resource/StorageAttribute.cs
Normal file
16
Esyur/Resource/StorageAttribute.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class StorageAttribute:Attribute
|
||||
{
|
||||
public StorageMode Mode { get; set; }
|
||||
public StorageAttribute(StorageMode mode)
|
||||
{
|
||||
Mode = mode;
|
||||
}
|
||||
}
|
||||
}
|
57
Esyur/Resource/StoreGeneric.cs
Normal file
57
Esyur/Resource/StoreGeneric.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Esyur.Core;
|
||||
using Esyur.Data;
|
||||
using Esyur.Resource.Template;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
public abstract class Store<T> : IStore where T:IResource
|
||||
{
|
||||
public Instance Instance { get; set; }
|
||||
|
||||
public event DestroyedEvent OnDestroy;
|
||||
|
||||
public abstract AsyncReply<bool> AddChild(IResource parent, IResource child);
|
||||
|
||||
public abstract AsyncReply<bool> AddParent(IResource child, IResource parent);
|
||||
|
||||
public abstract AsyncBag<T1> Children<T1>(IResource resource, string name) where T1 : IResource;
|
||||
|
||||
public virtual void Destroy()
|
||||
{
|
||||
OnDestroy?.Invoke(this);
|
||||
}
|
||||
|
||||
public abstract AsyncReply<IResource> Get(string path);
|
||||
|
||||
public abstract AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate);
|
||||
|
||||
|
||||
public abstract string Link(IResource resource);
|
||||
|
||||
public abstract bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
||||
|
||||
public abstract AsyncBag<T1> Parents<T1>(IResource resource, string name) where T1 : IResource;
|
||||
|
||||
public abstract AsyncReply<bool> Put(IResource resource);
|
||||
|
||||
public abstract bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
||||
|
||||
public abstract bool Remove(IResource resource);
|
||||
|
||||
public abstract AsyncReply<bool> RemoveChild(IResource parent, IResource child);
|
||||
|
||||
public abstract AsyncReply<bool> RemoveParent(IResource child, IResource parent);
|
||||
|
||||
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||
|
||||
public T New(string name = null, object attributes = null, object properties = null)
|
||||
{
|
||||
var resource = Warehouse.New<T>(name, this, null, null, attributes, properties);
|
||||
resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray());
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -15,6 +16,8 @@ namespace Esyur.Resource.Template
|
||||
set;
|
||||
}
|
||||
|
||||
public EventInfo Info { get; set; }
|
||||
|
||||
public override byte[] Compose()
|
||||
{
|
||||
var name = base.Compose();
|
||||
@ -39,7 +42,7 @@ namespace Esyur.Resource.Template
|
||||
}
|
||||
|
||||
|
||||
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion)
|
||||
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion = null)
|
||||
:base(template, MemberType.Property, index, name)
|
||||
{
|
||||
this.Expansion = expansion;
|
||||
|
@ -45,7 +45,7 @@ namespace Esyur.Resource.Template
|
||||
}
|
||||
|
||||
|
||||
public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion)
|
||||
public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion = null)
|
||||
:base(template, MemberType.Property, index, name)
|
||||
{
|
||||
this.IsVoid = isVoid;
|
||||
|
@ -24,10 +24,12 @@ namespace Esyur.Resource.Template
|
||||
set;
|
||||
}
|
||||
|
||||
/*
|
||||
public bool Serilize
|
||||
{
|
||||
get;set;
|
||||
}
|
||||
*/
|
||||
//bool ReadOnly;
|
||||
//IIPTypes::DataType ReturnType;
|
||||
public PropertyPermission Permission {
|
||||
@ -35,18 +37,19 @@ namespace Esyur.Resource.Template
|
||||
set;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
public bool Recordable
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}*/
|
||||
}
|
||||
|
||||
public StorageMode Storage
|
||||
/*
|
||||
public PropertyType Mode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}*/
|
||||
|
||||
public string ReadExpansion
|
||||
{
|
||||
@ -71,7 +74,7 @@ namespace Esyur.Resource.Template
|
||||
public override byte[] Compose()
|
||||
{
|
||||
var name = base.Compose();
|
||||
var pv = ((byte)(Permission) << 1) | (Storage == StorageMode.Recordable ? 1 : 0);
|
||||
var pv = ((byte)(Permission) << 1) | (Recordable ? 1 : 0);
|
||||
|
||||
if (WriteExpansion != null && ReadExpansion != null)
|
||||
{
|
||||
@ -117,11 +120,11 @@ namespace Esyur.Resource.Template
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public PropertyTemplate(ResourceTemplate template, byte index, string name, string read, string write, StorageMode storage)
|
||||
public PropertyTemplate(ResourceTemplate template, byte index, string name, string read = null, string write = null, bool recordable = false)
|
||||
:base(template, MemberType.Property, index, name)
|
||||
{
|
||||
//this.Recordable = recordable;
|
||||
this.Storage = storage;
|
||||
this.Recordable = recordable;
|
||||
//this.Storage = storage;
|
||||
this.ReadExpansion = read;
|
||||
this.WriteExpansion = write;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using Esyur.Data;
|
||||
using Esyur.Core;
|
||||
using System.Security.Cryptography;
|
||||
using Esyur.Proxy;
|
||||
using Esyur.Net.IIP;
|
||||
|
||||
namespace Esyur.Resource.Template
|
||||
{
|
||||
@ -159,52 +160,87 @@ namespace Esyur.Resource.Template
|
||||
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
|
||||
//byte currentIndex = 0;
|
||||
|
||||
bool classIsPublic = type.GetCustomAttribute<PublicAttribute>() != null;
|
||||
|
||||
byte i = 0;
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
if (classIsPublic)
|
||||
{
|
||||
var rp = pi.GetCustomAttribute<ResourceProperty>(true);
|
||||
|
||||
if (rp != null)
|
||||
{
|
||||
var pt = new PropertyTemplate(this, i++, pi.Name, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
||||
pt.Info = pi;
|
||||
pt.Serilize = rp.Serialize;
|
||||
properties.Add(pt);
|
||||
}
|
||||
|
||||
var ra = pi.GetCustomAttribute<ResourceAttribute>(true);
|
||||
|
||||
if (ra != null)
|
||||
{
|
||||
var at = new AttributeTemplate(this, i++, pi.Name);
|
||||
at.Info = pi;
|
||||
attributes.Add(at);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
else
|
||||
{
|
||||
var es = ei.GetCustomAttributes<ResourceEvent>(true).ToArray();
|
||||
if (es.Length > 0)
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
{
|
||||
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
||||
events.Add(et);
|
||||
var publicAttr = pi.GetCustomAttribute<PublicAttribute>(true);
|
||||
|
||||
if (publicAttr != null)
|
||||
{
|
||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||
|
||||
var pt = new PropertyTemplate(this, i++, pi.Name);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
||||
if (storageAttr != null)
|
||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
||||
|
||||
if (annotationAttr != null)
|
||||
pt.ReadExpansion = annotationAttr.Annotation;
|
||||
else
|
||||
pt.ReadExpansion = pi.PropertyType.Name;
|
||||
|
||||
pt.Info = pi;
|
||||
//pt.Serilize = publicAttr.Serialize;
|
||||
properties.Add(pt);
|
||||
}
|
||||
else
|
||||
{
|
||||
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
|
||||
if (attributeAttr != null)
|
||||
{
|
||||
var at = new AttributeTemplate(this, 0, pi.Name);
|
||||
at.Info = pi;
|
||||
attributes.Add(at);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var fs = mi.GetCustomAttributes<ResourceFunction>(true).ToArray();
|
||||
if (fs.Length > 0)
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
{
|
||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
||||
functions.Add(ft);
|
||||
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
||||
if (publicAttr != null)
|
||||
{
|
||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
|
||||
var et = new EventTemplate(this, i++, ei.Name);
|
||||
et.Info = ei;
|
||||
|
||||
if (annotationAttr != null)
|
||||
et.Expansion = annotationAttr.Annotation;
|
||||
|
||||
events.Add(et);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||
if (publicAttr != null)
|
||||
{
|
||||
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||
|
||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void));
|
||||
|
||||
if (annotationAttr != null)
|
||||
ft.Expansion = annotationAttr.Annotation;
|
||||
else
|
||||
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x=>x.ParameterType != typeof(DistributedConnection)).Select(x=> "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
||||
functions.Add(ft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +359,7 @@ namespace Esyur.Resource.Template
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile);
|
||||
var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable);
|
||||
|
||||
od.properties.Add(pt);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ using System.Threading.Tasks;
|
||||
using Esyur.Net.IIP;
|
||||
using System.Text.RegularExpressions;
|
||||
using Esyur.Misc;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Esyur.Resource
|
||||
{
|
||||
@ -43,8 +44,11 @@ namespace Esyur.Resource
|
||||
{
|
||||
//static byte prefixCounter;
|
||||
|
||||
static AutoList<IStore, Instance> stores = new AutoList<IStore, Instance>(null);
|
||||
static Dictionary<uint, WeakReference<IResource>> resources = new Dictionary<uint, WeakReference<IResource>>();
|
||||
//static AutoList<IStore, Instance> stores = new AutoList<IStore, Instance>(null);
|
||||
static ConcurrentDictionary<uint, WeakReference<IResource>> resources = new ConcurrentDictionary<uint, WeakReference<IResource>>();
|
||||
static ConcurrentDictionary<IStore, List<WeakReference<IResource>>> stores = new ConcurrentDictionary<IStore, List<WeakReference<IResource>>>();
|
||||
|
||||
|
||||
static uint resourceCounter = 0;
|
||||
|
||||
static KeyList<Guid, ResourceTemplate> templates = new KeyList<Guid, ResourceTemplate>();
|
||||
@ -61,7 +65,7 @@ namespace Esyur.Resource
|
||||
|
||||
private static Regex urlRegex = new Regex(@"^(?:([\S]*)://([^/]*)/?)");
|
||||
|
||||
private static object resourcesLock = new object();
|
||||
//private static object resourcesLock = new object();
|
||||
|
||||
static KeyList<string, Func<IStore>> getSupportedProtocols()
|
||||
{
|
||||
@ -78,8 +82,8 @@ namespace Esyur.Resource
|
||||
public static IStore GetStore(string name)
|
||||
{
|
||||
foreach (var s in stores)
|
||||
if (s.Instance.Name == name)
|
||||
return s as IStore;
|
||||
if (s.Key.Instance.Name == name)
|
||||
return s.Key;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -113,22 +117,28 @@ namespace Esyur.Resource
|
||||
{
|
||||
warehouseIsOpen = true;
|
||||
|
||||
var resSnap = resources.Select(x => {
|
||||
IResource r;
|
||||
var resSnap = resources.Select(x =>
|
||||
{
|
||||
IResource r;
|
||||
if (x.Value.TryGetTarget(out r))
|
||||
return r;
|
||||
else
|
||||
return null;
|
||||
}).Where(r=>r!=null).ToArray();
|
||||
}).Where(r => r != null).ToArray();
|
||||
|
||||
foreach (var r in resSnap)
|
||||
{
|
||||
//IResource r;
|
||||
//if (rk.Value.TryGetTarget(out r))
|
||||
//{
|
||||
var rt = await r.Trigger(ResourceTrigger.Initialize);
|
||||
if (!rt)
|
||||
return false;
|
||||
var rt = await r.Trigger(ResourceTrigger.Initialize);
|
||||
//if (!rt)
|
||||
// return false;
|
||||
|
||||
if (!rt)
|
||||
{
|
||||
Console.WriteLine($"Resource failed at Initialize {r.Instance.Name} [{r.Instance.Template.ClassName}]");
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
@ -137,9 +147,12 @@ namespace Esyur.Resource
|
||||
//IResource r;
|
||||
//if (rk.Value.TryGetTarget(out r))
|
||||
//{
|
||||
var rt = await r.Trigger(ResourceTrigger.SystemInitialized);
|
||||
if (!rt)
|
||||
return false;
|
||||
var rt = await r.Trigger(ResourceTrigger.SystemInitialized);
|
||||
if (!rt)
|
||||
{
|
||||
Console.WriteLine($"Resource failed at SystemInitialized {r.Instance.Name} [{r.Instance.Template.ClassName}]");
|
||||
}
|
||||
//return false;
|
||||
//}
|
||||
}
|
||||
|
||||
@ -217,7 +230,7 @@ namespace Esyur.Resource
|
||||
}
|
||||
|
||||
foreach (var store in stores)
|
||||
bag.Add(store.Trigger(ResourceTrigger.Terminate));
|
||||
bag.Add(store.Key.Trigger(ResourceTrigger.Terminate));
|
||||
|
||||
|
||||
foreach (var resource in resources.Values)
|
||||
@ -232,7 +245,7 @@ namespace Esyur.Resource
|
||||
|
||||
|
||||
foreach (var store in stores)
|
||||
bag.Add(store.Trigger(ResourceTrigger.SystemTerminated));
|
||||
bag.Add(store.Key.Trigger(ResourceTrigger.SystemTerminated));
|
||||
|
||||
bag.Seal();
|
||||
|
||||
@ -318,7 +331,7 @@ namespace Esyur.Resource
|
||||
var p = path.Trim().Split('/');
|
||||
IResource resource;
|
||||
|
||||
foreach (var store in stores)
|
||||
foreach (var store in stores.Keys)
|
||||
if (p[0] == store.Instance.Name)
|
||||
{
|
||||
|
||||
@ -433,19 +446,26 @@ namespace Esyur.Resource
|
||||
if (resource.Instance != null)
|
||||
throw new Exception("Resource has a store.");
|
||||
|
||||
var resourceReference = new WeakReference<IResource>(resource);
|
||||
|
||||
if (store == null)
|
||||
{
|
||||
// assign parent as a store
|
||||
if (parent is IStore)
|
||||
{
|
||||
store = (IStore)parent;
|
||||
stores[store].Add(resourceReference);
|
||||
}
|
||||
// assign parent's store as a store
|
||||
else if (parent != null)
|
||||
{
|
||||
store = parent.Instance.Store;
|
||||
stores[store].Add(resourceReference);
|
||||
}
|
||||
// assign self as a store (root store)
|
||||
else if (resource is IStore)
|
||||
{
|
||||
store = (IStore)resource;
|
||||
stores.Add(resource as IStore);
|
||||
}
|
||||
else
|
||||
throw new Exception("Can't find a store for the resource.");
|
||||
@ -475,10 +495,13 @@ namespace Esyur.Resource
|
||||
|
||||
|
||||
if (resource is IStore)
|
||||
{
|
||||
stores.TryAdd(resource as IStore, new List<WeakReference<IResource>>());
|
||||
StoreConnected?.Invoke(resource as IStore, name);
|
||||
}
|
||||
//else
|
||||
|
||||
|
||||
|
||||
store.Put(resource);
|
||||
|
||||
|
||||
@ -493,15 +516,17 @@ namespace Esyur.Resource
|
||||
var t = resource.GetType();
|
||||
Global.Counters["T-" + t.Namespace + "." + t.Name]++;
|
||||
|
||||
lock (resourcesLock)
|
||||
resources.Add(resource.Instance.Id, new WeakReference<IResource>(resource));
|
||||
//var wr = new WeakReference<IResource>(resource);
|
||||
|
||||
//lock (resourcesLock)
|
||||
resources.TryAdd(resource.Instance.Id, resourceReference);
|
||||
|
||||
if (warehouseIsOpen)
|
||||
resource.Trigger(ResourceTrigger.Initialize);
|
||||
|
||||
}
|
||||
|
||||
public static IResource New(Type type, string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null)
|
||||
public static IResource New(Type type, string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
||||
{
|
||||
type = ResourceProxy.GetProxy(type);
|
||||
|
||||
@ -539,9 +564,12 @@ namespace Esyur.Resource
|
||||
*/
|
||||
var res = Activator.CreateInstance(type) as IResource;
|
||||
|
||||
|
||||
if (properties != null)
|
||||
{
|
||||
foreach (var p in properties)
|
||||
var ps = Structure.FromObject(properties);
|
||||
|
||||
foreach (var p in ps)
|
||||
{
|
||||
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||
if (pi != null)
|
||||
@ -556,10 +584,10 @@ namespace Esyur.Resource
|
||||
|
||||
}
|
||||
|
||||
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null)
|
||||
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null)
|
||||
where T : IResource
|
||||
{
|
||||
return (T)New(typeof(T), name, store, parent, manager, attributes, arguments, properties);
|
||||
return (T)New(typeof(T), name, store, parent, manager, attributes, properties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -619,31 +647,45 @@ namespace Esyur.Resource
|
||||
|
||||
public static bool Remove(IResource resource)
|
||||
{
|
||||
|
||||
|
||||
if (resource.Instance == null)
|
||||
return false;
|
||||
|
||||
//lock (resourcesLock)
|
||||
//{
|
||||
|
||||
WeakReference<IResource> resourceReference;
|
||||
|
||||
if (resources.ContainsKey(resource.Instance.Id))
|
||||
lock(resourcesLock)
|
||||
resources.Remove(resource.Instance.Id);
|
||||
resources.TryRemove(resource.Instance.Id, out resourceReference);
|
||||
else
|
||||
return false;
|
||||
//}
|
||||
|
||||
if (resource != resource.Instance.Store)
|
||||
stores[resource.Instance.Store].Remove(resourceReference);
|
||||
|
||||
if (resource is IStore)
|
||||
{
|
||||
stores.Remove(resource as IStore);
|
||||
var store = resource as IStore;
|
||||
|
||||
WeakReference<IResource>[] toBeRemoved;
|
||||
List<WeakReference<IResource>> toBeRemoved;// = stores[store];
|
||||
|
||||
stores.TryRemove(store, out toBeRemoved);
|
||||
|
||||
//lock (resourcesLock)
|
||||
//{
|
||||
// // remove all objects associated with the store
|
||||
// toBeRemoved = resources.Values.Where(x =>
|
||||
// {
|
||||
// IResource r;
|
||||
// if (x.TryGetTarget(out r))
|
||||
// return r.Instance.Store == resource;
|
||||
// else
|
||||
// return false;
|
||||
// }).ToArray();
|
||||
//}
|
||||
|
||||
lock (resourcesLock)
|
||||
{
|
||||
// remove all objects associated with the store
|
||||
toBeRemoved = resources.Values.Where(x =>
|
||||
{
|
||||
IResource r;
|
||||
return x.TryGetTarget(out r) && r.Instance.Store == resource;
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
foreach (var o in toBeRemoved)
|
||||
{
|
||||
|
Reference in New Issue
Block a user