예제 #1
0
        public Task<IServiceResponse<int>> InsertMyObject(IServiceRequest<MyObject> obj)
        {
            obj.MustNotBeNull("obj");

            return Task.Factory.StartNew(() =>
            {
                using (var repo = new ExampleRepo())
                {
                    var toInsert = Mapper.Map<MyEntity>(obj.Argument);
                    try
                    {
                        repo.MyEntities.Insert(toInsert);
                    }
                    catch (Exception ex)
                    {
                        //yes - catching all exceptions is not good - but this is just demonstrating how you might use the exception to
                        //generate a failed response that automatically has the exception on it.

                        //IN SOME CASES, your service layer operations will bubble their exceptions out, of course - it all depends
                        //on how you want to handle it.
                        return ex.AsFailedResponse<int>();
                    }

                    return toInsert.Id.AsSuccessfulResponse();
                }
            });
        }
예제 #2
0
 public async System.Threading.Tasks.Task<IServiceResponse<MyObject>> GetMyObject(IServiceRequest<int> id)
 {
     // so we use the same validation mechanism that's used over in the Direct service implementation in
     // ../WebAPIDemos.ServiceLayer.Direct/MyObjectService.cs
     id.MustNotBeNull("id");
     //note - I'm using await here to handle the implicit casting of ApiServiceResponse<T> to IServiceResponse<T>
     return await _requestManager.Get<ApiServiceResponse<MyObject>>(string.Format("api/MyObjects/{0}", id.Argument.ToString()), id);
 }
        //note - for testability - a better implementation of this service would accept an IServiceCache abstraction
        //(name is actually irrelevant - it'd be a proprietary type for this solution),
        //and then one implementation of that would operate over the HostingEnvironment.Cache; making it
        //possible to isolate this class in a unit test with a mocked IServiceCache implementation.

        public async System.Threading.Tasks.Task<IServiceResponse<MyObject>> GetMyObject(IServiceRequest<int> id)
        {
            id.MustNotBeNull("id");
            string cacheKey = MyObjectCacheKey(id.Argument);
            //do caching 
            MyObject cached = (MyObject)HostingEnvironment.Cache[cacheKey];
            if (cached != null)
                return cached.AsSuccessfulResponse();

            //try and retrieve the object from the inner service.  The logic here is if we get a successful response, then 
            //we will cache it.  Otherwise we will simply return the response.  So, crucially, failed lookups are never cached in
            //this implementation - which, in practise, might not be desirable.
            var response = await _inner.GetMyObject(id);

            if (response.Success)
                HostingEnvironment.Cache.Insert(cacheKey, response.Result, null, DateTime.UtcNow.AddMinutes(5), System.Web.Caching.Cache.NoSlidingExpiration);

            return response;
        }
예제 #4
0
        public Task<IServiceResponse<MyObject>> GetMyObject(IServiceRequest<int> id)
        {
            id.MustNotBeNull("id");

            MyObject foo = null;

            //return Task.FromResult(foo.AsSuccessfulResponse());

            return Task.Factory.StartNew(() =>
            {
                using (var repo = new ExampleRepo())
                {
                    var found = Mapper.Map<MyObject>(repo.MyEntities.Fetch(id.Argument));

                    if (found != null)
                        return found.AsSuccessfulResponse();
                    else //could be nicer - ideally want a 'AsResponse' method that will auto-select success/fail based on not-null/null
                        return found.AsFailedResponse();
                }
            });
        }
예제 #5
0
        public async System.Threading.Tasks.Task<IServiceResponse<PagedResult<MyObject>>> QueryMyObjects(IServiceRequest<PagedQuery> query)
        {
            query.MustNotBeNull("query");
            
            //this method of query strings from object content can be refactored.  However, it will have to be a more complex solution
            //that is completely generic and handles nested objects in the same way that the server libraries expect to see.
            //for now, this merely demonstrates the core principle.
            Dictionary<string, string> queryKeyValues = new Dictionary<string, string>();
            //some system that relies on a similar mechanism to Model Binding should be used to convert to strings.  That uses
            //the TypeDescriptor.GetConverter mechanism, so we couuld do the same.
            queryKeyValues["Page"] = Convert.ToString(query.Argument.Page);
            queryKeyValues["PageSize"] = Convert.ToString(query.Argument.PageSize);
            string queryString = null;
            using (var tempContent = new FormUrlEncodedContent(queryKeyValues))
            {
                //why use this?  It handles the url encoding - and doesn't require System.Web (another popular
                //solution uses HttpUtility.ParseQueryString - but client code has no business referencing System.Web).
                queryString = await tempContent.ReadAsStringAsync();
            }

            return await _requestManager.Get<ApiServiceResponse<PagedResult<MyObject>>>(string.Concat("api/MyObjects?", queryString), query);
        }
예제 #6
0
 public async System.Threading.Tasks.Task<IServiceResponse<int>> InsertMyObject(IServiceRequest<MyObject> obj)
 {
     obj.MustNotBeNull("obj");
     return await _requestManager.Send<MyObject, ApiServiceResponse<int>>("api/MyObjects", HttpMethod.Post, obj);
 }
예제 #7
0
        public Task<IServiceResponse<PagedResult<MyObject>>> QueryMyObjects(IServiceRequest<PagedQuery> query)
        {
            query.MustNotBeNull("query");

            //just showing another way of 'faking' a task when there's no asynchrony actually involved:

            using (var repo = new ExampleRepo())
            {

                if (query.Argument.PageSize == -1) //get all
                {
                    var all = repo.MyEntities.All().ToArray();

                    var result = new PagedResult<MyObject>() { Count = all.Length, Page = 1, PageCount = 1, PageResults = Mapper.Map<MyEntity[], MyObject[]>(all), TotalCount = all.Length }.AsSuccessfulResponse();
                    return Task.FromResult(result);
                }
                else
                {
                    var total = repo.MyEntities.All().Count();
                    //to do - should be doing a bit more validation here...
                    var page = repo.MyEntities.All().Skip((query.Argument.Page - 1) * query.Argument.PageSize).Take(query.Argument.PageSize).ToArray();
                    var result = new PagedResult<MyObject>()
                    {
                        TotalCount = total,
                        Page = query.Argument.Page,
                        Count = page.Length,
                        PageCount = (int)Math.Round(((decimal)total / query.Argument.PageSize) + 0.5M),
                        PageResults = Mapper.Map<MyEntity[], MyObject[]>(page)
                    }.AsSuccessfulResponse();
                    return Task.FromResult(result);
                }

            }
        }