Bill Wagner 00491910a2 C# 7 language feature updates
Controllers/AccountController:
Replace single line methods with expression bodied members.
Includes constructor, C# 7 feature.

Controllers/CatalogController:
Remove unnecessary ToString() call.
Replace single line methods with expression bodied members.

Extensions/HttpClientExtensions:
Replace single line methods with expression bodied members.

Extensions/SessionExtensions:
Replace single line methods with expression bodied members.

Services/BasketService:
Remove unnecessary ToString() calls.
Add ?? to simplify conditional initialization
Use TryGetValue and out variable initialization to simplify Quantity
calculation

Services/CatalogService:
Use Value<T> generic method instead of dynamic types.
There is a lot of overhead for dynamic and it seems overkill here.

Services/IdentityParser:
Use the pattern matching is expression.
Refactor the LINQ queries to enumerate the collection (and create an
enumerator)
only once. The previous code had 3 enumerations.

Services/Utilities/HttpApiClient:
Remove the 'async' modifier and 'await' statements from methods where
the only asynchronous statement is the final statement of the method,
and
the task from the underlying method can be returned.

Services/Utilities/HttpApiClientWrapper:
Use expression bodied members where applicable.
Remove the 'async' modifier and 'await' statements from methods where
the only asynchronous statement is the final statement of the method,
and
the task from the underlying method can be returned.

ViewComponents/Cart:
Use expression bodied members where applicable.

ViewComponents/CartList:
Use expression bodied members where applicable.
Remove the 'async' modifier and 'await' statements from methods where
the only asynchronous statement is the final statement of the method,
and
the task from the underlying method can be returned.

ViewModels/Annotations/CardExpiration:
Use the out variable initializer to simplify the validation of the
card expiration date.

ViewModels/Basket:
Use property initializer syntax instead of constructor body

ViewModels/CatalogViewModels/IndexViewModel:
Use expression bodied property to return the calculated 'Disabled'
property

ViewModels/Order:
Use property initializer syntax.
2017-03-20 14:18:20 -04:00

131 lines
4.4 KiB
C#

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using WebMVC.Services.Utilities;
namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public class BasketService : IBasketService
{
private readonly IOptionsSnapshot<AppSettings> _settings;
private IHttpClient _apiClient;
private readonly string _remoteServiceBaseUrl;
private IHttpContextAccessor _httpContextAccesor;
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
{
_settings = settings;
_remoteServiceBaseUrl = _settings.Value.BasketUrl;
_httpContextAccesor = httpContextAccesor;
_apiClient = httpClient;
}
public async Task<Basket> GetBasket(ApplicationUser user)
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
var dataString = await _apiClient.GetStringAsync(basketUrl);
// Use the ?? Null conditional operator to simplify the initialization of response
var response = JsonConvert.DeserializeObject<Basket>(dataString) ??
new Basket()
{
BuyerId = user.Id
};
return response;
}
public async Task<Basket> UpdateBasket(Basket basket)
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = _remoteServiceBaseUrl;
var response = await _apiClient.PostAsync(basketUrl, basket);
return basket;
}
public async Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities)
{
var basket = await GetBasket(user);
basket.Items.ForEach(x =>
{
// Simplify this logic by using the
// new out variable initializer.
if (quantities.TryGetValue(x.Id, out var quantity))
{
x.Quantity = quantity;
}
});
return basket;
}
public Order MapBasketToOrder(Basket basket)
{
var order = new Order();
order.Total = 0;
basket.Items.ForEach(x =>
{
order.OrderItems.Add(new OrderItem()
{
ProductId = int.Parse(x.ProductId),
PictureUrl = x.PictureUrl,
ProductName = x.ProductName,
Units = x.Quantity,
UnitPrice = x.UnitPrice
});
order.Total += (x.Quantity * x.UnitPrice);
});
return order;
}
public async Task AddItemToBasket(ApplicationUser user, BasketItem product)
{
Basket basket = await GetBasket(user);
if (basket == null)
{
basket = new Basket()
{
BuyerId = user.Id,
Items = new List<BasketItem>()
};
}
basket.Items.Add(product);
await UpdateBasket(basket);
}
public async Task CleanBasket(ApplicationUser user)
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
var response = await _apiClient.DeleteAsync(basketUrl);
//CCE: response status code...
}
}
}