Exemplo n.º 1
0
        private static void MethodHandler(this ExpressApplication app, string urlPrefix,
                                          Func <object> serviceInstance, MethodInfo method, WebMethodAttribute meta)
        {
            // TODO support WebMethodAttribute options (caching, etc)
            var invoke = DynamicMethods.CompileMethod(method.DeclaringType, method);

            var parameters = method.GetParameters();

            if (parameters.Length == 0)
            {
                app.Get(
                    Combine(urlPrefix, method.Name),
                    req =>
                {
                    req.SetContext();
                    var result = invoke(serviceInstance(), new object[0]);
                    req.Json(result);
                });
            }
            else
            {
                app.Get(
                    Combine(urlPrefix, method.Name),
                    req =>
                {
                    req.SetContext();
                    var args   = ParseQueryArgs(req, parameters);
                    var result = invoke(serviceInstance(), args);
                    req.Json(result);
                });

                app.Post(
                    Combine(urlPrefix, method.Name),
                    req =>
                {
                    req.SetContext();
                    var args   = ParseArgs(req, parameters);
                    var result = invoke(serviceInstance(), args);
                    req.Json(result);
                });
            }
        }
Exemplo n.º 2
0
        private static ExpressApplication RestImpl(this ExpressApplication app,
                                                   string url, Type type, Func <int> nextIndex,
                                                   Func <RequestContext, object> getInstance,
                                                   Func <RequestContext, object> getModel)
        {
            app.Get(url, req => req.Json(getInstance(req)));

            var props = type
                        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                        .Where(p => FilterProperty(p))
                        .ToList();

            props.ForEach(prop =>
            {
                var propertyUrl = Combine(url, prop.Name);
                var getter      = DynamicMethods.CompileGetter(type, prop);
                var setter      = DynamicMethods.CompileSetter(type, prop);

                Func <RequestContext, object> propertyInstance = req =>
                {
                    var instance = getInstance(req);
                    return(getter(instance));
                };

                app.Get(propertyUrl, req => req.Json(propertyInstance(req)));

                if (setter != null)
                {
                    app.Update(propertyUrl, req =>
                    {
                        req.SetContext();

                        var json       = req.ParseJson();
                        var hasChanges = ChangesDetector(req, getModel);
                        var instance   = getInstance(req);

                        // TODO get default value from metadata
                        var defval = GetDefaultValue(prop.PropertyType);
                        var value  = json.Get("value", defval, prop.PropertyType);

                        setter(instance, value);

                        req.Json(hasChanges() ? ModelPayload(req, getModel) : null);
                    });
                }

                if (IsCollection(prop.PropertyType))
                {
                    RestCollection(app, propertyUrl, prop.PropertyType, nextIndex, propertyInstance, getModel);
                }
                else if (IsObject(prop.PropertyType))
                {
                    RestImpl(app, propertyUrl, prop.PropertyType, nextIndex, propertyInstance, getModel);
                }
            });

            var methods = type
                          .GetMethods(BindingFlags.Public | BindingFlags.Instance)
                          .Where(m => m.GetAttribute <RestAttribute>(true) != null)
                          .ToList();

            methods.ForEach(method =>
            {
                var call = DynamicMethods.CompileMethod(type, method);

                app.Post(url, req =>
                {
                    req.SetContext();

                    var hasChanges = ChangesDetector(req, getModel);

                    var args       = req.ParseArgs(method.GetParameters());
                    var collection = getInstance(req);
                    var result     = call(collection, args);

                    req.Json(hasChanges() ? ModelPayload(req, getModel) : result);
                });
            });

            return(app);
        }
Exemplo n.º 3
0
        private static void RestCollection(this ExpressApplication app, string url, Type type, Func <int> nextIndex,
                                           Func <RequestContext, object> getInstance, Func <RequestContext, object> getModel)
        {
            var indexer   = DynamicMethods.CompileIndexer(type);
            var indexName = "i" + nextIndex();
            var indexUrl  = Combine(url, string.Format("{{{0}}}", indexName));

            Func <RequestContext, object> getItem = req =>
            {
                var index      = req.Param <int>(indexName);
                var collection = getInstance(req);
                return(indexer(collection, index));
            };

            if (indexer != null)
            {
                app.Get(indexUrl, req => req.Json(getItem(req)));
            }

            // TODO dispatch multiple Add methods
            var addMethod = type.GetMethod("Add");

            if (addMethod != null)
            {
                var add = DynamicMethods.CompileMethod(type, addMethod);
                app.Put(url, req =>
                {
                    req.SetContext();

                    var hasChanges = ChangesDetector(req, getModel);

                    var args       = req.ParseArgs(addMethod.GetParameters());
                    var collection = getInstance(req);
                    var result     = add(collection, args);

                    req.Json(hasChanges() ? ModelPayload(req, getModel) : result);
                });
            }

            var remove = DynamicMethods.CompileRemoveAt(type);

            if (remove != null)
            {
                app.Delete(indexUrl, req =>
                {
                    req.SetContext();
                    var hasChanges = ChangesDetector(req, getModel);
                    var index      = req.Param <int>(indexName);
                    var collection = getInstance(req);
                    var result     = remove(collection, index);
                    req.Json(hasChanges() ? ModelPayload(req, getModel) : result);
                });
            }

            var countProperty = type.GetProperty("Count", BindingFlags.Instance | BindingFlags.Public);

            if (countProperty != null && countProperty.GetIndexParameters().Length == 0)
            {
                var count = DynamicMethods.CompileGetter(type, countProperty);

                app.Get(Combine(url, "Count"), req =>
                {
                    var collection = getInstance(req);
                    req.Json(count(collection));
                });
            }

            var itemType = GetItemType(type);

            if (IsObject(itemType))
            {
                RestImpl(app, indexUrl, itemType, nextIndex, getItem, getModel);
            }
        }