-
-
Save ddpruitt/5022ea47604bba2ecc01724d104c2999 to your computer and use it in GitHub Desktop.
C# Observable HTTP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using System.Collections.Immutable; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Reactive; | |
using System.Reactive.Concurrency; | |
using System.Reactive.Disposables; | |
using System.Reactive.Joins; | |
using System.Reactive.Linq; | |
using System.Reactive.Subjects; | |
using System.Reactive.Threading.Tasks; | |
using System.Web; | |
class UserService | |
{ | |
public UserService(Http http) => this.http = http; | |
public IObservable<UserWithAvatar> GetUserWithAvatar(int userId) => | |
from response in http.Get($"api/users/{userId}") | |
from user in JsonConvert.DeserializeObject<JObject>(response.Data) | |
from avatarResponse in http.Get($"api/avatars/{user["AvatarId"]}") | |
from avatar in JsonConvert.DeserializeObject<Avatar>(avatarResponse.Data) | |
into avatarStream | |
from avatar in avatarStream | |
select new UserWithAvatar | |
{ | |
Id = (int)user["Id"], | |
Avatar = avatar, | |
AvatarId = avatar.Id | |
} into x | |
from y in x | |
select y | |
readonly Http http; | |
} | |
class Http | |
{ | |
public Http(HttpClient http) => this.http = http; | |
readonly HttpClient http; | |
public IObservable<ObservableHttpResponseMessage> Get(string url) => Observable.FromAsync(async() => | |
{ | |
var response = await this.http.GetAsync(url); | |
var data = await response.Content.ReadAsStringAsync(); | |
return new ObservableHttpResponseMessage | |
{ | |
Data = data | |
}; | |
}); | |
public class ObservableHttpResponseMessage | |
{ | |
public string Data { get; set; } | |
} | |
} | |
static class JsonConvert | |
{ | |
public static IObservable<T> DeserializeObject<T>(string value) => | |
Observable.FromAsync(async () => | |
{ | |
using (var memoryStream = new MemoryStream(value.Select(x => (byte)x).ToArray())) | |
using (var streamReader = new StreamReader(memoryStream)) | |
using (var jsonReader = new JsonTextReader(streamReader)) | |
{ | |
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(await jsonReader.ReadAsStringAsync()); | |
} | |
}); | |
} | |
class User | |
{ | |
public int Id { get; set; } | |
} | |
class Avatar | |
{ | |
public int Id { get; set; } | |
} | |
interface IAvatarBearer | |
{ | |
Avatar Avatar { get; set; } | |
int Id { get; set; } | |
} | |
class UserWithAvatar : User, IAvatarBearer | |
{ | |
public Avatar Avatar { get; set; } | |
public int AvatarId { get; set; } | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment