Merge branch 'master'
This commit is contained in:
commit
1eae6a9ea2
5
.gitignore
vendored
5
.gitignore
vendored
@ -25,7 +25,7 @@ bld/
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
**/wwwroot/lib/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
@ -256,4 +256,5 @@ pub/
|
||||
/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json
|
||||
|
||||
#Ignore marker-file used to know which docker files we have.
|
||||
.eshopdocker_*
|
||||
.eshopdocker_*
|
||||
/src/Web/WebMVC/wwwroot/lib
|
||||
|
21
README.md
21
README.md
@ -14,11 +14,15 @@ Sample .NET Core reference application, powered by Microsoft, based on a simplif
|
||||
**Architecture overview**: This reference application is cross-platform either at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps.
|
||||
The architecture proposes a simplified microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the current communication protocol.
|
||||
<p>
|
||||
The plan is to add asynchronous communication for data updates propagation across multiple services based on integration events and an event bus plus other features defined at the <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>roadmap</a>.
|
||||
It also supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus plus other features defined at the <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>roadmap</a>.
|
||||
<p>
|
||||
<img src="img/eshop_logo.png">
|
||||
<img src="img/eShopOnContainers_Architecture_Diagram.png">
|
||||
<p>
|
||||
The microservices are different in type, meaning different internal architecture patterns approaches depending on it purpose, as shown in the image below.
|
||||
<p>
|
||||
<img src="img/eShopOnContainers_Types_Of_Microservices.png">
|
||||
<p>
|
||||
<p>
|
||||
Additional miroservice styles with other frameworks and No-SQL databases will be added, eventually. This is a great opportunity for pull requests from the community, like a new microservice using Nancy, or even other languages like Node, Go, Python or data containers with MongoDB with Azure DocDB compatibility, PostgreSQL, RavenDB, Event Store, MySql, etc. You name it! :)
|
||||
|
||||
@ -30,15 +34,14 @@ Additional miroservice styles with other frameworks and No-SQL databases will be
|
||||
## Related documentation and guidance
|
||||
While developing this reference application, we are creating a reference Guide/eBook named <b>"Architecting and Developing Containerized and Microservice based .NET Applications"</b> which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers.
|
||||
<p>
|
||||
There's also an additional eBook focusing on Containers/Docker lifecycle (DevOps, CI/CD, etc.) with Microsoft Tools, already published.
|
||||
You can start reviewing these Guides/eBooks here:
|
||||
There are also additional eBooks focusing on Containers/Docker lifecycle (DevOps, CI/CD, etc.) with Microsoft Tools, already published plus an additional eBook focusing on Enterprise Apps Patterns with Xamarin.Forms.
|
||||
You can download them and start reviewing these Guides/eBooks here:
|
||||
<p>
|
||||
You can download both eBooks from here:
|
||||
|
||||
| Architecting & Developing | Containers Lifecycle & CI/CD |
|
||||
| ------------ | ------------|
|
||||
| <a href='docs/architecting-and-developing-containerized-and-microservice-based-net-applications-ebook-early-draft.pdf'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> |
|
||||
| <a href='docs/architecting-and-developing-containerized-and-microservice-based-net-applications-ebook-early-draft.pdf'>**Download** (Early DRAFT, still work in progress)</a> | <a href='https://aka.ms/dockerlifecycleebook'>**Download** - First Edition from late 2016</a> |
|
||||
| Architecting & Developing | Containers Lifecycle & CI/CD | App patterns with Xamarin.Forms |
|
||||
| ------------ | ------------| ------------|
|
||||
| <a href='https://aka.ms/microservicesebook'><img src="img/ebook_arch_dev_microservices_containers_cover.png"> </a> | <a href='https://aka.ms/dockerlifecycleebook'> <img src="img/ebook_containers_lifecycle.png"> </a> | <a href='https://aka.ms/xamarinpatternsebook'> <img src="img/xamarin-enterprise-patterns-ebook-cover-small.png"> </a> |
|
||||
| <sup> <a href='https://aka.ms/microservicesebook'>**Download** (Early DRAFT, still work in progress)</a> </sup> | <sup> <a href='https://aka.ms/dockerlifecycleebook'>**Download** (First Edition from late 2016) </a> </sup> | <sup> <a href='https://aka.ms/xamarinpatternsebook'>**Download** (Early DRAFT, still work in progress) </a> </sup> |
|
||||
|
||||
Send feedback to [cesardl@microsoft.com](cesardl@microsoft.com)
|
||||
<p>
|
||||
@ -109,7 +112,7 @@ The script will build the code and corresponding Docker images, push the latter
|
||||
|
||||
## Sending feedback and pull requests
|
||||
As mentioned, we'd appreciate to your feedback, improvements and ideas.
|
||||
You can create new issues at the issues section, do pull requests and/or send emails to eshop_feedback@service.microsoft.com
|
||||
You can create new issues at the issues section, do pull requests and/or send emails to **eshop_feedback@service.microsoft.com**
|
||||
|
||||
## Questions
|
||||
[QUESTION] Answer +1 if the solution is working for you (Through VS2017 or CLI environment):
|
||||
|
29
_docker/rabbitmq/Dockerfile.nanowin
Normal file
29
_docker/rabbitmq/Dockerfile.nanowin
Normal file
@ -0,0 +1,29 @@
|
||||
#https://github.com/spring2/dockerfiles/tree/master/rabbitmq
|
||||
|
||||
FROM microsoft/windowsservercore
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
ENV chocolateyUseWindowsCompression false
|
||||
|
||||
RUN iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); \
|
||||
choco install -y curl;
|
||||
|
||||
RUN choco install -y erlang
|
||||
ENV ERLANG_SERVICE_MANAGER_PATH="C:\Program Files\erl8.2\erts-8.2\bin"
|
||||
RUN choco install -y rabbitmq
|
||||
ENV RABBITMQ_SERVER="C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.5"
|
||||
|
||||
ENV RABBITMQ_CONFIG_FILE="c:\rabbitmq"
|
||||
COPY rabbitmq.config C:/
|
||||
COPY rabbitmq.config C:/Users/ContainerAdministrator/AppData/Roaming/RabbitMQ/
|
||||
COPY enabled_plugins C:/Users/ContainerAdministrator/AppData/Roaming/RabbitMQ/
|
||||
|
||||
|
||||
EXPOSE 4369
|
||||
EXPOSE 5672
|
||||
EXPOSE 5671
|
||||
EXPOSE 15672
|
||||
|
||||
WORKDIR C:/Program\ Files/RabbitMQ\ Server/rabbitmq_server-3.6.5/sbin
|
||||
CMD .\rabbitmq-server.bat
|
1
_docker/rabbitmq/enabled_plugins
Normal file
1
_docker/rabbitmq/enabled_plugins
Normal file
@ -0,0 +1 @@
|
||||
[rabbitmq_amqp1_0,rabbitmq_management].
|
1
_docker/rabbitmq/rabbitmq.config
Normal file
1
_docker/rabbitmq/rabbitmq.config
Normal file
@ -0,0 +1 @@
|
||||
[{rabbit, [{loopback_users, []}]}].
|
30
_docker/redis/Dockerfile.nanowin
Normal file
30
_docker/redis/Dockerfile.nanowin
Normal file
@ -0,0 +1,30 @@
|
||||
# The MSI installs a service which is hard to override, so let's use a zip file.
|
||||
|
||||
FROM microsoft/windowsservercore
|
||||
MAINTAINER alexellis2@gmail.com
|
||||
|
||||
SHELL ["powershell"]
|
||||
RUN $ErrorActionPreference = 'Stop'; \
|
||||
wget https://github.com/MSOpenTech/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.zip -OutFile Redis-x64-3.2.100.zip ; \
|
||||
Expand-Archive Redis-x64-3.2.100.zip -dest 'C:\\Program Files\\Redis\\' ; \
|
||||
Remove-Item Redis-x64-3.2.100.zip -Force
|
||||
|
||||
RUN setx PATH '%PATH%;C:\\Program Files\\Redis\\'
|
||||
WORKDIR 'C:\\Program Files\\Redis\\'
|
||||
|
||||
|
||||
|
||||
RUN Get-Content redis.windows.conf | Where { $_ -notmatch 'bind 127.0.0.1' } | Set-Content redis.openport.conf ; \
|
||||
Get-Content redis.openport.conf | Where { $_ -notmatch 'protected-mode yes' } | Set-Content redis.unprotected.conf ; \
|
||||
Add-Content redis.unprotected.conf 'protected-mode no' ; \
|
||||
Add-Content redis.unprotected.conf 'bind 0.0.0.0' ; \
|
||||
Get-Content redis.unprotected.conf
|
||||
|
||||
EXPOSE 6379
|
||||
|
||||
RUN set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord
|
||||
|
||||
# Define our command to be run when launching the container
|
||||
CMD .\\redis-server.exe .\\redis.unprotected.conf --port 6379 ; \
|
||||
Write-Host Redis Started... ; \
|
||||
while ($true) { Start-Sleep -Seconds 3600 }
|
@ -6,6 +6,7 @@ projectList=(
|
||||
"/src/Services/Identity/Identity.API"
|
||||
"/src/Web/WebMVC"
|
||||
"/src/Web/WebSPA"
|
||||
"/src/Web/WebStatus
|
||||
)
|
||||
|
||||
# Build SPA app
|
||||
@ -36,4 +37,4 @@ done
|
||||
#fi
|
||||
|
||||
# No need to build the images, docker build or docker compose will
|
||||
# do that using the images and containers defined in the docker-compose.yml file.
|
||||
# do that using the images and containers defined in the docker-compose.yml file.
|
||||
|
@ -7,6 +7,7 @@ projectList=(
|
||||
"../src/Services/Identity/Identity.API"
|
||||
"../src/Web/WebMVC"
|
||||
"../src/Web/WebSPA"
|
||||
"../src/Web/WebStatus"
|
||||
)
|
||||
|
||||
for project in "${projectList[@]}"
|
||||
|
@ -1,160 +0,0 @@
|
||||
|
||||
#########################################################################################################
|
||||
# This "expanded Script" can be used when debugging issues when building the .NET Core bits
|
||||
# as it is easier to follow and debug than when using a loop (like in the optimized build-bits.ps1)
|
||||
#########################################################################################################
|
||||
|
||||
Param([string] $rootPath)
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
if ([string]::IsNullOrEmpty($rootPath)) {
|
||||
$rootPath = "$scriptPath\.."
|
||||
}
|
||||
Write-Host "Root path used is $rootPath" -ForegroundColor Yellow
|
||||
|
||||
# *** WebMVC paths ***
|
||||
$webMVCPath = $rootPath + "\src\Web\WebMVC"
|
||||
$webMVCPathToProject = $webMVCPath + "\WebMVC.csproj"
|
||||
Write-Host "webMVCPathToProject is $webMVCPathToProject" -ForegroundColor Yellow
|
||||
$webMVCPathToPub = $webMVCPath + "\obj\Docker\publish"
|
||||
Write-Host "webMVCPathToPub is $webMVCPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** WebSPA paths ***
|
||||
$webSPAPath = $rootPath + "\src\Web\WebSPA"
|
||||
$webSPAPathToProject = $webSPAPath + "\WebSPA.csproj"
|
||||
Write-Host "webSPAPathToProject is $webSPAPathToProject" -ForegroundColor Yellow
|
||||
$webSPAPathToPub = $webSPAPath + "\obj\Docker\publish"
|
||||
Write-Host "webSPAPathToPub is $webSPAPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** IdentitySvc paths ***
|
||||
$identitySvcPath = $rootPath + "\src\Services\Identity\Identity.API"
|
||||
$identitySvcToProject = $identitySvcPath + "\Identity.API.csproj"
|
||||
Write-Host "identitySvcToProject is $identitySvcToProject" -ForegroundColor Yellow
|
||||
$identitySvcPathToPub = $identitySvcPath + "\obj\Docker\publish"
|
||||
Write-Host "identitySvcPathToPub is $identitySvcPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** Catalog paths ***
|
||||
$catalogPath = $rootPath + "\src\Services\Catalog\Catalog.API"
|
||||
$catalogPathToProject = $catalogPath + "\Catalog.API.csproj"
|
||||
Write-Host "catalogPathToProject is $catalogPathToProject" -ForegroundColor Yellow
|
||||
$catalogPathToPub = $catalogPath + "\obj\Docker\publish"
|
||||
Write-Host "catalogPathToPub is $catalogPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
# *** Ordering paths ***
|
||||
$orderingPath = $rootPath + "\src\Services\Ordering\Ordering.API"
|
||||
$orderingPathToProject = $orderingPath + "\Ordering.API.csproj"
|
||||
Write-Host "orderingPathToProject is $orderingPathToProject" -ForegroundColor Yellow
|
||||
$orderingPathToPub = $orderingPath + "\obj\Docker\publish"
|
||||
Write-Host "orderingPathToPub is $orderingPathToPub" -ForegroundColor Yellow
|
||||
|
||||
# *** Basket paths ***
|
||||
$basketPath = $rootPath + "\src\Services\Basket\Basket.API"
|
||||
$basketPathToProject = $basketPath + "\Basket.API.csproj"
|
||||
Write-Host "basketPathToProject is $basketPathToProject" -ForegroundColor Yellow
|
||||
$basketPathToPub = $basketPath + "\obj\Docker\publish"
|
||||
Write-Host "basketPathToPub is $basketPathToPub" -ForegroundColor Yellow
|
||||
|
||||
|
||||
########################################################################################
|
||||
# Delete old eShop dotnet publish bits
|
||||
########################################################################################
|
||||
# Write-Host "Deleting previous dotnet publish bits from all projects" -ForegroundColor Blue
|
||||
|
||||
remove-item -path $WebMVCPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
remove-item -path $webSPAPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
remove-item -path $identitySvcPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
remove-item -path $catalogPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
remove-item -path $orderingPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
remove-item -path $basketPathToPub -Force -Recurse -ErrorAction SilentlyContinue
|
||||
|
||||
|
||||
|
||||
########################################################################################
|
||||
# Building DotNet bits
|
||||
########################################################################################
|
||||
|
||||
# WebMVC: Build dotnet bits
|
||||
Write-Host "WebMVC: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $WebMVCPathToProject
|
||||
dotnet build $WebMVCPathToProject
|
||||
dotnet publish $WebMVCPathToProject -o $WebMVCPathToPub
|
||||
|
||||
|
||||
# WebSPA: Build dotnet bits
|
||||
Write-Host "WebSPA: Installing npm dependencies"
|
||||
#TEMP COMMENT--- Start-Process -WorkingDirectory $webSPAPath -NoNewWindow -Wait npm i
|
||||
|
||||
Write-Host "WebSPA: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $webSPAPathToProject
|
||||
dotnet build $webSPAPathToProject
|
||||
dotnet publish $webSPAPathToProject -o $webSPAPathToPub
|
||||
|
||||
|
||||
# Identity Service: Build dotnet bits
|
||||
Write-Host "Identity Service: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $identitySvcToProject
|
||||
dotnet build $identitySvcToProject
|
||||
dotnet publish $identitySvcToProject -o $identitySvcPathToPub
|
||||
|
||||
|
||||
# Catalog Service: Build dotnet bits
|
||||
Write-Host "Catalog Service: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $catalogPathToProject
|
||||
dotnet build $catalogPathToProject
|
||||
dotnet publish $catalogPathToProject -o $catalogPathToPub
|
||||
|
||||
|
||||
# Ordering Service: Build dotnet bits
|
||||
Write-Host "Ordering Service: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $orderingPathToProject
|
||||
dotnet build $orderingPathToProject
|
||||
dotnet publish $orderingPathToProject -o $orderingPathToPub
|
||||
|
||||
|
||||
# Basket Service: Build dotnet bits
|
||||
Write-Host "Basket Service: Restore Dependencies, dotnet build and dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $basketPathToProject
|
||||
dotnet build $basketPathToProject
|
||||
dotnet publish $basketPathToProject -o $basketPathToPub
|
||||
|
||||
|
||||
|
||||
########################################################################################
|
||||
# Delete old eShop Docker images
|
||||
########################################################################################
|
||||
|
||||
$imagesToDelete = docker images --filter=reference="eshop/*" -q
|
||||
|
||||
If (-Not $imagesToDelete) {Write-Host "Not deleting eShop images as there are no eShop images in the current local Docker repo."}
|
||||
Else
|
||||
{
|
||||
# Delete all containers
|
||||
Write-Host "Deleting all containers in local Docker Host"
|
||||
docker rm $(docker ps -a -q) -f
|
||||
|
||||
# Delete all eshop images
|
||||
Write-Host "Deleting eShop images in local Docker repo"
|
||||
Write-Host $imagesToDelete
|
||||
docker rmi $(docker images --filter=reference="eshop/*" -q) -f
|
||||
}
|
||||
|
||||
|
||||
########################################################################################
|
||||
# Build new eShop images
|
||||
########################################################################################
|
||||
|
||||
# WE DON'T NEED DOCKER BUILD AS WE CAN RUN "DOCKER-COMPOSE BUILD" OR "DOCKER-COMPOSE UP" AND IT WILL BUILD ALL THE IMAGES IN THE .YML FOR US
|
||||
|
||||
#*** build docker images ***
|
||||
# docker build -t eshop/web $webPathToPub
|
||||
# docker build -t eshop/catalog.api $catalogPathToPub
|
||||
# docker build -t eshop/ordering.api $orderingApiPathToPub
|
||||
# docker build -t eshop/basket.api $basketPathToPub
|
||||
# docker build -t eshop/webspa $webSPAPathToPub
|
||||
# docker build -t eshop/identity $identitySvcPathToPub
|
@ -15,13 +15,14 @@ $projectPaths =
|
||||
@{Path="$rootPath\src\Services\Catalog\Catalog.API";Prj="Catalog.API.csproj"},
|
||||
@{Path="$rootPath\src\Services\Ordering\Ordering.API";Prj="Ordering.API.csproj"},
|
||||
@{Path="$rootPath\src\Services\Basket\Basket.API";Prj="Basket.API.csproj"}
|
||||
@{Path="$rootPath\src\Web\WebStatus";Prj="WebStatus.csproj"}
|
||||
|
||||
$projectPaths | foreach {
|
||||
$projectPath = $_.Path
|
||||
$projectFile = $_.Prj
|
||||
$outPath = $_.Path + "\obj\Docker\publish"
|
||||
$projectPathAndFile = "$projectPath\$projectFile"
|
||||
Write-Host "Deleting $outPath" -ForegroundColor Yellow
|
||||
Write-Host "Deleting old publish files in $outPath" -ForegroundColor Yellow
|
||||
remove-item -path $outPath -Force -Recurse -ErrorAction SilentlyContinue
|
||||
Write-Host "Publishing $projectPathAndFile to $outPath" -ForegroundColor Yellow
|
||||
dotnet restore $projectPathAndFile
|
||||
|
@ -8,3 +8,8 @@ services:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq
|
||||
ports:
|
||||
- "5672:5672"
|
||||
|
79
docker-compose-windows.override.yml
Normal file
79
docker-compose-windows.override.yml
Normal file
@ -0,0 +1,79 @@
|
||||
version: '2.1'
|
||||
|
||||
# The default docker-compose.override file can use the "localhost" as the external name for testing web apps within the same dev machine.
|
||||
# The ESHOP_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like:
|
||||
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost
|
||||
# but values present in the environment vars at runtime will always override those defined inside the .env file
|
||||
# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
|
||||
|
||||
services:
|
||||
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- CatalogUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
ports:
|
||||
- "5104:5104"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- IdentityUrl=http://10.0.75.1:5105 #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
|
||||
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
||||
ports:
|
||||
- "5100:5100"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
80
docker-compose-windows.prod.yml
Normal file
80
docker-compose-windows.prod.yml
Normal file
@ -0,0 +1,80 @@
|
||||
version: '2.1'
|
||||
|
||||
# The Production docker-compose file has to have the external/real IPs or DNS names for the services
|
||||
# The ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like:
|
||||
# ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=192.168.88.248
|
||||
# but values present in the environment vars at runtime will always override those defined inside the .env file
|
||||
# An external IP or DNS name has to be used when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
|
||||
#
|
||||
# Set ASPNETCORE_ENVIRONMENT=Development to get errors while testing.
|
||||
#
|
||||
# You need to start it with the following CLI command:
|
||||
# docker-compose -f docker-compose-windows.yml -f docker-compose-windows.prod.yml up -d
|
||||
|
||||
services:
|
||||
|
||||
basket.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
catalog.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5101:5101"
|
||||
|
||||
identity.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
|
||||
ordering.api:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
ports:
|
||||
- "5102:5102"
|
||||
|
||||
webspa:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5104
|
||||
- CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||
- OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||
ports:
|
||||
- "5104:5104"
|
||||
|
||||
webmvc:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5100
|
||||
- CatalogUrl=http://catalog.api:5101
|
||||
- OrderingUrl=http://ordering.api:5102
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
ports:
|
||||
- "5100:5100"
|
||||
|
||||
sql.data:
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
80
docker-compose-windows.yml
Normal file
80
docker-compose-windows.yml
Normal file
@ -0,0 +1,80 @@
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
build:
|
||||
context: ./src/Services/Basket/Basket.API
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.api
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
build:
|
||||
context: ./src/Services/Catalog/Catalog.API
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
identity.api:
|
||||
image: eshop/identity.api
|
||||
build:
|
||||
context: ./src/Services/Identity/Identity.API
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
ordering.api:
|
||||
image: eshop/ordering.api
|
||||
build:
|
||||
context: ./src/Services/Ordering/Ordering.API
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
webspa:
|
||||
image: eshop/webspa
|
||||
build:
|
||||
context: ./src/Web/WebSPA
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- identity.api
|
||||
- basket.api
|
||||
|
||||
webmvc:
|
||||
image: eshop/webmvc
|
||||
build:
|
||||
context: ./src/Web/WebMVC
|
||||
dockerfile: Dockerfile.nanowin
|
||||
depends_on:
|
||||
- catalog.api
|
||||
- ordering.api
|
||||
- identity.api
|
||||
- basket.api
|
||||
|
||||
sql.data:
|
||||
image: microsoft/mssql-server-windows
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
build:
|
||||
context: ./_docker/redis
|
||||
dockerfile: Dockerfile.nanowin
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq
|
||||
build:
|
||||
context: ./_docker/rabbitmq
|
||||
dockerfile: Dockerfile.nanowin
|
||||
ports:
|
||||
- "5672:5672"
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: nat
|
||||
|
@ -14,6 +14,7 @@ services:
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
@ -22,7 +23,8 @@ services:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
|
||||
@ -31,6 +33,7 @@ services:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5105
|
||||
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
||||
ports:
|
||||
@ -42,6 +45,8 @@ services:
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
|
||||
@ -73,4 +78,17 @@ services:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
- "5433:1433"
|
||||
|
||||
webstatus:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5107
|
||||
- CatalogUrl=http://catalog.api:5101/hc
|
||||
- OrderingUrl=http://ordering.api:5102/hc
|
||||
- BasketUrl=http://basket.api:5103/hc
|
||||
- IdentityUrl=http://identity.api:5105/hc
|
||||
- mvc=http://webmvc:5100/hc
|
||||
- spa=http://webspa:5104/hc
|
||||
ports:
|
||||
- "5107:5107"
|
||||
|
@ -8,7 +8,7 @@ version: '2'
|
||||
#
|
||||
# Set ASPNETCORE_ENVIRONMENT=Development to get errors while testing.
|
||||
#
|
||||
# You need to start it with the following CLI command:
|
||||
# You need to start it with the following CLI command:
|
||||
# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
|
||||
services:
|
||||
@ -19,6 +19,7 @@ services:
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5103
|
||||
- ConnectionString=basket.data
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
@ -28,6 +29,7 @@ services:
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5101
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
||||
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5101:5101"
|
||||
|
||||
@ -38,6 +40,7 @@ services:
|
||||
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105.
|
||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback
|
||||
ports:
|
||||
- "5105:5105"
|
||||
|
||||
@ -47,6 +50,8 @@ services:
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5102
|
||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
- EventBusConnection=rabbitmq
|
||||
ports:
|
||||
- "5102:5102"
|
||||
|
||||
@ -77,4 +82,17 @@ services:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
- "5433:1433"
|
||||
|
||||
webstatus:
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5107
|
||||
- CatalogUrl=http://catalog.api:5101/hc
|
||||
- OrderingUrl=http://ordering.api:5102/hc
|
||||
- BasketUrl=http://basket.api:5103/hc
|
||||
- mvc=http://webmvc:5100/hc
|
||||
- spa=http://webspa:5104/hc
|
||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||
ports:
|
||||
- "5107:5107"
|
@ -90,3 +90,18 @@ services:
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webstatus:
|
||||
image: eshop/webstatus:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
environment:
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- ./src/Web/WebStatus:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
@ -60,3 +60,13 @@ services:
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
webstatus:
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
@ -9,6 +9,7 @@ services:
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.api
|
||||
- rabbitmq
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
@ -17,6 +18,7 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- sql.data
|
||||
- rabbitmq
|
||||
|
||||
identity.api:
|
||||
image: eshop/identity.api
|
||||
@ -61,3 +63,14 @@ services:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq
|
||||
ports:
|
||||
- "5672:5672"
|
||||
|
||||
webstatus:
|
||||
image: eshop/webstatus
|
||||
build:
|
||||
context: ./src/Web/WebStatus
|
||||
dockerfile: Dockerfile
|
||||
|
BIN
docs/Enterprise-Application-Patterns-using-XamarinForms.pdf
Normal file
BIN
docs/Enterprise-Application-Patterns-using-XamarinForms.pdf
Normal file
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.0
|
||||
VisualStudioVersion = 15.0.26228.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||
EndProject
|
||||
@ -39,10 +39,24 @@ EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ordering.Infrastructure", "src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj", "{95F1F07C-4D92-4742-BD07-E5B805AAB651}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\UnitTest\UnitTest.csproj", "{7796F5D8-31FC-45A4-B673-19DE5BA194CF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B}
|
||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68} = {F16E3C6A-1C94-4EAB-BE91-099618060B68}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
||||
EndProject
|
||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B}
|
||||
{5B810E3D-112E-4857-B197-F09D2FD41E27} = {5B810E3D-112E-4857-B197-F09D2FD41E27}
|
||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68} = {F16E3C6A-1C94-4EAB-BE91-099618060B68}
|
||||
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {F0333D8E-0B27-42B7-B2C6-78F3657624E2}
|
||||
{42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {42681D9D-750A-4DF7-BD9F-9292CFD5C253}
|
||||
{2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {2110CBB0-3B38-4EE4-A743-DF6968D80D90}
|
||||
{CFE2FACB-4538-4B99-8A10-306F3882952D} = {CFE2FACB-4538-4B99-8A10-306F3882952D}
|
||||
{231226CE-690B-4979-8870-9A79D80928E2} = {231226CE-690B-4979-8870-9A79D80928E2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{F16E3C6A-1C94-4EAB-BE91-099618060B68}"
|
||||
EndProject
|
||||
@ -50,6 +64,30 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "test\Se
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.csproj", "{CFE2FACB-4538-4B99-8A10-306F3882952D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{DB0EFB20-B024-4E5E-A75C-52143C131D25}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus", "src\BuildingBlocks\EventBus\EventBus\EventBus.csproj", "{0044B293-1DCC-4224-B948-00CF6DC7F510}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{8088F3FC-6787-45FA-A924-816EC81CBFAC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{A81ECBC2-6B00-4DCD-8388-469174033379}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{942ED6E8-0050-495F-A0EA-01E97F63760C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.Data", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.Data\Microsoft.Extensions.HealthChecks.Data.csproj", "{7804FC60-23E6-490C-8E08-F9FEF829F184}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resilience", "Resilience", "{FBF43D93-F2E7-4FF8-B4AB-186895949B88}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Resilience.Http", "src\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj", "{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
@ -544,6 +582,390 @@ Global
|
||||
{CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CFE2FACB-4538-4B99-8A10-306F3882952D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -567,5 +989,17 @@ Global
|
||||
{F16E3C6A-1C94-4EAB-BE91-099618060B68} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
|
||||
{5B810E3D-112E-4857-B197-F09D2FD41E27} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||
{CFE2FACB-4538-4B99-8A10-306F3882952D} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||
{DB0EFB20-B024-4E5E-A75C-52143C131D25} = {932D8224-11F6-4D07-B109-DA28AD288A63}
|
||||
{807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
|
||||
{0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
|
||||
{8088F3FC-6787-45FA-A924-816EC81CBFAC} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
|
||||
{9EE28E45-1533-472B-8267-56C48855BA0E} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}
|
||||
{A81ECBC2-6B00-4DCD-8388-469174033379} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
|
||||
{DF8367F8-E6BD-4D07-99D2-E416BF8AB01E} = {A81ECBC2-6B00-4DCD-8388-469174033379}
|
||||
{942ED6E8-0050-495F-A0EA-01E97F63760C} = {A81ECBC2-6B00-4DCD-8388-469174033379}
|
||||
{7804FC60-23E6-490C-8E08-F9FEF829F184} = {A81ECBC2-6B00-4DCD-8388-469174033379}
|
||||
{C0A7918D-B4F2-4E7F-8DE2-1E5279EF079F} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
|
||||
{FBF43D93-F2E7-4FF8-B4AB-186895949B88} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
|
||||
{D1C47FF1-91F1-4CAF-9ABB-AD642B821502} = {FBF43D93-F2E7-4FF8-B4AB-186895949B88}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -1,18 +1,10 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26213.1
|
||||
VisualStudioVersion = 15.0.26228.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docker-compose.override.yml = docker-compose.override.yml
|
||||
docker-compose.yml = docker-compose.yml
|
||||
global.json = global.json
|
||||
NuGet.config = NuGet.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{91CF7717-08AB-4E65-B10E-0B426F01E2E8}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web Apps", "Web Apps", "{E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}"
|
||||
@ -49,7 +41,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Code", "Shared Code"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7814B-72A6-465B-A61C-57B512DEE303}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj"", "{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "src\Web\WebSPA\WebSPA.csproj", "{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Apps", "Mobile Apps", "{B7B1D395-4E06-4036-BE86-C216756B9367}"
|
||||
EndProject
|
||||
@ -75,6 +67,44 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\Services\U
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.API", "src\Services\Identity\Identity.API\Identity.API.csproj", "{A579E108-5445-403D-A407-339AC4D1611B}"
|
||||
EndProject
|
||||
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A579E108-5445-403D-A407-339AC4D1611B} = {A579E108-5445-403D-A407-339AC4D1611B}
|
||||
{9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41} = {23FB706A-2701-41E9-8BF9-28936001CA41}
|
||||
{F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {F0333D8E-0B27-42B7-B2C6-78F3657624E2}
|
||||
{42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {42681D9D-750A-4DF7-BD9F-9292CFD5C253}
|
||||
{2110CBB0-3B38-4EE4-A743-DF6968D80D90} = {2110CBB0-3B38-4EE4-A743-DF6968D80D90}
|
||||
{231226CE-690B-4979-8870-9A79D80928E2} = {231226CE-690B-4979-8870-9A79D80928E2}
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{B473B70F-0796-4862-B1AD-BB742D93B868}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus", "src\BuildingBlocks\EventBus\EventBus\EventBus.csproj", "{3D6B7A87-162E-4479-B256-1291BEB503B6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBusRabbitMQ", "src\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{52AF222A-258C-4032-ACDD-857D7251BC1E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{438B774F-5569-4DE2-AA62-3F8BAEB31C55}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\Services\FunctionalTests\FunctionalTests.csproj", "{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HealthChecks", "HealthChecks", "{96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj", "{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj", "{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.HealthChecks.Data", "src\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.Data\Microsoft.Extensions.HealthChecks.Data.csproj", "{0E7AEB45-80F2-42B9-96BB-3414669E58AA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resilience", "Resilience", "{D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Resilience.Http", "src\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj", "{D92EB452-7A72-4B26-A8ED-0204CD376BC4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStatus", "src\Web\WebStatus\WebStatus.csproj", "{23FB706A-2701-41E9-8BF9-28936001CA41}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
@ -1004,6 +1034,438 @@ Global
|
||||
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x64.Build.0 = Release|Any CPU
|
||||
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FEA0C318-FFED-4D39-8781-265718CA43DD}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6}.Release|x86.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x64.Build.0 = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x64.Build.0 = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -1039,5 +1501,18 @@ Global
|
||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7}
|
||||
{7796F5D8-31FC-45A4-B673-19DE5BA194CF} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||
{A579E108-5445-403D-A407-339AC4D1611B} = {02DF7FEE-C302-433D-A6CD-237A2569F236}
|
||||
{1EF3AC0F-F27C-46DD-AC53-D762D2C11C45} = {932D8224-11F6-4D07-B109-DA28AD288A63}
|
||||
{B473B70F-0796-4862-B1AD-BB742D93B868} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}
|
||||
{3D6B7A87-162E-4479-B256-1291BEB503B6} = {B473B70F-0796-4862-B1AD-BB742D93B868}
|
||||
{52AF222A-258C-4032-ACDD-857D7251BC1E} = {B473B70F-0796-4862-B1AD-BB742D93B868}
|
||||
{438B774F-5569-4DE2-AA62-3F8BAEB31C55} = {B473B70F-0796-4862-B1AD-BB742D93B868}
|
||||
{2DA840CE-FCEA-4CF7-B1A1-ADD7775E7357} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||
{96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}
|
||||
{FFFD3E09-A803-4F99-BAC5-C93ABA3E02D3} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B}
|
||||
{EE65FA8B-1D87-4050-BC21-F305F2F8AE45} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B}
|
||||
{0E7AEB45-80F2-42B9-96BB-3414669E58AA} = {96CE8CE7-BC97-4A53-899F-5EB63D7BBF7B}
|
||||
{D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06} = {1EF3AC0F-F27C-46DD-AC53-D762D2C11C45}
|
||||
{D92EB452-7A72-4B26-A8ED-0204CD376BC4} = {D13768ED-5AF1-4E09-96DD-FF6E7A2E5E06}
|
||||
{23FB706A-2701-41E9-8BF9-28936001CA41} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 427 KiB After Width: | Height: | Size: 405 KiB |
BIN
img/eShopOnContainers_Architecture_Diagram_old.png
Normal file
BIN
img/eShopOnContainers_Architecture_Diagram_old.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 427 KiB |
BIN
img/eShopOnContainers_Types_Of_Microservices.png
Normal file
BIN
img/eShopOnContainers_Types_Of_Microservices.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
BIN
img/xamarin-enterprise-patterns-ebook-cover-small.png
Normal file
BIN
img/xamarin-enterprise-patterns-ebook-cover-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,14 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
|
||||
{
|
||||
public interface IEventBus
|
||||
{
|
||||
void Subscribe<T>(IIntegrationEventHandler<T> handler) where T: IntegrationEvent;
|
||||
void Unsubscribe<T>(IIntegrationEventHandler<T> handler) where T : IntegrationEvent;
|
||||
void Publish(IntegrationEvent @event);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
|
||||
{
|
||||
public interface IIntegrationEventHandler<in TIntegrationEvent> : IIntegrationEventHandler
|
||||
where TIntegrationEvent: IntegrationEvent
|
||||
{
|
||||
Task Handle(TIntegrationEvent @event);
|
||||
}
|
||||
|
||||
public interface IIntegrationEventHandler
|
||||
{
|
||||
}
|
||||
}
|
17
src/BuildingBlocks/EventBus/EventBus/EventBus.csproj
Normal file
17
src/BuildingBlocks/EventBus/EventBus/EventBus.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
<RuntimeFrameworkVersion>1.1.0</RuntimeFrameworkVersion>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.EventBus</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Abstractions\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events
|
||||
{
|
||||
public class IntegrationEvent
|
||||
{
|
||||
public IntegrationEvent()
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
CreationDate = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public Guid Id { get; }
|
||||
public DateTime CreationDate { get; }
|
||||
}
|
||||
}
|
171
src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs
Normal file
171
src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using Newtonsoft.Json;
|
||||
using RabbitMQ.Client;
|
||||
using RabbitMQ.Client.Events;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
||||
{
|
||||
public class EventBusRabbitMQ : IEventBus, IDisposable
|
||||
{
|
||||
private readonly string _brokerName = "eshop_event_bus";
|
||||
private readonly string _connectionString;
|
||||
private readonly Dictionary<string, List<IIntegrationEventHandler>> _handlers;
|
||||
private readonly List<Type> _eventTypes;
|
||||
|
||||
private IModel _model;
|
||||
private IConnection _connection;
|
||||
private string _queueName;
|
||||
|
||||
|
||||
public EventBusRabbitMQ(string connectionString)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
_handlers = new Dictionary<string, List<IIntegrationEventHandler>>();
|
||||
_eventTypes = new List<Type>();
|
||||
}
|
||||
|
||||
public void Publish(IntegrationEvent @event)
|
||||
{
|
||||
var eventName = @event.GetType().Name;
|
||||
var factory = new ConnectionFactory() { HostName = _connectionString };
|
||||
using (var connection = factory.CreateConnection())
|
||||
using (var channel = connection.CreateModel())
|
||||
{
|
||||
channel.ExchangeDeclare(exchange: _brokerName,
|
||||
type: "direct");
|
||||
|
||||
string message = JsonConvert.SerializeObject(@event);
|
||||
var body = Encoding.UTF8.GetBytes(message);
|
||||
|
||||
channel.BasicPublish(exchange: _brokerName,
|
||||
routingKey: eventName,
|
||||
basicProperties: null,
|
||||
body: body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Subscribe<T>(IIntegrationEventHandler<T> handler) where T : IntegrationEvent
|
||||
{
|
||||
var eventName = typeof(T).Name;
|
||||
if (_handlers.ContainsKey(eventName))
|
||||
{
|
||||
_handlers[eventName].Add(handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = GetChannel();
|
||||
channel.QueueBind(queue: _queueName,
|
||||
exchange: _brokerName,
|
||||
routingKey: eventName);
|
||||
|
||||
_handlers.Add(eventName, new List<IIntegrationEventHandler>());
|
||||
_handlers[eventName].Add(handler);
|
||||
_eventTypes.Add(typeof(T));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Unsubscribe<T>(IIntegrationEventHandler<T> handler) where T : IntegrationEvent
|
||||
{
|
||||
var eventName = typeof(T).Name;
|
||||
if (_handlers.ContainsKey(eventName) && _handlers[eventName].Contains(handler))
|
||||
{
|
||||
_handlers[eventName].Remove(handler);
|
||||
|
||||
if (_handlers[eventName].Count == 0)
|
||||
{
|
||||
_handlers.Remove(eventName);
|
||||
var eventType = _eventTypes.Single(e => e.Name == eventName);
|
||||
_eventTypes.Remove(eventType);
|
||||
_model.QueueUnbind(queue: _queueName,
|
||||
exchange: _brokerName,
|
||||
routingKey: eventName);
|
||||
|
||||
if (_handlers.Keys.Count == 0)
|
||||
{
|
||||
_queueName = string.Empty;
|
||||
_model.Dispose();
|
||||
_connection.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_handlers.Clear();
|
||||
_model?.Dispose();
|
||||
_connection?.Dispose();
|
||||
}
|
||||
|
||||
private IModel GetChannel()
|
||||
{
|
||||
if (_model != null)
|
||||
{
|
||||
return _model;
|
||||
}
|
||||
else
|
||||
{
|
||||
(_model, _connection) = CreateConnection();
|
||||
return _model;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private (IModel model, IConnection connection) CreateConnection()
|
||||
{
|
||||
var factory = new ConnectionFactory() { HostName = _connectionString };
|
||||
var con = factory.CreateConnection();
|
||||
var channel = con.CreateModel();
|
||||
|
||||
channel.ExchangeDeclare(exchange: _brokerName,
|
||||
type: "direct");
|
||||
if (string.IsNullOrEmpty(_queueName))
|
||||
{
|
||||
_queueName = channel.QueueDeclare().QueueName;
|
||||
}
|
||||
|
||||
var consumer = new EventingBasicConsumer(channel);
|
||||
consumer.Received += async (model, ea) =>
|
||||
{
|
||||
var eventName = ea.RoutingKey;
|
||||
var message = Encoding.UTF8.GetString(ea.Body);
|
||||
|
||||
await ProcessEvent(eventName, message);
|
||||
};
|
||||
channel.BasicConsume(queue: _queueName,
|
||||
noAck: true,
|
||||
consumer: consumer);
|
||||
|
||||
return (channel, con);
|
||||
}
|
||||
|
||||
private async Task ProcessEvent(string eventName, string message)
|
||||
{
|
||||
if (_handlers.ContainsKey(eventName))
|
||||
{
|
||||
Type eventType = _eventTypes.Single(t => t.Name == eventName);
|
||||
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
|
||||
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
|
||||
var handlers = _handlers[eventName];
|
||||
|
||||
foreach (var handler in handlers)
|
||||
{
|
||||
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
<RuntimeFrameworkVersion>1.1.0</RuntimeFrameworkVersion>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="4.1.1" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EventBus\EventBus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public enum EventStateEnum
|
||||
{
|
||||
NotPublished = 0,
|
||||
Published = 1,
|
||||
PublishedFailed = 2
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public class IntegrationEventLogContext : DbContext
|
||||
{
|
||||
public IntegrationEventLogContext(DbContextOptions<IntegrationEventLogContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<IntegrationEventLogEntry> IntegrationEventLogs { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<IntegrationEventLogEntry>(ConfigureIntegrationEventLogEntry);
|
||||
}
|
||||
|
||||
void ConfigureIntegrationEventLogEntry(EntityTypeBuilder<IntegrationEventLogEntry> builder)
|
||||
{
|
||||
builder.ToTable("IntegrationEventLog");
|
||||
|
||||
builder.HasKey(e => e.EventId);
|
||||
|
||||
builder.Property(e => e.EventId)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.Content)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.CreationTime)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.State)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.TimesSent)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.EventTypeName)
|
||||
.IsRequired();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
<RuntimeFrameworkVersion>1.1.0</RuntimeFrameworkVersion>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EventBus\EventBus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public class IntegrationEventLogEntry
|
||||
{
|
||||
private IntegrationEventLogEntry() { }
|
||||
public IntegrationEventLogEntry(IntegrationEvent @event)
|
||||
{
|
||||
EventId = @event.Id;
|
||||
CreationTime = @event.CreationDate;
|
||||
EventTypeName = @event.GetType().FullName;
|
||||
Content = JsonConvert.SerializeObject(@event);
|
||||
State = EventStateEnum.NotPublished;
|
||||
TimesSent = 0;
|
||||
}
|
||||
public Guid EventId { get; private set; }
|
||||
public string EventTypeName { get; private set; }
|
||||
public EventStateEnum State { get; set; }
|
||||
public int TimesSent { get; set; }
|
||||
public DateTime CreationTime { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
|
||||
{
|
||||
public interface IIntegrationEventLogService
|
||||
{
|
||||
Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction);
|
||||
Task MarkEventAsPublishedAsync(IntegrationEvent @event);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
|
||||
{
|
||||
public class IntegrationEventLogService : IIntegrationEventLogService
|
||||
{
|
||||
private readonly IntegrationEventLogContext _integrationEventLogContext;
|
||||
private readonly DbConnection _dbConnection;
|
||||
|
||||
public IntegrationEventLogService(DbConnection dbConnection)
|
||||
{
|
||||
_dbConnection = dbConnection?? throw new ArgumentNullException("dbConnection");
|
||||
_integrationEventLogContext = new IntegrationEventLogContext(
|
||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||
.UseSqlServer(_dbConnection)
|
||||
.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning))
|
||||
.Options);
|
||||
}
|
||||
|
||||
public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction)
|
||||
{
|
||||
if(transaction == null)
|
||||
{
|
||||
throw new ArgumentNullException("transaction", $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event.");
|
||||
}
|
||||
|
||||
var eventLogEntry = new IntegrationEventLogEntry(@event);
|
||||
|
||||
_integrationEventLogContext.Database.UseTransaction(transaction);
|
||||
_integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry);
|
||||
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public Task MarkEventAsPublishedAsync(IntegrationEvent @event)
|
||||
{
|
||||
var eventLogEntry = _integrationEventLogContext.IntegrationEventLogs.Single(ie => ie.EventId == @event.Id);
|
||||
eventLogEntry.TimesSent++;
|
||||
eventLogEntry.State = EventStateEnum.Published;
|
||||
|
||||
_integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry);
|
||||
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities
|
||||
{
|
||||
public class ResilientTransaction
|
||||
{
|
||||
private DbContext _context;
|
||||
private ResilientTransaction(DbContext context) =>
|
||||
_context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
|
||||
public static ResilientTransaction New (DbContext context) =>
|
||||
new ResilientTransaction(context);
|
||||
|
||||
public async Task ExecuteAsync(Func<Task> action)
|
||||
{
|
||||
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
|
||||
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
|
||||
var strategy = _context.Database.CreateExecutionStrategy();
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
using (var transaction = _context.Database.BeginTransaction())
|
||||
{
|
||||
await action();
|
||||
transaction.Commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.HealthChecks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNetCore.HealthChecks
|
||||
{
|
||||
public class HealthCheckMiddleware
|
||||
{
|
||||
private RequestDelegate _next;
|
||||
private string _path;
|
||||
private int? _port;
|
||||
private IHealthCheckService _service;
|
||||
|
||||
public HealthCheckMiddleware(RequestDelegate next, IHealthCheckService service, int port)
|
||||
{
|
||||
_port = port;
|
||||
_service = service;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public HealthCheckMiddleware(RequestDelegate next, IHealthCheckService service, string path)
|
||||
{
|
||||
_path = path;
|
||||
_service = service;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (IsHealthCheckRequest(context))
|
||||
{
|
||||
var result = await _service.CheckHealthAsync();
|
||||
var status = result.CheckStatus;
|
||||
|
||||
if (status != CheckStatus.Healthy)
|
||||
context.Response.StatusCode = 503;
|
||||
|
||||
context.Response.Headers.Add("content-type", "application/json");
|
||||
await context.Response.WriteAsync(JsonConvert.SerializeObject(new { status = status.ToString() }));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsHealthCheckRequest(HttpContext context)
|
||||
{
|
||||
if (_port.HasValue)
|
||||
{
|
||||
var connInfo = context.Features.Get<IHttpConnectionFeature>();
|
||||
if (connInfo.LocalPort == _port)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (context.Request.Path == _path)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Microsoft.AspNetCore.HealthChecks
|
||||
{
|
||||
public class HealthCheckStartupFilter : IStartupFilter
|
||||
{
|
||||
private string _path;
|
||||
private int? _port;
|
||||
|
||||
public HealthCheckStartupFilter(int port)
|
||||
{
|
||||
_port = port;
|
||||
}
|
||||
|
||||
public HealthCheckStartupFilter(string path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||
{
|
||||
return app =>
|
||||
{
|
||||
if (_port.HasValue)
|
||||
app.UseMiddleware<HealthCheckMiddleware>(_port);
|
||||
else
|
||||
app.UseMiddleware<HealthCheckMiddleware>(_path);
|
||||
|
||||
next(app);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.HealthChecks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
public static class HealthCheckWebHostBuilderExtension
|
||||
{
|
||||
public static IWebHostBuilder UseHealthChecks(this IWebHostBuilder builder, int port)
|
||||
{
|
||||
Guard.ArgumentValid(port > 0 && port < 65536, nameof(port), "Port must be a value between 1 and 65535");
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
var existingUrl = builder.GetSetting(WebHostDefaults.ServerUrlsKey);
|
||||
builder.UseSetting(WebHostDefaults.ServerUrlsKey, $"{existingUrl};http://localhost:{port}");
|
||||
|
||||
services.AddSingleton<IStartupFilter>(new HealthCheckStartupFilter(port));
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IWebHostBuilder UseHealthChecks(this IWebHostBuilder builder, string path)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(path), path);
|
||||
// REVIEW: Is there a better URL path validator somewhere?
|
||||
Guard.ArgumentValid(!path.Contains("?"), nameof(path), "Path cannot contain query string values");
|
||||
Guard.ArgumentValid(path.StartsWith("/"), nameof(path), "Path should start with /");
|
||||
|
||||
builder.ConfigureServices(services => services.AddSingleton<IStartupFilter>(new HealthCheckStartupFilter(path)));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.HealthChecks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
public static class HealthCheckWebHostExtensions
|
||||
{
|
||||
private const int DEFAULT_TIMEOUT_SECONDS = 300;
|
||||
|
||||
public static void RunWhenHealthy(this IWebHost webHost)
|
||||
{
|
||||
webHost.RunWhenHealthy(TimeSpan.FromSeconds(DEFAULT_TIMEOUT_SECONDS));
|
||||
}
|
||||
|
||||
public static void RunWhenHealthy(this IWebHost webHost, TimeSpan timeout)
|
||||
{
|
||||
var healthChecks = webHost.Services.GetService(typeof(IHealthCheckService)) as IHealthCheckService;
|
||||
|
||||
var loops = 0;
|
||||
do
|
||||
{
|
||||
var checkResult = healthChecks.CheckHealthAsync().Result;
|
||||
if (checkResult.CheckStatus == CheckStatus.Healthy)
|
||||
{
|
||||
webHost.Run();
|
||||
break;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
loops++;
|
||||
|
||||
} while (loops < timeout.TotalSeconds);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\common\Guard.cs" Link="Internal\Guard.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
|
||||
<ProjectReference Include="..\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,45 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static class HealthCheckBuilderDataExtensions
|
||||
{
|
||||
public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name, string connectionString)
|
||||
{
|
||||
builder.AddCheck($"SqlCheck({name})", async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
//TODO: There is probably a much better way to do this.
|
||||
using (var connection = new SqlConnection(connectionString))
|
||||
{
|
||||
connection.Open();
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandType = CommandType.Text;
|
||||
command.CommandText = "SELECT 1";
|
||||
var result = (int)await command.ExecuteScalarAsync().ConfigureAwait(false);
|
||||
if (result == 1)
|
||||
{
|
||||
return HealthCheckResult.Healthy($"SqlCheck({name}): Healthy");
|
||||
}
|
||||
|
||||
return HealthCheckResult.Unhealthy($"SqlCheck({name}): Unhealthy");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
return HealthCheckResult.Unhealthy($"SqlCheck({name}): Exception during check: {ex.GetType().FullName}");
|
||||
}
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.3</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\common\Guard.cs" Link="Internal\Guard.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,13 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public enum CheckStatus
|
||||
{
|
||||
Unknown,
|
||||
Unhealthy,
|
||||
Healthy,
|
||||
Warning
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static partial class HealthCheckBuilderExtensions
|
||||
{
|
||||
// Lambda versions of AddCheck for Func/Func<Task>/Func<ValueTask>
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<IHealthCheckResult> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, IHealthCheckResult> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<IHealthCheckResult> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, IHealthCheckResult> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<Task<IHealthCheckResult>> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromTaskCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, Task<IHealthCheckResult>> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromTaskCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<Task<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromTaskCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, Task<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromTaskCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func<ValueTask<IHealthCheckResult>> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, ValueTask<IHealthCheckResult>> check)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check, builder.DefaultCacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func<ValueTask<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func<CancellationToken, ValueTask<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
|
||||
builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check, cacheDuration));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static partial class HealthCheckBuilderExtensions
|
||||
{
|
||||
// Numeric checks
|
||||
|
||||
public static HealthCheckBuilder AddMinValueCheck<T>(this HealthCheckBuilder builder, string name, T minValue, Func<T> currentValueFunc)
|
||||
where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(name), name);
|
||||
Guard.ArgumentNotNull(nameof(currentValueFunc), currentValueFunc);
|
||||
|
||||
builder.AddCheck(name, () =>
|
||||
{
|
||||
var currentValue = currentValueFunc();
|
||||
var status = currentValue.CompareTo(minValue) >= 0 ? CheckStatus.Healthy : CheckStatus.Unhealthy;
|
||||
return HealthCheckResult.FromStatus(
|
||||
status,
|
||||
$"{name}: min={minValue}, current={currentValue}",
|
||||
new Dictionary<string, object> { { "min", minValue }, { "current", currentValue } }
|
||||
);
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddMaxValueCheck<T>(this HealthCheckBuilder builder, string name, T maxValue, Func<T> currentValueFunc)
|
||||
where T : IComparable<T>
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(name), name);
|
||||
Guard.ArgumentNotNull(nameof(currentValueFunc), currentValueFunc);
|
||||
|
||||
builder.AddCheck($"{name}", () =>
|
||||
{
|
||||
var currentValue = currentValueFunc();
|
||||
var status = currentValue.CompareTo(maxValue) <= 0 ? CheckStatus.Healthy : CheckStatus.Unhealthy;
|
||||
return HealthCheckResult.FromStatus(
|
||||
status,
|
||||
$"{name}: max={maxValue}, current={currentValue}",
|
||||
new Dictionary<string, object> { { "max", maxValue }, { "current", currentValue } }
|
||||
);
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static partial class HealthCheckBuilderExtensions
|
||||
{
|
||||
// System checks
|
||||
|
||||
public static HealthCheckBuilder AddPrivateMemorySizeCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"PrivateMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().PrivateMemorySize64);
|
||||
|
||||
public static HealthCheckBuilder AddVirtualMemorySizeCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"VirtualMemorySize({maxSize})", maxSize, () => Process.GetCurrentProcess().VirtualMemorySize64);
|
||||
|
||||
public static HealthCheckBuilder AddWorkingSetCheck(this HealthCheckBuilder builder, long maxSize)
|
||||
=> AddMaxValueCheck(builder, $"WorkingSet({maxSize})", maxSize, () => Process.GetCurrentProcess().WorkingSet64);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.HealthChecks.Internal;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static partial class HealthCheckBuilderExtensions
|
||||
{
|
||||
// URL checks
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url)
|
||||
=> AddUrlCheck(builder, url, response => UrlChecker.DefaultUrlCheck(response));
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, IHealthCheckResult> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlCheck(builder, url, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url,
|
||||
Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(url), url);
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
var urlCheck = new UrlChecker(checkFunc, url);
|
||||
builder.AddCheck($"UrlCheck({url})", () => urlCheck.CheckAsync());
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName)
|
||||
=> AddUrlChecks(builder, urlItems, groupName, CheckStatus.Warning, response => UrlChecker.DefaultUrlCheck(response));
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
Func<HttpResponseMessage, IHealthCheckResult> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlChecks(builder, urlItems, groupName, CheckStatus.Warning, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlChecks(builder, urlItems, groupName, CheckStatus.Warning, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlChecks(builder, urlItems, groupName, CheckStatus.Warning, response => checkFunc(response));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
CheckStatus partialSuccessStatus)
|
||||
=> AddUrlChecks(builder, urlItems, groupName, partialSuccessStatus, response => UrlChecker.DefaultUrlCheck(response));
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
CheckStatus partialSuccessStatus, Func<HttpResponseMessage, IHealthCheckResult> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlChecks(builder, urlItems, groupName, partialSuccessStatus, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
CheckStatus partialSuccessStatus, Func<HttpResponseMessage, Task<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
|
||||
return AddUrlChecks(builder, urlItems, groupName, partialSuccessStatus, response => new ValueTask<IHealthCheckResult>(checkFunc(response)));
|
||||
}
|
||||
|
||||
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable<string> urlItems, string groupName,
|
||||
CheckStatus partialSuccessStatus, Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc)
|
||||
{
|
||||
var urls = urlItems?.ToArray();
|
||||
|
||||
Guard.ArgumentNotNull(nameof(builder), builder);
|
||||
Guard.ArgumentNotNullOrEmpty(nameof(urlItems), urls);
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(groupName), groupName);
|
||||
|
||||
var urlChecker = new UrlChecker(checkFunc, urls) { PartiallyHealthyStatus = partialSuccessStatus };
|
||||
builder.AddCheck($"UrlChecks({groupName})", () => urlChecker.CheckAsync());
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
// REVIEW: Does this need to be thread safe?
|
||||
/// <summary>
|
||||
/// Represents a composite health check result built from several results.
|
||||
/// </summary>
|
||||
public class CompositeHealthCheckResult : IHealthCheckResult
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, object> _emptyData = new Dictionary<string, object>();
|
||||
private readonly CheckStatus _initialStatus;
|
||||
private readonly CheckStatus _partiallyHealthyStatus;
|
||||
private readonly Dictionary<string, IHealthCheckResult> _results = new Dictionary<string, IHealthCheckResult>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public CompositeHealthCheckResult(CheckStatus partiallyHealthyStatus = CheckStatus.Warning,
|
||||
CheckStatus initialStatus = CheckStatus.Unknown)
|
||||
{
|
||||
_partiallyHealthyStatus = partiallyHealthyStatus;
|
||||
_initialStatus = initialStatus;
|
||||
}
|
||||
|
||||
public CheckStatus CheckStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
var checkStatuses = new HashSet<CheckStatus>(_results.Select(x => x.Value.CheckStatus));
|
||||
if (checkStatuses.Count == 0)
|
||||
return _initialStatus;
|
||||
if (checkStatuses.Count == 1)
|
||||
return checkStatuses.First();
|
||||
if (checkStatuses.Contains(CheckStatus.Healthy))
|
||||
return _partiallyHealthyStatus;
|
||||
|
||||
return CheckStatus.Unhealthy;
|
||||
}
|
||||
}
|
||||
|
||||
public string Description => string.Join(Environment.NewLine, _results.Select(r => r.Value.Description));
|
||||
|
||||
public IReadOnlyDictionary<string, object> Data
|
||||
{
|
||||
get
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
|
||||
foreach (var kvp in _results)
|
||||
result.Add(kvp.Key, kvp.Value.Data);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, IHealthCheckResult> Results => _results;
|
||||
|
||||
// REVIEW: Should description be required? Seems redundant for success checks.
|
||||
|
||||
public void Add(string name, CheckStatus status, string description)
|
||||
=> Add(name, status, description, null);
|
||||
|
||||
public void Add(string name, CheckStatus status, string description, Dictionary<string, object> data)
|
||||
{
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(name), name);
|
||||
Guard.ArgumentValid(status != CheckStatus.Unknown, nameof(status), "Cannot add unknown status to composite health check result");
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(description), description);
|
||||
|
||||
_results.Add(name, HealthCheckResult.FromStatus(status, description, data));
|
||||
}
|
||||
|
||||
public void Add(string name, IHealthCheckResult checkResult)
|
||||
{
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(name), name);
|
||||
Guard.ArgumentNotNull(nameof(checkResult), checkResult);
|
||||
|
||||
_results.Add(name, checkResult);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public class HealthCheck : IHealthCheck
|
||||
{
|
||||
private DateTimeOffset _cacheExpiration;
|
||||
private IHealthCheckResult _cachedResult;
|
||||
private volatile int _writerCount;
|
||||
|
||||
protected HealthCheck(Func<CancellationToken, ValueTask<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(check), check);
|
||||
Guard.ArgumentValid(cacheDuration >= TimeSpan.Zero, nameof(cacheDuration), "Cache duration must either be zero (disabled) or a positive value");
|
||||
|
||||
Check = check;
|
||||
CacheDuration = cacheDuration;
|
||||
}
|
||||
|
||||
public TimeSpan CacheDuration { get; }
|
||||
|
||||
protected Func<CancellationToken, ValueTask<IHealthCheckResult>> Check { get; }
|
||||
|
||||
protected virtual DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
|
||||
|
||||
public async ValueTask<IHealthCheckResult> CheckAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (_cacheExpiration <= UtcNow)
|
||||
{
|
||||
// Can't use a standard lock here because of async, so we'll use this flag to determine when we should write a value,
|
||||
// and the waiters who aren't allowed to write will just spin wait for the new value.
|
||||
if (Interlocked.Exchange(ref _writerCount, 1) != 0)
|
||||
{
|
||||
await Task.Delay(5, cancellationToken).ConfigureAwait(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_cachedResult = await Check(cancellationToken).ConfigureAwait(false);
|
||||
_cacheExpiration = UtcNow + CacheDuration;
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writerCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return _cachedResult;
|
||||
}
|
||||
|
||||
public static HealthCheck FromCheck(Func<IHealthCheckResult> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(token => new ValueTask<IHealthCheckResult>(check()), cacheDuration);
|
||||
|
||||
public static HealthCheck FromCheck(Func<CancellationToken, IHealthCheckResult> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(token => new ValueTask<IHealthCheckResult>(check(token)), cacheDuration);
|
||||
|
||||
public static HealthCheck FromTaskCheck(Func<Task<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(token => new ValueTask<IHealthCheckResult>(check()), cacheDuration);
|
||||
|
||||
public static HealthCheck FromTaskCheck(Func<CancellationToken, Task<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(token => new ValueTask<IHealthCheckResult>(check(token)), cacheDuration);
|
||||
|
||||
public static HealthCheck FromValueTaskCheck(Func<ValueTask<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(token => check(), cacheDuration);
|
||||
|
||||
public static HealthCheck FromValueTaskCheck(Func<CancellationToken, ValueTask<IHealthCheckResult>> check, TimeSpan cacheDuration)
|
||||
=> new HealthCheck(check, cacheDuration);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public class HealthCheckBuilder
|
||||
{
|
||||
private readonly Dictionary<string, IHealthCheck> _checks;
|
||||
|
||||
public HealthCheckBuilder()
|
||||
{
|
||||
_checks = new Dictionary<string, IHealthCheck>(StringComparer.OrdinalIgnoreCase);
|
||||
DefaultCacheDuration = TimeSpan.FromMinutes(5);
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, IHealthCheck> Checks => _checks;
|
||||
|
||||
public TimeSpan DefaultCacheDuration { get; private set; }
|
||||
|
||||
public HealthCheckBuilder AddCheck(string name, IHealthCheck check)
|
||||
{
|
||||
Guard.ArgumentNotNullOrWhitespace(nameof(name), name);
|
||||
Guard.ArgumentNotNull(nameof(check), check);
|
||||
|
||||
_checks.Add(name, check);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HealthCheckBuilder WithDefaultCacheDuration(TimeSpan duration)
|
||||
{
|
||||
Guard.ArgumentValid(duration >= TimeSpan.Zero, nameof(duration), "Duration must be zero (disabled) or a positive duration");
|
||||
|
||||
DefaultCacheDuration = duration;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static class HealthCheckExtensions
|
||||
{
|
||||
public static ValueTask<IHealthCheckResult> CheckAsync(this IHealthCheck healthCheck)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(healthCheck), healthCheck);
|
||||
|
||||
return healthCheck.CheckAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public class HealthCheckResult : IHealthCheckResult
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, object> _emptyData = new Dictionary<string, object>();
|
||||
|
||||
public CheckStatus CheckStatus { get; }
|
||||
public IReadOnlyDictionary<string, object> Data { get; }
|
||||
public string Description { get; }
|
||||
|
||||
private HealthCheckResult(CheckStatus checkStatus, string description, IReadOnlyDictionary<string, object> data)
|
||||
{
|
||||
CheckStatus = checkStatus;
|
||||
Description = description;
|
||||
Data = data ?? _emptyData;
|
||||
}
|
||||
|
||||
public static HealthCheckResult Unhealthy(string description)
|
||||
=> new HealthCheckResult(CheckStatus.Unhealthy, description, null);
|
||||
|
||||
public static HealthCheckResult Unhealthy(string description, IReadOnlyDictionary<string, object> data)
|
||||
=> new HealthCheckResult(CheckStatus.Unhealthy, description, data);
|
||||
|
||||
public static HealthCheckResult Healthy(string description)
|
||||
=> new HealthCheckResult(CheckStatus.Healthy, description, null);
|
||||
|
||||
public static HealthCheckResult Healthy(string description, IReadOnlyDictionary<string, object> data)
|
||||
=> new HealthCheckResult(CheckStatus.Healthy, description, data);
|
||||
|
||||
public static HealthCheckResult Warning(string description)
|
||||
=> new HealthCheckResult(CheckStatus.Warning, description, null);
|
||||
|
||||
public static HealthCheckResult Warning(string description, IReadOnlyDictionary<string, object> data)
|
||||
=> new HealthCheckResult(CheckStatus.Warning, description, data);
|
||||
|
||||
public static HealthCheckResult Unknown(string description)
|
||||
=> new HealthCheckResult(CheckStatus.Unknown, description, null);
|
||||
|
||||
public static HealthCheckResult Unknown(string description, IReadOnlyDictionary<string, object> data)
|
||||
=> new HealthCheckResult(CheckStatus.Unknown, description, data);
|
||||
|
||||
public static HealthCheckResult FromStatus(CheckStatus status, string description)
|
||||
=> new HealthCheckResult(status, description, null);
|
||||
|
||||
public static HealthCheckResult FromStatus(CheckStatus status, string description, IReadOnlyDictionary<string, object> data)
|
||||
=> new HealthCheckResult(status, description, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public class HealthCheckResults
|
||||
{
|
||||
public IList<IHealthCheckResult> CheckResults { get; } = new List<IHealthCheckResult>();
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public class HealthCheckService : IHealthCheckService
|
||||
{
|
||||
public IReadOnlyDictionary<string, IHealthCheck> _checks;
|
||||
|
||||
private ILogger<HealthCheckService> _logger;
|
||||
|
||||
public HealthCheckService(HealthCheckBuilder builder, ILogger<HealthCheckService> logger)
|
||||
{
|
||||
_checks = builder.Checks;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<CompositeHealthCheckResult> CheckHealthAsync(CheckStatus partiallyHealthyStatus, CancellationToken cancellationToken)
|
||||
{
|
||||
var logMessage = new StringBuilder();
|
||||
var result = new CompositeHealthCheckResult(partiallyHealthyStatus);
|
||||
|
||||
foreach (var check in _checks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var healthCheckResult = await check.Value.CheckAsync().ConfigureAwait(false);
|
||||
logMessage.AppendLine($"HealthCheck: {check.Key} : {healthCheckResult.CheckStatus}");
|
||||
result.Add(check.Key, healthCheckResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logMessage.AppendLine($"HealthCheck: {check.Key} : Exception {ex.GetType().FullName} thrown");
|
||||
result.Add(check.Key, CheckStatus.Unhealthy, $"Exception during check: {ex.GetType().FullName}");
|
||||
}
|
||||
}
|
||||
|
||||
if (logMessage.Length == 0)
|
||||
logMessage.AppendLine("HealthCheck: No checks have been registered");
|
||||
|
||||
_logger.Log((result.CheckStatus == CheckStatus.Healthy ? LogLevel.Information : LogLevel.Error), 0, logMessage.ToString(), null, MessageFormatter);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string MessageFormatter(string state, Exception error) => state;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.HealthChecks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class HealthCheckServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddHealthChecks(this IServiceCollection services, Action<HealthCheckBuilder> checkupAction)
|
||||
{
|
||||
var checkupBuilder = new HealthCheckBuilder();
|
||||
|
||||
checkupAction.Invoke(checkupBuilder);
|
||||
|
||||
services.AddSingleton(checkupBuilder);
|
||||
services.AddSingleton<IHealthCheckService, HealthCheckService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public static class HealthCheckServiceExtensions
|
||||
{
|
||||
public static Task<CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(service), service);
|
||||
|
||||
return service.CheckHealthAsync(CheckStatus.Unhealthy, CancellationToken.None);
|
||||
}
|
||||
|
||||
public static Task<CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service, CheckStatus partiallyHealthyStatus)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(service), service);
|
||||
|
||||
return service.CheckHealthAsync(partiallyHealthyStatus, CancellationToken.None);
|
||||
}
|
||||
|
||||
public static Task<CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service, CancellationToken cancellationToken)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(service), service);
|
||||
|
||||
return service.CheckHealthAsync(CheckStatus.Unhealthy, cancellationToken);
|
||||
}
|
||||
public static Task<CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service, CheckStatus partiallyHealthyStatus, CancellationToken cancellationToken)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(service), service);
|
||||
|
||||
return service.CheckHealthAsync(partiallyHealthyStatus, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public interface IHealthCheck
|
||||
{
|
||||
TimeSpan CacheDuration { get; }
|
||||
|
||||
ValueTask<IHealthCheckResult> CheckAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public interface IHealthCheckResult
|
||||
{
|
||||
CheckStatus CheckStatus { get; }
|
||||
string Description { get; }
|
||||
IReadOnlyDictionary<string, object> Data { get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks
|
||||
{
|
||||
public interface IHealthCheckService
|
||||
{
|
||||
Task<CompositeHealthCheckResult> CheckHealthAsync(CheckStatus partiallyHealthyStatus, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.HealthChecks.Internal
|
||||
{
|
||||
public class UrlChecker
|
||||
{
|
||||
private readonly Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> _checkFunc;
|
||||
private readonly string[] _urls;
|
||||
|
||||
// REVIEW: Cache timeout here?
|
||||
public UrlChecker(Func<HttpResponseMessage, ValueTask<IHealthCheckResult>> checkFunc, params string[] urls)
|
||||
{
|
||||
Guard.ArgumentNotNull(nameof(checkFunc), checkFunc);
|
||||
Guard.ArgumentNotNullOrEmpty(nameof(urls), urls);
|
||||
|
||||
_checkFunc = checkFunc;
|
||||
_urls = urls;
|
||||
}
|
||||
|
||||
public CheckStatus PartiallyHealthyStatus { get; set; } = CheckStatus.Warning;
|
||||
|
||||
public Task<IHealthCheckResult> CheckAsync()
|
||||
=> _urls.Length == 1 ? CheckSingleAsync() : CheckMultiAsync();
|
||||
|
||||
public async Task<IHealthCheckResult> CheckSingleAsync()
|
||||
{
|
||||
var httpClient = CreateHttpClient();
|
||||
var result = default(IHealthCheckResult);
|
||||
await CheckUrlAsync(httpClient, _urls[0], (_, checkResult) => result = checkResult).ConfigureAwait(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IHealthCheckResult> CheckMultiAsync()
|
||||
{
|
||||
var composite = new CompositeHealthCheckResult(PartiallyHealthyStatus);
|
||||
var httpClient = CreateHttpClient();
|
||||
|
||||
// REVIEW: Should these be done in parallel?
|
||||
foreach (var url in _urls)
|
||||
await CheckUrlAsync(httpClient, url, (name, checkResult) => composite.Add(name, checkResult)).ConfigureAwait(false);
|
||||
|
||||
return composite;
|
||||
}
|
||||
|
||||
private async Task CheckUrlAsync(HttpClient httpClient, string url, Action<string, IHealthCheckResult> adder)
|
||||
{
|
||||
var name = $"UrlCheck({url})";
|
||||
try
|
||||
{
|
||||
var response = await httpClient.GetAsync(url).ConfigureAwait(false);
|
||||
var result = await _checkFunc(response);
|
||||
adder(name, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
adder(name, HealthCheckResult.Unhealthy($"Exception during check: {ex.GetType().FullName}"));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpClient CreateHttpClient()
|
||||
{
|
||||
var httpClient = GetHttpClient();
|
||||
httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public static async ValueTask<IHealthCheckResult> DefaultUrlCheck(HttpResponseMessage response)
|
||||
{
|
||||
// REVIEW: Should this be an explicit 200 check, or just an "is success" check?
|
||||
var status = response.StatusCode == HttpStatusCode.OK ? CheckStatus.Healthy : CheckStatus.Unhealthy;
|
||||
var data = new Dictionary<string, object>
|
||||
{
|
||||
{ "url", response.RequestMessage.RequestUri.ToString() },
|
||||
{ "status", (int)response.StatusCode },
|
||||
{ "reason", response.ReasonPhrase },
|
||||
{ "body", await response.Content?.ReadAsStringAsync() }
|
||||
};
|
||||
return HealthCheckResult.FromStatus(status, $"UrlCheck({response.RequestMessage.RequestUri}): status code {response.StatusCode} ({(int)response.StatusCode})", data);
|
||||
}
|
||||
|
||||
protected virtual HttpClient GetHttpClient()
|
||||
=> new HttpClient();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.3</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\common\Guard.cs" Link="Internal\Guard.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Thread" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
45
src/BuildingBlocks/HealthChecks/src/common/Guard.cs
Normal file
45
src/BuildingBlocks/HealthChecks/src/common/Guard.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
static class Guard
|
||||
{
|
||||
public static void ArgumentNotNull(string argumentName, object value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(argumentName);
|
||||
}
|
||||
|
||||
public static void ArgumentNotNullOrEmpty<T>(string argumentName, string value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(argumentName);
|
||||
if (string.IsNullOrEmpty(value))
|
||||
throw new ArgumentException("Value cannot be an empty string", argumentName);
|
||||
}
|
||||
|
||||
// Use IReadOnlyCollection<T> instead of IEnumerable<T> to discourage double enumeration
|
||||
public static void ArgumentNotNullOrEmpty<T>(string argumentName, IReadOnlyCollection<T> items)
|
||||
{
|
||||
if (items == null)
|
||||
throw new ArgumentNullException(argumentName);
|
||||
if (items.Count == 0)
|
||||
throw new ArgumentException("Collection must contain at least one item", argumentName);
|
||||
}
|
||||
|
||||
public static void ArgumentNotNullOrWhitespace(string argumentName, string value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(argumentName);
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
throw new ArgumentException("Value must contain a non-whitespace value", argumentName);
|
||||
}
|
||||
|
||||
public static void ArgumentValid(bool valid, string argumentName, string exceptionMessage)
|
||||
{
|
||||
if (!valid)
|
||||
throw new ArgumentException(exceptionMessage, argumentName);
|
||||
}
|
||||
}
|
16
src/BuildingBlocks/Resilience/Resilience.Http/IHttpClient.cs
Normal file
16
src/BuildingBlocks/Resilience/Resilience.Http/IHttpClient.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public interface IHttpClient
|
||||
{
|
||||
HttpClient Inst { get; }
|
||||
Task<string> GetStringAsync(string uri);
|
||||
Task<HttpResponseMessage> PostAsync<T>(string uri, T item);
|
||||
Task<HttpResponseMessage> DeleteAsync(string uri);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="Polly" Version="5.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public class ResiliencePolicy
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Polly;
|
||||
using Polly.Wrap;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// HttpClient wrapper that integrates Retry and Circuit
|
||||
/// breaker policies when invoking HTTP services.
|
||||
/// Based on Polly library: https://github.com/App-vNext/Polly
|
||||
/// </summary>
|
||||
public class ResilientHttpClient : IHttpClient
|
||||
{
|
||||
private HttpClient _client;
|
||||
private PolicyWrap _policyWrapper;
|
||||
private ILogger<ResilientHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
|
||||
public ResilientHttpClient(Policy[] policies, ILogger<ResilientHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
|
||||
// Add Policies to be applied
|
||||
_policyWrapper = Policy.WrapAsync(policies);
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
HttpInvoker(() =>
|
||||
_client.GetStringAsync(uri));
|
||||
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item) =>
|
||||
// a new StringContent must be created for each retry
|
||||
// as it is disposed after each call
|
||||
HttpInvoker(() =>
|
||||
{
|
||||
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
|
||||
// raise exception if HttpResponseCode 500
|
||||
// needed for circuit breaker to track fails
|
||||
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new HttpRequestException();
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
HttpInvoker(() => _client.DeleteAsync(uri));
|
||||
|
||||
|
||||
private Task<T> HttpInvoker<T>(Func<Task<T>> action) =>
|
||||
// Executes the action applying all
|
||||
// the policies defined in the wrapper
|
||||
_policyWrapper.ExecuteAsync(() => action());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public class StandardHttpClient : IHttpClient
|
||||
{
|
||||
private HttpClient _client;
|
||||
private ILogger<StandardHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
public StandardHttpClient(ILogger<StandardHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
_client.GetStringAsync(uri);
|
||||
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item)
|
||||
{
|
||||
var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
return _client.PostAsync(uri, contentString);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
_client.DeleteAsync(uri);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:light="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Light"
|
||||
xmlns:converters="clr-namespace:eShopOnContainers.Core.Converters;assembly=eShopOnContainers.Core"
|
||||
xmlns:effects="clr-namespace:eShopOnContainers.Core.Effects;assembly=eShopOnContainers.Core"
|
||||
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
|
||||
x:Class="eShopOnContainers.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary MergedWith="light:LightThemeResources">
|
||||
@ -17,6 +17,7 @@
|
||||
<Color x:Key="GreenColor">#00A69C</Color>
|
||||
<Color x:Key="DarkGreenColor">#00857D</Color>
|
||||
<Color x:Key="GrayColor">#e2e2e2</Color>
|
||||
<Color x:Key="ErrorColor">#ff5252</Color>
|
||||
|
||||
<!-- FONTS -->
|
||||
<OnPlatform
|
||||
@ -100,15 +101,25 @@
|
||||
<!-- CONVERTERS -->
|
||||
<converters:CountToBoolConverter x:Key="CountToBoolConverter" />
|
||||
<converters:DatetimeConverter x:Key="DatetimeConverter" />
|
||||
<converters:FirstValidationErrorConverter x:Key="FirstValidationErrorConverter" />
|
||||
<converters:ImageConverter x:Key="ImageConverter" />
|
||||
<converters:ItemTappedEventArgsConverter x:Key="ItemTappedEventArgsConverter" />
|
||||
<converters:InverseCountToBoolConverter x:Key="InverseCountToBoolConverter" />
|
||||
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
|
||||
<converters:ItemsToHeightConverter x:Key="ItemsToHeightConverter" />
|
||||
<converters:ToUpperConverter x:Key="ToUpperConverter" />
|
||||
<converters:WebNavigatingEventArgsConverter x:Key="WebNavigatingEventArgsConverter" />
|
||||
|
||||
<converters:WebNavigatingEventArgsConverter x:Key="WebNavigatingEventArgsConverter" />
|
||||
<converters:WebNavigatedEventArgsConverter x:Key="WebNavigatedEventArgsConverter" />
|
||||
|
||||
<!-- STYLES -->
|
||||
<Style x:Key="ValidationErrorLabelStyle"
|
||||
TargetType="{x:Type Label}">
|
||||
<Setter Property="TextColor"
|
||||
Value="{StaticResource ErrorColor}" />
|
||||
<Setter Property="FontSize"
|
||||
Value="{StaticResource LittleSize}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="EntryStyle"
|
||||
TargetType="{x:Type Entry}">
|
||||
<Setter Property="FontFamily"
|
||||
@ -125,9 +136,9 @@
|
||||
Value="Bold" />
|
||||
<Setter Property="Opacity"
|
||||
Value="0.6" />
|
||||
<Setter Property="effects:LineColorEffect.ApplyLineColor"
|
||||
<Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
|
||||
Value="True" />
|
||||
<Setter Property="effects:LineColorEffect.LineColor"
|
||||
<Setter Property="behaviors:LineColorBehavior.LineColor"
|
||||
Value="{StaticResource BlackColor}" />
|
||||
<Style.Triggers>
|
||||
<Trigger TargetType="Entry"
|
||||
@ -156,16 +167,16 @@
|
||||
Value="Transparent" />
|
||||
<Setter Property="Opacity"
|
||||
Value="0.6" />
|
||||
<Setter Property="effects:LineColorEffect.ApplyLineColor"
|
||||
<Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
|
||||
Value="True" />
|
||||
<Setter Property="effects:LineColorEffect.LineColor"
|
||||
<Setter Property="behaviors:LineColorBehavior.LineColor"
|
||||
Value="Gray" />
|
||||
<Style.Triggers>
|
||||
<Trigger TargetType="Entry"
|
||||
Property="IsFocused"
|
||||
Value="True">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
<Setter Property="effects:LineColorEffect.LineColor"
|
||||
<Setter Property="behaviors:LineColorBehavior.LineColor"
|
||||
Value="{StaticResource GreenColor}" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
|
@ -1,6 +1,6 @@
|
||||
using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Services;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
@ -27,13 +27,13 @@ namespace eShopOnContainers
|
||||
private void InitApp()
|
||||
{
|
||||
UseMockServices = Settings.UseMocks;
|
||||
|
||||
ViewModelLocator.Instance.UpdateDependencies(UseMockServices);
|
||||
ViewModelLocator.Initialize();
|
||||
ViewModelLocator.UpdateDependencies(UseMockServices);
|
||||
}
|
||||
|
||||
private Task InitNavigation()
|
||||
{
|
||||
var navigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
|
||||
var navigationService = ViewModelLocator.Resolve<INavigationService>();
|
||||
return navigationService.InitializeAsync();
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,18 @@
|
||||
using System.Linq;
|
||||
using Xamarin.Forms;
|
||||
using eShopOnContainers.Core.Effects;
|
||||
|
||||
namespace eShopOnContainers.Core.Effects
|
||||
namespace eShopOnContainers.Core.Behaviors
|
||||
{
|
||||
public static class LineColorEffect
|
||||
public static class LineColorBehavior
|
||||
{
|
||||
public static readonly BindableProperty ApplyLineColorProperty =
|
||||
BindableProperty.CreateAttached("ApplyLineColor", typeof(bool), typeof(LineColorEffect), false,
|
||||
BindableProperty.CreateAttached("ApplyLineColor", typeof(bool), typeof(LineColorBehavior), false,
|
||||
propertyChanged: OnApplyLineColorChanged);
|
||||
|
||||
public static readonly BindableProperty LineColorProperty =
|
||||
BindableProperty.CreateAttached("LineColor", typeof(Color), typeof(LineColorBehavior), Color.Default);
|
||||
|
||||
public static bool GetApplyLineColor(BindableObject view)
|
||||
{
|
||||
return (bool)view.GetValue(ApplyLineColorProperty);
|
||||
@ -19,6 +23,16 @@ namespace eShopOnContainers.Core.Effects
|
||||
view.SetValue(ApplyLineColorProperty, value);
|
||||
}
|
||||
|
||||
public static Color GetLineColor(BindableObject view)
|
||||
{
|
||||
return (Color)view.GetValue(LineColorProperty);
|
||||
}
|
||||
|
||||
public static void SetLineColor(BindableObject view, Color value)
|
||||
{
|
||||
view.SetValue(LineColorProperty, value);
|
||||
}
|
||||
|
||||
private static void OnApplyLineColorChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var view = bindable as View;
|
||||
@ -28,9 +42,9 @@ namespace eShopOnContainers.Core.Effects
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasShadow = (bool)newValue;
|
||||
bool hasLine = (bool)newValue;
|
||||
|
||||
if (hasShadow)
|
||||
if (hasLine)
|
||||
{
|
||||
view.Effects.Add(new EntryLineColorEffect());
|
||||
}
|
||||
@ -43,25 +57,5 @@ namespace eShopOnContainers.Core.Effects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly BindableProperty LineColorProperty =
|
||||
BindableProperty.CreateAttached("LineColor", typeof(Color), typeof(LineColorEffect), Color.Default);
|
||||
|
||||
public static Color GetLineColor(BindableObject view)
|
||||
{
|
||||
return (Color)view.GetValue(LineColorProperty);
|
||||
}
|
||||
|
||||
public static void SetLineColor(BindableObject view, Color value)
|
||||
{
|
||||
view.SetValue(LineColorProperty, value);
|
||||
}
|
||||
|
||||
class EntryLineColorEffect : RoutingEffect
|
||||
{
|
||||
public EntryLineColorEffect() : base("eShopOnContainers.EntryLineColorEffect")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.Core.Converters
|
||||
{
|
||||
public class FirstValidationErrorConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
ICollection<string> errors = value as ICollection<string>;
|
||||
return errors != null && errors.Count > 0 ? errors.ElementAt(0) : null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.Core.Converters
|
||||
{
|
||||
public class WebNavigatedEventArgsConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var eventArgs = value as WebNavigatedEventArgs;
|
||||
if (eventArgs == null)
|
||||
throw new ArgumentException("Expected WebNavigatedEventArgs as value", "value");
|
||||
|
||||
return eventArgs.Url;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.Core.Effects
|
||||
{
|
||||
public class EntryLineColorEffect : RoutingEffect
|
||||
{
|
||||
public EntryLineColorEffect() : base("eShopOnContainers.EntryLineColorEffect")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using eShopOnContainers.Core.Animations.Base;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.Core.Extensions
|
||||
{
|
||||
public static class AnimationExtension
|
||||
{
|
||||
public static async void Animate(this VisualElement visualElement, AnimationBase animation, Action onFinishedCallback = null)
|
||||
{
|
||||
animation.Target = visualElement;
|
||||
|
||||
await animation.Begin();
|
||||
|
||||
onFinishedCallback?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@
|
||||
IdentityEndpoint = string.Format("{0}:5105/connect/authorize", baseEndpoint);
|
||||
UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint);
|
||||
LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint);
|
||||
IdentityCallback = "http://eshopxamarin/callback.html";
|
||||
IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint);
|
||||
LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using eShopOnContainers.Core.Models.Basket;
|
||||
using eShopOnContainers.Core.Models.Catalog;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@ -21,7 +21,7 @@ namespace eShopOnContainers.Core.Helpers
|
||||
|
||||
try
|
||||
{
|
||||
if (!ViewModelLocator.Instance.UseMockService
|
||||
if (!ViewModelLocator.UseMockService
|
||||
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
|
||||
{
|
||||
foreach (var catalogItem in catalogItems)
|
||||
@ -54,7 +54,7 @@ namespace eShopOnContainers.Core.Helpers
|
||||
|
||||
try
|
||||
{
|
||||
if (!ViewModelLocator.Instance.UseMockService
|
||||
if (!ViewModelLocator.UseMockService
|
||||
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
|
||||
{
|
||||
foreach (var basketItem in basketItems)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using Plugin.Settings;
|
||||
using Plugin.Settings.Abstractions;
|
||||
|
||||
@ -27,7 +27,7 @@ namespace eShopOnContainers.Core.Helpers
|
||||
private const string IdUrlBase = "url_base";
|
||||
private static readonly string AccessTokenDefault = string.Empty;
|
||||
private static readonly string IdTokenDefault = string.Empty;
|
||||
private static readonly bool UseMocksDefault = ViewModelLocator.Instance.UseMockService;
|
||||
private static readonly bool UseMocksDefault = true;
|
||||
private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
|
||||
|
||||
#endregion
|
||||
|
@ -15,6 +15,16 @@ namespace eShopOnContainers.Core.Models.Basket
|
||||
|
||||
public decimal UnitPrice { get; set; }
|
||||
|
||||
public decimal OldUnitPrice { get; set; }
|
||||
|
||||
public bool HasNewPrice
|
||||
{
|
||||
get
|
||||
{
|
||||
return OldUnitPrice != 0.0m;
|
||||
}
|
||||
}
|
||||
|
||||
public int Quantity
|
||||
{
|
||||
get { return _quantity; }
|
||||
|
@ -34,6 +34,9 @@ namespace eShopOnContainers.Core.Models.Orders
|
||||
[JsonProperty("country")]
|
||||
public string ShippingCountry { get; set; }
|
||||
|
||||
[JsonProperty("zipCode")]
|
||||
public string ShippingZipCode { get; set; }
|
||||
|
||||
public int CardTypeId { get; set; }
|
||||
|
||||
public string CardNumber { get; set; }
|
||||
|
@ -1,5 +1,4 @@
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using System;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace eShopOnContainers.Services
|
||||
@ -12,12 +11,6 @@ namespace eShopOnContainers.Services
|
||||
|
||||
Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase;
|
||||
|
||||
Task NavigateToAsync(Type viewModelType);
|
||||
|
||||
Task NavigateToAsync(Type viewModelType, object parameter);
|
||||
|
||||
Task NavigateBackAsync();
|
||||
|
||||
Task RemoveLastFromBackStackAsync();
|
||||
|
||||
Task RemoveBackStackAsync();
|
||||
|
@ -1,9 +1,10 @@
|
||||
using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Core.ViewModels;
|
||||
using eShopOnContainers.Core.Views;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@ -11,23 +12,6 @@ namespace eShopOnContainers.Services
|
||||
{
|
||||
public class NavigationService : INavigationService
|
||||
{
|
||||
protected readonly Dictionary<Type, Type> _mappings;
|
||||
|
||||
protected Application CurrentApplication
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public NavigationService()
|
||||
{
|
||||
_mappings = new Dictionary<Type, Type>();
|
||||
|
||||
CreatePageViewModelMappings();
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
{
|
||||
if(string.IsNullOrEmpty(Settings.AuthAccessToken))
|
||||
@ -46,32 +30,9 @@ namespace eShopOnContainers.Services
|
||||
return InternalNavigateToAsync(typeof(TViewModel), parameter);
|
||||
}
|
||||
|
||||
public Task NavigateToAsync(Type viewModelType)
|
||||
public Task RemoveLastFromBackStackAsync()
|
||||
{
|
||||
return InternalNavigateToAsync(viewModelType, null);
|
||||
}
|
||||
|
||||
public Task NavigateToAsync(Type viewModelType, object parameter)
|
||||
{
|
||||
return InternalNavigateToAsync(viewModelType, parameter);
|
||||
}
|
||||
|
||||
public async Task NavigateBackAsync()
|
||||
{
|
||||
if (CurrentApplication.MainPage is CatalogView)
|
||||
{
|
||||
var mainPage = CurrentApplication.MainPage as CatalogView;
|
||||
await mainPage.Navigation.PopAsync();
|
||||
}
|
||||
else if (CurrentApplication.MainPage != null)
|
||||
{
|
||||
await CurrentApplication.MainPage.Navigation.PopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Task RemoveLastFromBackStackAsync()
|
||||
{
|
||||
var mainPage = CurrentApplication.MainPage as CustomNavigationView;
|
||||
var mainPage = Application.Current.MainPage as CustomNavigationView;
|
||||
|
||||
if (mainPage != null)
|
||||
{
|
||||
@ -82,9 +43,9 @@ namespace eShopOnContainers.Services
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public virtual Task RemoveBackStackAsync()
|
||||
public Task RemoveBackStackAsync()
|
||||
{
|
||||
var mainPage = CurrentApplication.MainPage as CustomNavigationView;
|
||||
var mainPage = Application.Current.MainPage as CustomNavigationView;
|
||||
|
||||
if (mainPage != null)
|
||||
{
|
||||
@ -98,67 +59,49 @@ namespace eShopOnContainers.Services
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
protected virtual async Task InternalNavigateToAsync(Type viewModelType, object parameter)
|
||||
private async Task InternalNavigateToAsync(Type viewModelType, object parameter)
|
||||
{
|
||||
Page page = CreateAndBindPage(viewModelType, parameter);
|
||||
Page page = CreatePage(viewModelType, parameter);
|
||||
|
||||
if (page is LoginView)
|
||||
{
|
||||
CurrentApplication.MainPage = new CustomNavigationView(page);
|
||||
Application.Current.MainPage = new CustomNavigationView(page);
|
||||
}
|
||||
else
|
||||
{
|
||||
var navigationPage = CurrentApplication.MainPage as CustomNavigationView;
|
||||
|
||||
{
|
||||
var navigationPage = Application.Current.MainPage as CustomNavigationView;
|
||||
if (navigationPage != null)
|
||||
{
|
||||
await navigationPage.PushAsync(page);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentApplication.MainPage = new CustomNavigationView(page);
|
||||
Application.Current.MainPage = new CustomNavigationView(page);
|
||||
}
|
||||
}
|
||||
|
||||
await (page.BindingContext as ViewModelBase).InitializeAsync(parameter);
|
||||
}
|
||||
|
||||
protected Type GetPageTypeForViewModel(Type viewModelType)
|
||||
{
|
||||
if (!_mappings.ContainsKey(viewModelType))
|
||||
{
|
||||
throw new KeyNotFoundException($"No map for ${viewModelType} was found on navigation mappings");
|
||||
}
|
||||
private Type GetPageTypeForViewModel(Type viewModelType)
|
||||
{
|
||||
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
|
||||
var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;
|
||||
var viewAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);
|
||||
var viewType = Type.GetType(viewAssemblyName);
|
||||
return viewType;
|
||||
}
|
||||
|
||||
return _mappings[viewModelType];
|
||||
}
|
||||
private Page CreatePage(Type viewModelType, object parameter)
|
||||
{
|
||||
Type pageType = GetPageTypeForViewModel(viewModelType);
|
||||
if (pageType == null)
|
||||
{
|
||||
throw new Exception($"Cannot locate page type for {viewModelType}");
|
||||
}
|
||||
|
||||
protected Page CreateAndBindPage(Type viewModelType, object parameter)
|
||||
{
|
||||
Type pageType = GetPageTypeForViewModel(viewModelType);
|
||||
|
||||
if (pageType == null)
|
||||
{
|
||||
throw new Exception($"Mapping type for {viewModelType} is not a page");
|
||||
}
|
||||
|
||||
Page page = Activator.CreateInstance(pageType) as Page;
|
||||
ViewModelBase viewModel = ViewModelLocator.Instance.Resolve(viewModelType) as ViewModelBase;
|
||||
page.BindingContext = viewModel;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
private void CreatePageViewModelMappings()
|
||||
{
|
||||
_mappings.Add(typeof(BasketViewModel), typeof(BasketView));
|
||||
_mappings.Add(typeof(CatalogViewModel), typeof(CatalogView));
|
||||
_mappings.Add(typeof(CheckoutViewModel), typeof(CheckoutView));
|
||||
_mappings.Add(typeof(LoginViewModel), typeof(LoginView));
|
||||
_mappings.Add(typeof(MainViewModel), typeof(MainView));
|
||||
_mappings.Add(typeof(OrderDetailViewModel), typeof(OrderDetailView));
|
||||
_mappings.Add(typeof(ProfileViewModel), typeof(ProfileView));
|
||||
_mappings.Add(typeof(SettingsViewModel), typeof(SettingsView));
|
||||
}
|
||||
Page page = Activator.CreateInstance(pageType) as Page;
|
||||
return page;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace eShopOnContainers.Core.Validations
|
||||
@ -8,13 +7,24 @@ namespace eShopOnContainers.Core.Validations
|
||||
public class ValidatableObject<T> : ExtendedBindableObject, IValidity
|
||||
{
|
||||
private readonly List<IValidationRule<T>> _validations;
|
||||
private readonly ObservableCollection<string> _errors;
|
||||
private List<string> _errors;
|
||||
private T _value;
|
||||
private bool _isValid;
|
||||
|
||||
public List<IValidationRule<T>> Validations => _validations;
|
||||
|
||||
public ObservableCollection<string> Errors => _errors;
|
||||
public List<string> Errors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _errors;
|
||||
}
|
||||
set
|
||||
{
|
||||
_errors = value;
|
||||
RaisePropertyChanged(() => Errors);
|
||||
}
|
||||
}
|
||||
|
||||
public T Value
|
||||
{
|
||||
@ -22,7 +32,6 @@ namespace eShopOnContainers.Core.Validations
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
@ -36,11 +45,9 @@ namespace eShopOnContainers.Core.Validations
|
||||
{
|
||||
return _isValid;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_isValid = value;
|
||||
_errors.Clear();
|
||||
RaisePropertyChanged(() => IsValid);
|
||||
}
|
||||
}
|
||||
@ -48,7 +55,7 @@ namespace eShopOnContainers.Core.Validations
|
||||
public ValidatableObject()
|
||||
{
|
||||
_isValid = true;
|
||||
_errors = new ObservableCollection<string>();
|
||||
_errors = new List<string>();
|
||||
_validations = new List<IValidationRule<T>>();
|
||||
}
|
||||
|
||||
@ -59,11 +66,7 @@ namespace eShopOnContainers.Core.Validations
|
||||
IEnumerable<string> errors = _validations.Where(v => !v.Check(Value))
|
||||
.Select(v => v.ValidationMessage);
|
||||
|
||||
foreach (var error in errors)
|
||||
{
|
||||
Errors.Add(error);
|
||||
}
|
||||
|
||||
Errors = errors.ToList();
|
||||
IsValid = !Errors.Any();
|
||||
|
||||
return this.IsValid;
|
||||
|
@ -3,7 +3,7 @@ using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.ViewModels.Base
|
||||
namespace eShopOnContainers.Core.ViewModels.Base
|
||||
{
|
||||
public abstract class ExtendedBindableObject : BindableObject
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace eShopOnContainers.Core.ViewModels.Base
|
||||
{
|
||||
public class MessengerKeys
|
||||
public class MessageKeys
|
||||
{
|
||||
// Add product to basket
|
||||
public const string AddProduct = "AddProduct";
|
@ -1,9 +1,8 @@
|
||||
using eShopOnContainers.Core;
|
||||
using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Services;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace eShopOnContainers.ViewModels.Base
|
||||
namespace eShopOnContainers.Core.ViewModels.Base
|
||||
{
|
||||
public abstract class ViewModelBase : ExtendedBindableObject
|
||||
{
|
||||
@ -28,8 +27,8 @@ namespace eShopOnContainers.ViewModels.Base
|
||||
|
||||
public ViewModelBase()
|
||||
{
|
||||
DialogService = ViewModelLocator.Instance.Resolve<IDialogService>();
|
||||
NavigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
|
||||
DialogService = ViewModelLocator.Resolve<IDialogService>();
|
||||
NavigationService = ViewModelLocator.Resolve<INavigationService>();
|
||||
GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
using Microsoft.Practices.Unity;
|
||||
using eShopOnContainers.Core.ViewModels;
|
||||
using eShopOnContainers.Services;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using eShopOnContainers.Core.Services.Catalog;
|
||||
using eShopOnContainers.Core.Services.OpenUrl;
|
||||
using eShopOnContainers.Core.Services.RequestProvider;
|
||||
@ -9,100 +10,101 @@ using eShopOnContainers.Core.Services.Basket;
|
||||
using eShopOnContainers.Core.Services.Identity;
|
||||
using eShopOnContainers.Core.Services.Order;
|
||||
using eShopOnContainers.Core.Services.User;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace eShopOnContainers.ViewModels.Base
|
||||
namespace eShopOnContainers.Core.ViewModels.Base
|
||||
{
|
||||
public class ViewModelLocator
|
||||
public static class ViewModelLocator
|
||||
{
|
||||
private bool _useMockService;
|
||||
private readonly IUnityContainer _unityContainer;
|
||||
private static readonly IUnityContainer _unityContainer = new UnityContainer();
|
||||
|
||||
private static readonly ViewModelLocator _instance = new ViewModelLocator();
|
||||
public static readonly BindableProperty AutoWireViewModelProperty =
|
||||
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
|
||||
|
||||
public static ViewModelLocator Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
public static bool GetAutoWireViewModel(BindableObject bindable)
|
||||
{
|
||||
return (bool)bindable.GetValue(ViewModelLocator.AutoWireViewModelProperty);
|
||||
}
|
||||
|
||||
public bool UseMockService
|
||||
{
|
||||
get { return _useMockService; }
|
||||
set { _useMockService = value; ; }
|
||||
}
|
||||
public static void SetAutoWireViewModel(BindableObject bindable, bool value)
|
||||
{
|
||||
bindable.SetValue(ViewModelLocator.AutoWireViewModelProperty, value);
|
||||
}
|
||||
|
||||
protected ViewModelLocator()
|
||||
{
|
||||
_unityContainer = new UnityContainer();
|
||||
public static bool UseMockService { get; set; }
|
||||
|
||||
// Services
|
||||
_unityContainer.RegisterType<IDialogService, DialogService>();
|
||||
RegisterSingleton<INavigationService, NavigationService>();
|
||||
_unityContainer.RegisterType<IOpenUrlService, OpenUrlService>();
|
||||
_unityContainer.RegisterType<IRequestProvider, RequestProvider>();
|
||||
_unityContainer.RegisterType<IIdentityService, IdentityService>();
|
||||
public static void Initialize()
|
||||
{
|
||||
// Services
|
||||
_unityContainer.RegisterType<IDialogService, DialogService>();
|
||||
_unityContainer.RegisterType<INavigationService, NavigationService>(new ContainerControlledLifetimeManager());
|
||||
_unityContainer.RegisterType<IOpenUrlService, OpenUrlService>();
|
||||
_unityContainer.RegisterType<IRequestProvider, RequestProvider>();
|
||||
_unityContainer.RegisterType<IIdentityService, IdentityService>();
|
||||
_unityContainer.RegisterType<ICatalogService, CatalogMockService>();
|
||||
_unityContainer.RegisterType<IBasketService, BasketMockService>();
|
||||
_unityContainer.RegisterType<IUserService, UserMockService>();
|
||||
|
||||
_unityContainer.RegisterType<ICatalogService, CatalogMockService>();
|
||||
_unityContainer.RegisterType<IBasketService, BasketMockService>();
|
||||
_unityContainer.RegisterType<IUserService, UserMockService>();
|
||||
// View models
|
||||
_unityContainer.RegisterType<BasketViewModel>();
|
||||
_unityContainer.RegisterType<CatalogViewModel>();
|
||||
_unityContainer.RegisterType<CheckoutViewModel>();
|
||||
_unityContainer.RegisterType<LoginViewModel>();
|
||||
_unityContainer.RegisterType<MainViewModel>();
|
||||
_unityContainer.RegisterType<OrderDetailViewModel>();
|
||||
_unityContainer.RegisterType<ProfileViewModel>();
|
||||
_unityContainer.RegisterType<SettingsViewModel>();
|
||||
}
|
||||
|
||||
// View models
|
||||
_unityContainer.RegisterType<BasketViewModel>();
|
||||
_unityContainer.RegisterType<CatalogViewModel>();
|
||||
_unityContainer.RegisterType<CheckoutViewModel>();
|
||||
_unityContainer.RegisterType<LoginViewModel>();
|
||||
_unityContainer.RegisterType<MainViewModel>();
|
||||
_unityContainer.RegisterType<OrderDetailViewModel>();
|
||||
_unityContainer.RegisterType<ProfileViewModel>();
|
||||
_unityContainer.RegisterType<SettingsViewModel>();
|
||||
}
|
||||
public static void UpdateDependencies(bool useMockServices)
|
||||
{
|
||||
// Change injected dependencies
|
||||
if (useMockServices)
|
||||
{
|
||||
_unityContainer.RegisterInstance<ICatalogService>(new CatalogMockService());
|
||||
_unityContainer.RegisterInstance<IBasketService>(new BasketMockService());
|
||||
_unityContainer.RegisterInstance<IOrderService>(new OrderMockService());
|
||||
_unityContainer.RegisterInstance<IUserService>(new UserMockService());
|
||||
|
||||
public void UpdateDependencies(bool useMockServices)
|
||||
{
|
||||
// Change injected dependencies
|
||||
if (useMockServices)
|
||||
{
|
||||
_unityContainer.RegisterInstance<ICatalogService>(new CatalogMockService());
|
||||
_unityContainer.RegisterInstance<IBasketService>(new BasketMockService());
|
||||
_unityContainer.RegisterInstance<IOrderService>(new OrderMockService());
|
||||
_unityContainer.RegisterInstance<IUserService>(new UserMockService());
|
||||
UseMockService = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestProvider = Resolve<IRequestProvider>();
|
||||
_unityContainer.RegisterInstance<ICatalogService>(new CatalogService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IBasketService>(new BasketService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IOrderService>(new OrderService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IUserService>(new UserService(requestProvider));
|
||||
|
||||
UseMockService = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestProvider = Resolve<IRequestProvider>();
|
||||
_unityContainer.RegisterInstance<ICatalogService>(new CatalogService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IBasketService>(new BasketService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IOrderService>(new OrderService(requestProvider));
|
||||
_unityContainer.RegisterInstance<IUserService>(new UserService(requestProvider));
|
||||
UseMockService = false;
|
||||
}
|
||||
}
|
||||
|
||||
UseMockService = false;
|
||||
}
|
||||
}
|
||||
|
||||
public T Resolve<T>()
|
||||
{
|
||||
return _unityContainer.Resolve<T>();
|
||||
}
|
||||
public static T Resolve<T>()
|
||||
{
|
||||
return _unityContainer.Resolve<T>();
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return _unityContainer.Resolve(type);
|
||||
}
|
||||
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var view = bindable as Element;
|
||||
if (view == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void Register<T>(T instance)
|
||||
{
|
||||
_unityContainer.RegisterInstance<T>(instance);
|
||||
}
|
||||
var viewType = view.GetType();
|
||||
var viewName = viewType.FullName.Replace(".Views.", ".ViewModels.");
|
||||
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
|
||||
var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}Model, {1}", viewName, viewAssemblyName);
|
||||
|
||||
public void Register<TInterface, T>() where T : TInterface
|
||||
{
|
||||
_unityContainer.RegisterType<TInterface, T>();
|
||||
}
|
||||
|
||||
public void RegisterSingleton<TInterface, T>() where T : TInterface
|
||||
{
|
||||
_unityContainer.RegisterType<TInterface, T>(new ContainerControlledLifetimeManager());
|
||||
}
|
||||
}
|
||||
var viewModelType = Type.GetType(viewModelName);
|
||||
if (viewModelType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var viewModel = _unityContainer.Resolve(viewModelType);
|
||||
view.BindingContext = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,8 +4,6 @@ using eShopOnContainers.Core.Models.Catalog;
|
||||
using eShopOnContainers.Core.Services.Basket;
|
||||
using eShopOnContainers.Core.Services.User;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -61,7 +59,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand AddCommand => new Command<BasketItem>(AddItem);
|
||||
public ICommand AddCommand => new Command<BasketItem>(async (item) => await AddItemAsync(item));
|
||||
|
||||
public ICommand CheckoutCommand => new Command(async () => await CheckoutAsync());
|
||||
|
||||
@ -78,26 +76,28 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
if (basket != null && basket.Items != null && basket.Items.Any())
|
||||
{
|
||||
BadgeCount = 0;
|
||||
BasketItems.Clear();
|
||||
|
||||
foreach (var basketItem in basket.Items)
|
||||
{
|
||||
BadgeCount += basketItem.Quantity;
|
||||
AddBasketItem(basketItem);
|
||||
await AddBasketItemAsync(basketItem);
|
||||
}
|
||||
}
|
||||
|
||||
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct);
|
||||
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct, (sender, arg) =>
|
||||
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct);
|
||||
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct, async (sender, arg) =>
|
||||
{
|
||||
BadgeCount++;
|
||||
|
||||
AddCatalogItem(arg);
|
||||
await AddCatalogItemAsync(arg);
|
||||
});
|
||||
|
||||
await base.InitializeAsync(navigationData);
|
||||
}
|
||||
|
||||
private void AddCatalogItem(CatalogItem item)
|
||||
private async Task AddCatalogItemAsync(CatalogItem item)
|
||||
{
|
||||
BasketItems.Add(new BasketItem
|
||||
{
|
||||
@ -108,26 +108,26 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
Quantity = 1
|
||||
});
|
||||
|
||||
ReCalculateTotal();
|
||||
await ReCalculateTotalAsync();
|
||||
}
|
||||
|
||||
private void AddItem(BasketItem item)
|
||||
private async Task AddItemAsync(BasketItem item)
|
||||
{
|
||||
BadgeCount++;
|
||||
|
||||
AddBasketItem(item);
|
||||
await AddBasketItemAsync(item);
|
||||
|
||||
RaisePropertyChanged(() => BasketItems);
|
||||
}
|
||||
|
||||
private void AddBasketItem(BasketItem item)
|
||||
private async Task AddBasketItemAsync(BasketItem item)
|
||||
{
|
||||
BasketItems.Add(item);
|
||||
|
||||
ReCalculateTotal();
|
||||
await ReCalculateTotalAsync();
|
||||
}
|
||||
|
||||
private async void ReCalculateTotal()
|
||||
private async Task ReCalculateTotalAsync()
|
||||
{
|
||||
Total = 0;
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
using System.Threading.Tasks;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Collections.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using eShopOnContainers.Core.Models.Catalog;
|
||||
using eShopOnContainers.Core.Services.Catalog;
|
||||
using System.Windows.Input;
|
||||
using System.Linq;
|
||||
using eShopOnContainers.Core.Services.Basket;
|
||||
using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Core.Services.User;
|
||||
|
||||
namespace eShopOnContainers.Core.ViewModels
|
||||
@ -20,19 +17,11 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
private CatalogBrand _brand;
|
||||
private ObservableCollection<CatalogType> _types;
|
||||
private CatalogType _type;
|
||||
|
||||
private IBasketService _basketService;
|
||||
private ICatalogService _productsService;
|
||||
private IUserService _userService;
|
||||
|
||||
public CatalogViewModel(
|
||||
IBasketService basketService,
|
||||
ICatalogService productsService,
|
||||
IUserService userService)
|
||||
public CatalogViewModel(ICatalogService productsService)
|
||||
{
|
||||
_basketService = basketService;
|
||||
_productsService = productsService;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
public ObservableCollection<CatalogItem> Products
|
||||
@ -91,9 +80,9 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
public ICommand AddCatalogItemCommand => new Command<CatalogItem>(AddCatalogItem);
|
||||
|
||||
public ICommand FilterCommand => new Command(Filter);
|
||||
public ICommand FilterCommand => new Command(async () => await FilterAsync());
|
||||
|
||||
public ICommand ClearFilterCommand => new Command(ClearFilter);
|
||||
public ICommand ClearFilterCommand => new Command(async () => await ClearFilterAsync());
|
||||
|
||||
public override async Task InitializeAsync(object navigationData)
|
||||
{
|
||||
@ -110,10 +99,10 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
private void AddCatalogItem(CatalogItem catalogItem)
|
||||
{
|
||||
// Add new item to Basket
|
||||
MessagingCenter.Send(this, MessengerKeys.AddProduct, catalogItem);
|
||||
MessagingCenter.Send(this, MessageKeys.AddProduct, catalogItem);
|
||||
}
|
||||
|
||||
private async void Filter()
|
||||
private async Task FilterAsync()
|
||||
{
|
||||
if (Brand == null && Type == null)
|
||||
{
|
||||
@ -123,13 +112,13 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
IsBusy = true;
|
||||
|
||||
// Filter catalog products
|
||||
MessagingCenter.Send(this, MessengerKeys.Filter);
|
||||
MessagingCenter.Send(this, MessageKeys.Filter);
|
||||
Products = await _productsService.FilterAsync(Brand.Id, Type.Id);
|
||||
|
||||
IsBusy = false;
|
||||
}
|
||||
|
||||
private async void ClearFilter()
|
||||
private async Task ClearFilterAsync()
|
||||
{
|
||||
IsBusy = true;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
using eShopOnContainers.Core.Models.Navigation;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
using System.Threading.Tasks;
|
||||
@ -90,7 +90,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
ZipCode = userInfo?.ZipCode,
|
||||
State = userInfo?.State,
|
||||
Country = userInfo?.Country,
|
||||
City = string.Empty
|
||||
City = userInfo?.Address
|
||||
};
|
||||
|
||||
// Create Payment Info
|
||||
@ -117,7 +117,8 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
ShippingState = _shippingAddress.State,
|
||||
ShippingCountry = _shippingAddress.Country,
|
||||
ShippingStreet = _shippingAddress.Street,
|
||||
ShippingCity = _shippingAddress.City,
|
||||
ShippingCity = _shippingAddress.City,
|
||||
ShippingZipCode = _shippingAddress.ZipCode,
|
||||
Total = CalculateTotal(CreateOrderItems(orderItems))
|
||||
};
|
||||
|
||||
@ -138,7 +139,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);
|
||||
|
||||
// Reset Basket badge
|
||||
var basketViewModel = ViewModelLocator.Instance.Resolve<BasketViewModel>();
|
||||
var basketViewModel = ViewModelLocator.Resolve<BasketViewModel>();
|
||||
basketViewModel.BadgeCount = 0;
|
||||
|
||||
// Navigate to Orders
|
||||
|
@ -2,9 +2,8 @@
|
||||
using eShopOnContainers.Core.Models.User;
|
||||
using eShopOnContainers.Core.Services.Identity;
|
||||
using eShopOnContainers.Core.Services.OpenUrl;
|
||||
using eShopOnContainers.Core.Services.User;
|
||||
using eShopOnContainers.Core.Validations;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using IdentityModel.Client;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@ -25,16 +24,13 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
private IOpenUrlService _openUrlService;
|
||||
private IIdentityService _identityService;
|
||||
private IUserService _userService;
|
||||
|
||||
public LoginViewModel(
|
||||
IOpenUrlService openUrlService,
|
||||
IIdentityService identityService,
|
||||
IUserService userService)
|
||||
IIdentityService identityService)
|
||||
{
|
||||
_openUrlService = openUrlService;
|
||||
_identityService = identityService;
|
||||
_userService = userService;
|
||||
|
||||
_userName = new ValidatableObject<string>();
|
||||
_password = new ValidatableObject<string>();
|
||||
@ -131,6 +127,10 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
public ICommand SettingsCommand => new Command(async () => await SettingsAsync());
|
||||
|
||||
public ICommand ValidateUserNameCommand => new Command(() => ValidateUserName());
|
||||
|
||||
public ICommand ValidatePasswordCommand => new Command(() => ValidatePassword());
|
||||
|
||||
public override Task InitializeAsync(object navigationData)
|
||||
{
|
||||
if(navigationData is LogoutParameter)
|
||||
@ -221,14 +221,16 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
private async Task NavigateAsync(string url)
|
||||
{
|
||||
if (url.Equals(GlobalSetting.Instance.LogoutCallback))
|
||||
var unescapedUrl = System.Net.WebUtility.UrlDecode(url);
|
||||
|
||||
if (unescapedUrl.Equals(GlobalSetting.Instance.LogoutCallback))
|
||||
{
|
||||
Settings.AuthAccessToken = string.Empty;
|
||||
Settings.AuthIdToken = string.Empty;
|
||||
IsLogin = false;
|
||||
LoginUrl = _identityService.CreateAuthorizeRequest();
|
||||
}
|
||||
else if (url.Contains(GlobalSetting.Instance.IdentityCallback))
|
||||
else if (unescapedUrl.Contains(GlobalSetting.Instance.IdentityCallback))
|
||||
{
|
||||
var authResponse = new AuthorizeResponse(url);
|
||||
|
||||
@ -253,16 +255,26 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
private bool Validate()
|
||||
{
|
||||
bool isValidUser = _userName.Validate();
|
||||
bool isValidPassword = _password.Validate();
|
||||
bool isValidUser = ValidateUserName();
|
||||
bool isValidPassword = ValidatePassword();
|
||||
|
||||
return isValidUser && isValidPassword;
|
||||
}
|
||||
|
||||
private bool ValidateUserName()
|
||||
{
|
||||
return _userName.Validate();
|
||||
}
|
||||
|
||||
private bool ValidatePassword()
|
||||
{
|
||||
return _password.Validate();
|
||||
}
|
||||
|
||||
private void AddValidations()
|
||||
{
|
||||
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Username should not be empty" });
|
||||
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Password should not be empty" });
|
||||
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A username is required." });
|
||||
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A password is required." });
|
||||
}
|
||||
|
||||
public void InvalidateMock()
|
||||
|
@ -1,8 +1,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using eShopOnContainers.Core.Models.Navigation;
|
||||
using Xamarin.Forms;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace eShopOnContainers.Core.ViewModels
|
||||
@ -19,7 +18,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
{
|
||||
// Change selected application tab
|
||||
var tabIndex = ((TabParameter)navigationData).TabIndex;
|
||||
MessagingCenter.Send(this, MessengerKeys.ChangeTab, tabIndex);
|
||||
MessagingCenter.Send(this, MessageKeys.ChangeTab, tabIndex);
|
||||
}
|
||||
|
||||
return base.InitializeAsync(navigationData);
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using eShopOnContainers.Core.Models.Orders;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using eShopOnContainers.Core.Services.Catalog;
|
||||
using eShopOnContainers.Core.Services.Basket;
|
||||
using eShopOnContainers.Core.Services.Order;
|
||||
@ -13,17 +13,10 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
{
|
||||
private Order _order;
|
||||
|
||||
private IBasketService _orderService;
|
||||
private ICatalogService _catalogService;
|
||||
private IOrderService _ordersService;
|
||||
|
||||
public OrderDetailViewModel(
|
||||
IBasketService orderService,
|
||||
ICatalogService catalogService,
|
||||
IOrderService ordersService)
|
||||
public OrderDetailViewModel(IOrderService ordersService)
|
||||
{
|
||||
_orderService = orderService;
|
||||
_catalogService = catalogService;
|
||||
_ordersService = ordersService;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ using eShopOnContainers.Core.Helpers;
|
||||
using eShopOnContainers.Core.Models.Orders;
|
||||
using eShopOnContainers.Core.Models.User;
|
||||
using eShopOnContainers.Core.Services.Order;
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using eShopOnContainers.ViewModels.Base;
|
||||
using eShopOnContainers.Core.ViewModels.Base;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
using System.Threading.Tasks;
|
||||
@ -71,7 +71,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
|
||||
private void MockServices()
|
||||
{
|
||||
ViewModelLocator.Instance.UpdateDependencies(!UseAzureServices);
|
||||
ViewModelLocator.UpdateDependencies(!UseAzureServices);
|
||||
UpdateInfo();
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="eShopOnContainers.Core.Views.BasketView"
|
||||
x:Class="eShopOnContainers.Core.Views.BasketView"
|
||||
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
|
||||
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
|
||||
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
|
||||
Title="Cart">
|
||||
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
|
||||
Title="Cart">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user