示例#1
0
        /// <summary>
        /// Put a resource in the warehouse.
        /// </summary>
        /// <param name="resource">Resource instance.</param>
        /// <param name="name">Resource name.</param>
        /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
        /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
        public static void Put(IResource resource, string name, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null)
        {
            resource.Instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age);

            if (manager != null)
            {
                resource.Instance.Managers.Add(manager);
            }

            if (store == parent)
            {
                parent = null;
            }

            if (parent == null)
            {
                if (!(resource is IStore))
                {
                    store.Instance.Children.Add(resource);
                }
            }
            else
            {
                parent.Instance.Children.Add(resource);
            }



            if (resource is IStore)
            {
                stores.Add(resource as IStore);
                StoreConnected?.Invoke(resource as IStore, name);
            }
            else
            {
                store.Put(resource);
            }

            resources.Add(resource.Instance.Id, resource);

            if (!storeIsOpen)
            {
                resource.Trigger(ResourceTrigger.Initialize);
            }
        }
示例#2
0
    //public static async AsyncReply<T> Push<T>(string path, T resource) where T : IResource
    //{
    //    await Put(path, resource);
    //    return resource;
    //}

    /// <summary>
    /// Put a resource in the warehouse.
    /// </summary>
    /// <param name="name">Resource name.</param>
    /// <param name="resource">Resource instance.</param>
    /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
    /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
    public static async AsyncReply <T> Put <T>(string name, T resource, IStore store = null, IResource parent = null, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource
    {
        if (resource.Instance != null)
        {
            throw new Exception("Resource has a store.");
        }

        var path = name.TrimStart('/').Split('/');

        if (path.Length > 1)
        {
            if (parent != null)
            {
                throw new Exception("Parent can't be set when using path in instance name");
            }

            parent = await Warehouse.Get <IResource>(string.Join("/", path.Take(path.Length - 1)));

            if (parent == null)
            {
                throw new Exception("Can't find parent");
            }

            store = store ?? parent.Instance.Store;
        }

        var instanceName = path.Last();


        var resourceReference = new WeakReference <IResource>(resource);

        if (store == null)
        {
            // assign parent's store as a store
            if (parent != null)
            {
                // assign parent as a store
                if (parent is IStore)
                {
                    store = (IStore)parent;
                    List <WeakReference <IResource> > list;
                    if (stores.TryGetValue(store, out list))
                    {
                        lock (((ICollection)list).SyncRoot)
                            list.Add(resourceReference);
                    }
                    //stores[store].Add(resourceReference);
                }
                else
                {
                    store = parent.Instance.Store;

                    List <WeakReference <IResource> > list;
                    if (stores.TryGetValue(store, out list))
                    {
                        lock (((ICollection)list).SyncRoot)
                            list.Add(resourceReference);
                    }
                }
            }
            // assign self as a store (root store)
            else if (resource is IStore)
            {
                store = (IStore)resource;
            }
            else
            {
                throw new Exception("Can't find a store for the resource.");
            }
        }

        resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age);

        if (attributes != null)
        {
            resource.Instance.SetAttributes(Map <string, object> .FromObject(attributes));
        }

        if (manager != null)
        {
            resource.Instance.Managers.Add(manager);
        }

        if (store == parent)
        {
            parent = null;
        }



        try
        {
            if (resource is IStore)
            {
                stores.TryAdd(resource as IStore, new List <WeakReference <IResource> >());
            }


            if (!await store.Put(resource))
            {
                throw new Exception("Store failed to put the resource");
            }
            //return default(T);


            if (parent != null)
            {
                await parent.Instance.Store.AddChild(parent, resource);

                await store.AddParent(resource, parent);
            }

            var t = resource.GetType();
            Global.Counters["T-" + t.Namespace + "." + t.Name]++;


            resources.TryAdd(resource.Instance.Id, resourceReference);

            if (warehouseIsOpen)
            {
                await resource.Trigger(ResourceTrigger.Initialize);

                if (resource is IStore)
                {
                    await resource.Trigger(ResourceTrigger.Open);
                }
            }

            if (resource is IStore)
            {
                StoreConnected?.Invoke(resource as IStore);
            }
        }
        catch (Exception ex)
        {
            Warehouse.Remove(resource);
            throw ex;
        }

        return(resource);
    }