Skip to content

Commit

Permalink
Merge pull request #75 from NimblePros/ShadyNagy/35_add_aspire_to_sol…
Browse files Browse the repository at this point in the history
…ution

Add aspire to solution
  • Loading branch information
ardalis authored Oct 18, 2024
2 parents 91deda3 + 4bf9634 commit b17ed46
Show file tree
Hide file tree
Showing 30 changed files with 310 additions and 117 deletions.
10 changes: 10 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.7.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.7.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.0" />
<!-- Aspire -->
<PackageVersion Include="Aspire.Hosting.AppHost" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.3.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="8.0.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageVersion Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.9.0-beta.2" />
<!-- Test -->
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(AspNetVersion)" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
Expand Down
18 changes: 18 additions & 0 deletions Everything.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "tests\UnitTest
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7EFE7D65-5C2D-4D83-B034-D06B2D37564E}"
ProjectSection(SolutionItems) = preProject
Directory.Packages.props = Directory.Packages.props
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopWeb.AppHost", "src\eShopWeb.AppHost\eShopWeb.AppHost.csproj", "{E3079820-FF6C-4CC7-9CBB-8DF68237299F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopWeb.AspireServiceDefaults", "src\eShopWeb.AspireServiceDefaults\eShopWeb.AspireServiceDefaults.csproj", "{7DB219F4-4ABC-45D6-A5F7-B938769D5319}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -78,6 +83,14 @@ Global
{EAD6CF0B-2979-462C-BBB9-AF723B1EB570}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAD6CF0B-2979-462C-BBB9-AF723B1EB570}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAD6CF0B-2979-462C-BBB9-AF723B1EB570}.Release|Any CPU.Build.0 = Release|Any CPU
{E3079820-FF6C-4CC7-9CBB-8DF68237299F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3079820-FF6C-4CC7-9CBB-8DF68237299F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3079820-FF6C-4CC7-9CBB-8DF68237299F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3079820-FF6C-4CC7-9CBB-8DF68237299F}.Release|Any CPU.Build.0 = Release|Any CPU
{7DB219F4-4ABC-45D6-A5F7-B938769D5319}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DB219F4-4ABC-45D6-A5F7-B938769D5319}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DB219F4-4ABC-45D6-A5F7-B938769D5319}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DB219F4-4ABC-45D6-A5F7-B938769D5319}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -93,5 +106,10 @@ Global
{D6829485-DD9C-42CE-BEDE-4EB0E81021AC} = {BAA5312D-B54C-42D6-A3B9-504DD12F8250}
{698594AE-78D3-429F-B5CC-3A6F6BCE397A} = {BAA5312D-B54C-42D6-A3B9-504DD12F8250}
{EAD6CF0B-2979-462C-BBB9-AF723B1EB570} = {BAA5312D-B54C-42D6-A3B9-504DD12F8250}
{E3079820-FF6C-4CC7-9CBB-8DF68237299F} = {8FF16BDB-352E-42A2-A25F-0B5BC3A17FD7}
{7DB219F4-4ABC-45D6-A5F7-B938769D5319} = {8FF16BDB-352E-42A2-A25F-0B5BC3A17FD7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CC66E299-A176-4667-95E3-CCDA89AAC6D0}
EndGlobalSection
EndGlobal
3 changes: 2 additions & 1 deletion src/BlazorAdmin/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
using Microsoft.Extensions.Logging;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.RootComponents.Add<App>("#admin");
builder.RootComponents.Add<HeadOutlet>("head::after");

var configSection = builder.Configuration.GetRequiredSection(BaseUrlConfiguration.CONFIG_NAME);
builder.Services.Configure<BaseUrlConfiguration>(configSection);

builder.Services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddScoped<ToastService>();
builder.Services.AddScoped<HttpService>();
Expand Down
4 changes: 2 additions & 2 deletions src/BlazorAdmin/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"applicationUrl": "https://localhost:5011;http://localhost:5010",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand All @@ -21,7 +21,7 @@
"commandName": "Project",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"applicationUrl": "https://localhost:5011;http://localhost:5010",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
2 changes: 1 addition & 1 deletion src/BlazorAdmin/Services/CatalogLookupDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public CatalogLookupDataService(HttpClient httpClient,
public async Task<List<TLookupData>> List()
{
var endpointName = typeof(TLookupData).GetCustomAttribute<EndpointAttribute>().Name;
_logger.LogInformation($"Fetching {typeof(TLookupData).Name} from API. Enpoint : {endpointName}");
_logger.LogInformation($"Fetching {typeof(TLookupData).Name} from API Endpoint : {endpointName}");

var response = await _httpClient.GetFromJsonAsync<TReponse>($"{_apiUrl}{endpointName}");
return response.List;
Expand Down
18 changes: 5 additions & 13 deletions src/PublicApi/AuthEndpoints/AuthenticateEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,10 @@ namespace Microsoft.eShopWeb.PublicApi.AuthEndpoints;
/// <summary>
/// Authenticates a user
/// </summary>
public class AuthenticateEndpoint : Endpoint<AuthenticateRequest, AuthenticateResponse>
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ITokenClaimsService _tokenClaimsService;

public AuthenticateEndpoint(SignInManager<ApplicationUser> signInManager,
public class AuthenticateEndpoint(SignInManager<ApplicationUser> signInManager,
ITokenClaimsService tokenClaimsService)
{
_signInManager = signInManager;
_tokenClaimsService = tokenClaimsService;
}

: Endpoint<AuthenticateRequest, AuthenticateResponse>
{
public override void Configure()
{
Post("api/authenticate");
Expand All @@ -43,7 +35,7 @@ public override async Task<AuthenticateResponse> ExecuteAsync(AuthenticateReques
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
//var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
var result = await _signInManager.PasswordSignInAsync(request.Username, request.Password, false, true);
var result = await signInManager.PasswordSignInAsync(request.Username, request.Password, false, true);

response.Result = result.Succeeded;
response.IsLockedOut = result.IsLockedOut;
Expand All @@ -53,7 +45,7 @@ public override async Task<AuthenticateResponse> ExecuteAsync(AuthenticateReques

if (result.Succeeded)
{
response.Token = await _tokenClaimsService.GetTokenAsync(request.Username);
response.Token = await tokenClaimsService.GetTokenAsync(request.Username);
}

return response;
Expand Down
16 changes: 4 additions & 12 deletions src/PublicApi/CatalogBrandEndpoints/CatalogBrandListEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,9 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogBrandEndpoints;
/// <summary>
/// List Catalog Brands
/// </summary>
public class CatalogBrandListEndpoint : EndpointWithoutRequest<ListCatalogBrandsResponse>
public class CatalogBrandListEndpoint(IRepository<CatalogBrand> catalogBrandRepository, AutoMapper.IMapper mapper)
: EndpointWithoutRequest<ListCatalogBrandsResponse>
{
private readonly IRepository<CatalogBrand> _catalogBrandRepository;
private readonly AutoMapper.IMapper _mapper;

public CatalogBrandListEndpoint(IRepository<CatalogBrand> catalogBrandRepository, AutoMapper.IMapper mapper)
{
_catalogBrandRepository = catalogBrandRepository;
_mapper = mapper;
}

public override void Configure()
{
Get("api/catalog-brands");
Expand All @@ -35,9 +27,9 @@ public override async Task<ListCatalogBrandsResponse> ExecuteAsync(CancellationT
{
var response = new ListCatalogBrandsResponse();

var items = await _catalogBrandRepository.ListAsync(ct);
var items = await catalogBrandRepository.ListAsync(ct);

response.CatalogBrands.AddRange(items.Select(_mapper.Map<CatalogBrandDto>));
response.CatalogBrands.AddRange(items.Select(mapper.Map<CatalogBrandDto>));

return response;
}
Expand Down
15 changes: 3 additions & 12 deletions src/PublicApi/CatalogItemEndpoints/CatalogItemGetByIdEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,9 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
/// <summary>
/// Get a Catalog Item by Id
/// </summary>
public class CatalogItemGetByIdEndpoint
public class CatalogItemGetByIdEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
: Endpoint<GetByIdCatalogItemRequest, Results<Ok<GetByIdCatalogItemResponse>, NotFound>>
{
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IUriComposer _uriComposer;

public CatalogItemGetByIdEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
{
_itemRepository = itemRepository;
_uriComposer = uriComposer;
}

public override void Configure()
{
Get("api/catalog-items/{catalogItemId}");
Expand All @@ -36,7 +27,7 @@ public override async Task<Results<Ok<GetByIdCatalogItemResponse>, NotFound>> Ex
{
var response = new GetByIdCatalogItemResponse(request.CorrelationId());

var item = await _itemRepository.GetByIdAsync(request.CatalogItemId, ct);
var item = await itemRepository.GetByIdAsync(request.CatalogItemId, ct);
if (item is null)
return TypedResults.NotFound();

Expand All @@ -47,7 +38,7 @@ public override async Task<Results<Ok<GetByIdCatalogItemResponse>, NotFound>> Ex
CatalogTypeId = item.CatalogTypeId,
Description = item.Description,
Name = item.Name,
PictureUri = _uriComposer.ComposePicUri(item.PictureUri),
PictureUri = uriComposer.ComposePicUri(item.PictureUri),
Price = item.Price
};
return TypedResults.Ok(response);
Expand Down
23 changes: 7 additions & 16 deletions src/PublicApi/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,10 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
/// <summary>
/// List Catalog Items (paged)
/// </summary>
public class CatalogItemListPagedEndpoint : Endpoint<ListPagedCatalogItemRequest, ListPagedCatalogItemResponse>
public class CatalogItemListPagedEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer,
AutoMapper.IMapper mapper)
: Endpoint<ListPagedCatalogItemRequest, ListPagedCatalogItemResponse>
{
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IUriComposer _uriComposer;
private readonly AutoMapper.IMapper _mapper;

public CatalogItemListPagedEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer, AutoMapper.IMapper mapper)
{
_itemRepository = itemRepository;
_uriComposer = uriComposer;
_mapper = mapper;
}

public override void Configure()
{
Get("api/catalog-items");
Expand All @@ -42,20 +33,20 @@ public override async Task<ListPagedCatalogItemResponse> ExecuteAsync(ListPagedC
var response = new ListPagedCatalogItemResponse(request.CorrelationId());

var filterSpec = new CatalogFilterSpecification(request.CatalogBrandId, request.CatalogTypeId);
int totalItems = await _itemRepository.CountAsync(filterSpec, ct);
int totalItems = await itemRepository.CountAsync(filterSpec, ct);

var pagedSpec = new CatalogFilterPaginatedSpecification(
skip: request.PageIndex * request.PageSize,
take: request.PageSize,
brandId: request.CatalogBrandId,
typeId: request.CatalogTypeId);

var items = await _itemRepository.ListAsync(pagedSpec, ct);
var items = await itemRepository.ListAsync(pagedSpec, ct);

response.CatalogItems.AddRange(items.Select(_mapper.Map<CatalogItemDto>));
response.CatalogItems.AddRange(items.Select(mapper.Map<CatalogItemDto>));
foreach (CatalogItemDto item in response.CatalogItems)
{
item.PictureUri = _uriComposer.ComposePicUri(item.PictureUri);
item.PictureUri = uriComposer.ComposePicUri(item.PictureUri);
}

if (request.PageSize > 0)
Expand Down
20 changes: 6 additions & 14 deletions src/PublicApi/CatalogItemEndpoints/CreateCatalogItemEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,9 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
/// <summary>
/// Creates a new Catalog Item
/// </summary>
public class CreateCatalogItemEndpoint : Endpoint<CreateCatalogItemRequest, CreateCatalogItemResponse>
public class CreateCatalogItemEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
: Endpoint<CreateCatalogItemRequest, CreateCatalogItemResponse>
{
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IUriComposer _uriComposer;

public CreateCatalogItemEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
{
_itemRepository = itemRepository;
_uriComposer = uriComposer;
}

public override void Configure()
{
Post("api/catalog-items");
Expand All @@ -39,14 +31,14 @@ public override async Task HandleAsync(CreateCatalogItemRequest request, Cancell
var response = new CreateCatalogItemResponse(request.CorrelationId());

var catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name);
var existingCataloogItem = await _itemRepository.CountAsync(catalogItemNameSpecification, ct);
var existingCataloogItem = await itemRepository.CountAsync(catalogItemNameSpecification, ct);
if (existingCataloogItem > 0)
{
throw new DuplicateException($"A catalogItem with name {request.Name} already exists");
}

var newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri);
newItem = await _itemRepository.AddAsync(newItem, ct);
newItem = await itemRepository.AddAsync(newItem, ct);

if (newItem.Id != 0)
{
Expand All @@ -55,7 +47,7 @@ public override async Task HandleAsync(CreateCatalogItemRequest request, Cancell
// In production, we recommend uploading to a blob storage and deliver the image via CDN after a verification process.

newItem.UpdatePictureUri("eCatalog-item-default.png");
await _itemRepository.UpdateAsync(newItem, ct);
await itemRepository.UpdateAsync(newItem, ct);
}

var dto = new CatalogItemDto
Expand All @@ -65,7 +57,7 @@ public override async Task HandleAsync(CreateCatalogItemRequest request, Cancell
CatalogTypeId = newItem.CatalogTypeId,
Description = newItem.Description,
Name = newItem.Name,
PictureUri = _uriComposer.ComposePicUri(newItem.PictureUri),
PictureUri = uriComposer.ComposePicUri(newItem.PictureUri),
Price = newItem.Price
};
response.CatalogItem = dto;
Expand Down
13 changes: 3 additions & 10 deletions src/PublicApi/CatalogItemEndpoints/DeleteCatalogItemEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
/// <summary>
/// Deletes a Catalog Item
/// </summary>
public class DeleteCatalogItemEndpoint : Endpoint<DeleteCatalogItemRequest, Results<Ok<DeleteCatalogItemResponse>, NotFound>>
public class DeleteCatalogItemEndpoint(IRepository<CatalogItem> itemRepository) : Endpoint<DeleteCatalogItemRequest, Results<Ok<DeleteCatalogItemResponse>, NotFound>>
{
private readonly IRepository<CatalogItem> _itemRepository;

public DeleteCatalogItemEndpoint(IRepository<CatalogItem> itemRepository)
{
_itemRepository = itemRepository;
}

public override void Configure()
{
Delete("api/catalog-items/{catalogItemId}");
Expand All @@ -35,11 +28,11 @@ public override async Task<Results<Ok<DeleteCatalogItemResponse>, NotFound>> Exe
{
var response = new DeleteCatalogItemResponse(request.CorrelationId());

var itemToDelete = await _itemRepository.GetByIdAsync(request.CatalogItemId, ct);
var itemToDelete = await itemRepository.GetByIdAsync(request.CatalogItemId, ct);
if (itemToDelete is null)
return TypedResults.NotFound();

await _itemRepository.DeleteAsync(itemToDelete, ct);
await itemRepository.DeleteAsync(itemToDelete, ct);

return TypedResults.Ok(response);
}
Expand Down
18 changes: 5 additions & 13 deletions src/PublicApi/CatalogItemEndpoints/UpdateCatalogItemEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,9 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
/// <summary>
/// Updates a Catalog Item
/// </summary>
public class UpdateCatalogItemEndpoint : Endpoint<UpdateCatalogItemRequest, Results<Ok<UpdateCatalogItemResponse>, NotFound>>
public class UpdateCatalogItemEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
: Endpoint<UpdateCatalogItemRequest, Results<Ok<UpdateCatalogItemResponse>, NotFound>>
{
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IUriComposer _uriComposer;

public UpdateCatalogItemEndpoint(IRepository<CatalogItem> itemRepository, IUriComposer uriComposer)
{
_itemRepository = itemRepository;
_uriComposer = uriComposer;
}

public override void Configure()
{
Put("api/catalog-items");
Expand All @@ -37,7 +29,7 @@ public override async Task<Results<Ok<UpdateCatalogItemResponse>, NotFound>> Exe
{
var response = new UpdateCatalogItemResponse(request.CorrelationId());

var existingItem = await _itemRepository.GetByIdAsync(request.Id, ct);
var existingItem = await itemRepository.GetByIdAsync(request.Id, ct);
if (existingItem == null)
{
return TypedResults.NotFound();
Expand All @@ -48,7 +40,7 @@ public override async Task<Results<Ok<UpdateCatalogItemResponse>, NotFound>> Exe
existingItem.UpdateBrand(request.CatalogBrandId);
existingItem.UpdateType(request.CatalogTypeId);

await _itemRepository.UpdateAsync(existingItem, ct);
await itemRepository.UpdateAsync(existingItem, ct);

var dto = new CatalogItemDto
{
Expand All @@ -57,7 +49,7 @@ public override async Task<Results<Ok<UpdateCatalogItemResponse>, NotFound>> Exe
CatalogTypeId = existingItem.CatalogTypeId,
Description = existingItem.Description,
Name = existingItem.Name,
PictureUri = _uriComposer.ComposePicUri(existingItem.PictureUri),
PictureUri = uriComposer.ComposePicUri(existingItem.PictureUri),
Price = existingItem.Price
};
response.CatalogItem = dto;
Expand Down
Loading

0 comments on commit b17ed46

Please sign in to comment.