├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── dotnet-format-daily.yml │ ├── gh-pages.yml │ ├── label-sponsors.yml │ └── requirements.txt ├── .gitignore ├── .gitmodules ├── CodeCoverage.runsettings ├── Directory.Build.props ├── Directory.Build.targets ├── LICENSE ├── Prism.Container.Extensions.sln ├── README.md ├── azure-pipelines.yml ├── build ├── Process-Release.ps1 ├── Sign-Packages.ps1 └── filelist.txt ├── docs ├── .nojekyll ├── CNAME ├── assets │ ├── favicon.ico │ └── prism-logo.png ├── containers │ ├── dryioc.md │ ├── index.md │ ├── microsoft-extensions-dependencyinjection.md │ └── unity.md ├── forms │ ├── executionawarecommand.md │ ├── fluent-navigation.md │ ├── index.md │ ├── navigationerrors.md │ └── pagebehaviorfactory.md ├── index.md ├── registerdelegates.md ├── registermany.md ├── registerservices.md ├── scoping.md └── shiny │ ├── index.md │ ├── modularity.md │ ├── navigation.md │ └── startup.md ├── global.json ├── mkdocs.yml ├── plugin.snk ├── prism-logo.png ├── sample ├── .editorconfig ├── PrismSample.Android │ ├── Assets │ │ └── AboutAssets.txt │ ├── MainActivity.cs │ ├── MainApplication.cs │ ├── PrismSample.Android.csproj │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── drawable-hdpi │ │ │ └── icon.png │ │ ├── drawable-mdpi │ │ │ └── icon.png │ │ ├── drawable-xhdpi │ │ │ └── icon.png │ │ ├── drawable-xxhdpi │ │ │ └── icon.png │ │ ├── drawable-xxxhdpi │ │ │ └── icon.png │ │ ├── drawable │ │ │ └── splash_screen.xml │ │ ├── layout │ │ │ ├── Tabbar.xml │ │ │ └── Toolbar.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── icon.xml │ │ │ └── icon_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ └── SplashActivity.cs ├── PrismSample.UWP │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ │ ├── LargeTile.scale-100.png │ │ ├── LargeTile.scale-200.png │ │ ├── LargeTile.scale-400.png │ │ ├── SmallTile.scale-100.png │ │ ├── SmallTile.scale-200.png │ │ ├── SmallTile.scale-400.png │ │ ├── SplashScreen.scale-100.png │ │ ├── SplashScreen.scale-200.png │ │ ├── SplashScreen.scale-400.png │ │ ├── Square150x150Logo.scale-100.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square150x150Logo.scale-400.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ │ ├── Square44x44Logo.scale-100.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.scale-400.png │ │ ├── Square44x44Logo.targetsize-16.png │ │ ├── Square44x44Logo.targetsize-256.png │ │ ├── Square44x44Logo.targetsize-48.png │ │ ├── StoreLogo.backup.png │ │ ├── StoreLogo.scale-100.png │ │ ├── StoreLogo.scale-200.png │ │ ├── StoreLogo.scale-400.png │ │ ├── Wide310x150Logo.scale-100.png │ │ ├── Wide310x150Logo.scale-200.png │ │ └── Wide310x150Logo.scale-400.png │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Package.appxmanifest │ ├── PrismSample.UWP.csproj │ └── Properties │ │ ├── AssemblyInfo.cs │ │ └── Default.rd.xml ├── PrismSample.iOS │ ├── AppDelegate.cs │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon1024.png │ │ │ ├── Icon120.png │ │ │ ├── Icon152.png │ │ │ ├── Icon167.png │ │ │ ├── Icon180.png │ │ │ ├── Icon20.png │ │ │ ├── Icon29.png │ │ │ ├── Icon40.png │ │ │ ├── Icon58.png │ │ │ ├── Icon60.png │ │ │ ├── Icon76.png │ │ │ ├── Icon80.png │ │ │ └── Icon87.png │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── PrismSample.iOS.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Resources │ │ ├── Default-568h@2x.png │ │ ├── Default-Portrait.png │ │ ├── Default-Portrait@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ └── LaunchScreen.storyboard └── PrismSample │ ├── App.xaml │ ├── App.xaml.cs │ ├── PrismSample.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── Shiny │ └── Startup.cs │ ├── ViewModels │ └── MainPageViewModel.cs │ └── Views │ ├── MainPage.xaml │ └── MainPage.xaml.cs ├── src ├── Prism.Container.Extensions │ ├── IServiceCollectionAware.cs │ ├── IServiceCollectionExtensions.cs │ ├── IServiceProviderExtensions.cs │ ├── Internals │ │ ├── ContainerExtensionAttribute.cs │ │ └── ContainerLocationHelper.cs │ ├── Prism.Container.Extensions.csproj │ ├── PrismServiceProvider.cs │ ├── PrismServiceScope.cs │ └── RegisterOnceExtensions.cs ├── Prism.DryIoc.Extensions │ ├── ContainerExtension.cs │ ├── Extensions │ │ └── PrismIocExtensions.cs │ ├── Internals │ │ └── PrismContainerExtensionAttribute.cs │ ├── Prism.DryIoc.Extensions.csproj │ ├── PrismContainerExtension.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ReadMe.txt │ └── build │ │ ├── PreserveContainerExtension.cs │ │ └── Prism.DryIoc.Extensions.targets ├── Prism.Forms.Extended │ ├── Behaviors │ │ ├── DefaultPageBehaviorFactoryOptions.cs │ │ ├── ExtendedPageBehaviorFactory.cs │ │ ├── IPageBehaviorFactoryOptions.cs │ │ └── TabbedPageChildTitleBehavior.cs │ ├── Commands │ │ ├── ExecutionAwareCommand.cs │ │ ├── ExecutionAwareCommandBase.cs │ │ ├── ExecutionAwareCommand{T}.cs │ │ └── UnhandledCommandException.cs │ ├── Common │ │ └── ErrorHandlerRegistry.cs │ ├── Events │ │ └── NavigationErrorEvent.cs │ ├── Ioc │ │ └── RequiredTypesExtensions.cs │ ├── Navigation │ │ ├── ErrorReportingNavigationService.cs │ │ ├── NavigationBuilder.cs │ │ ├── NavigationBuilderExtensions.cs │ │ └── NavigationInstruction.cs │ ├── Platform │ │ └── PlatformSpecifics.cs │ ├── Prism.Forms.Extended.csproj │ ├── PrismApplication.android.cs │ ├── PrismApplication.cs │ ├── PrismApplication.iosmac.cs │ ├── PrismApplication.netstandard.cs │ ├── Styles │ │ └── DefaultResources.cs │ └── ViewModels │ │ └── DefaultViewModel.cs ├── Prism.Microsoft.DependencyInjection.Extensions │ ├── ConcreteAwareOverrideProvider.cs │ ├── ConcreteAwareServiceProvider.cs │ ├── ConcreteAwareServiceScope.cs │ ├── Internals │ │ └── PrismContainerExtensionAttribute.cs │ ├── MicrsoftDependencyInjectionExtensions.cs │ ├── NamedServiceRegistry.cs │ ├── Prism.Microsoft.DependencyInjection.Extensions.csproj │ ├── PrismContainerExtension.cs │ ├── ReadMe.txt │ └── build │ │ ├── PreserveContainerExtension.cs │ │ └── Prism.Microsoft.DependencyInjection.Extensions.targets ├── Prism.Unity.Extensions │ ├── ContainerExtension.cs │ ├── Internals │ │ └── PrismContainerExtensionAttribute.cs │ ├── Prism.Unity.Extensions.csproj │ ├── PrismContainerExtension.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ReadMe.txt │ └── build │ │ ├── PreserveContainerExtension.cs │ │ └── Prism.Unity.Extensions.targets └── Shiny.Prism │ ├── Modularity │ ├── IModuleCatalogExtensions.cs │ ├── IShinyModule.cs │ ├── IShinyPrismModuleInitializer.cs │ ├── IStartupModule.cs │ ├── ShinyModule.cs │ ├── ShinyPrismModuleInitializer.cs │ └── StartupModule.cs │ ├── Navigation │ ├── INavigationServiceDelegate.cs │ ├── NavigationExtensions.cs │ └── NavigationServiceDelegate.cs │ ├── PrismStartup.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── ReadMe.txt │ └── Shiny.Prism.csproj ├── tests ├── Prism.Container.Extensions.Mocks │ ├── Mocks │ │ ├── Bar.cs │ │ ├── Foo.cs │ │ ├── FooBarImpl.cs │ │ ├── IBar.cs │ │ └── IFoo.cs │ └── Prism.Container.Extensions.Mocks.csproj ├── Prism.Container.Extensions.Shared.Tests │ ├── Mocks │ │ ├── GenericService.cs │ │ └── MockDbContext.cs │ ├── Prism.Container.Extensions.Shared.Tests.projitems │ ├── Prism.Container.Extensions.Shared.Tests.shproj │ └── Tests │ │ ├── CommonAspNetServiceTests.cs │ │ └── SharedTestCollection.cs ├── Prism.DryIoc.Extensions.Tests │ ├── ContainerTests.cs │ ├── MicrosoftExtensionsTests.cs │ └── Prism.DryIoc.Extensions.Tests.csproj ├── Prism.DryIoc.Forms.Extended.Tests │ └── Prism.DryIoc.Forms.Extended.Tests.csproj ├── Prism.Forms.Extended.Mocks │ ├── Mocks │ │ ├── AppMock.xaml │ │ ├── AppMock.xaml.cs │ │ ├── Navigation │ │ │ └── MockNavigationService.cs │ │ ├── ViewModels │ │ │ ├── ViewAViewModel.cs │ │ │ ├── ViewBViewModel.cs │ │ │ ├── ViewCViewModel.cs │ │ │ └── ViewDViewModel.cs │ │ └── Views │ │ │ ├── ViewA.cs │ │ │ ├── ViewB.cs │ │ │ ├── ViewC.cs │ │ │ ├── ViewD.xaml │ │ │ └── ViewD.xaml.cs │ ├── Prism.Forms.Extended.Mocks.projitems │ ├── Prism.Forms.Extended.Mocks.shproj │ └── Tests │ │ ├── ExecutionAwareCommandTests.cs │ │ ├── ExtendedPageBehaviorFactoryTests.cs │ │ ├── FluentNavigationTests.cs │ │ └── PrismApplicationTests.cs ├── Prism.Microsoft.DependencyInjection.Extensions.Forms.Tests │ └── Prism.Microsoft.DependencyInjection.Forms.Extended.Tests.csproj ├── Prism.Microsoft.DependencyInjection.Extensions.Tests │ ├── ContainerTests.cs │ ├── MicrosoftExtensionsTests.cs │ └── Prism.Microsoft.DependencyInjection.Extensions.Tests.csproj ├── Prism.Unity.Extensions.Tests │ ├── ContainerTests.cs │ ├── MicrosoftExtensionsTests.cs │ └── Prism.Unity.Extensions.Tests.csproj ├── Prism.Unity.Forms.Extended.Tests │ └── Prism.Unity.Forms.Extended.Tests.csproj └── Shiny.Prism.Tests │ ├── Mocks │ ├── Delegates │ │ ├── MockBeaconDelegate.cs │ │ ├── MockBleAdapterDelegate.cs │ │ ├── MockGeofenceDelegate.cs │ │ └── MockGpsDelegate.cs │ ├── MockStartup.cs │ ├── Modularity │ │ ├── MockModuleStartup.cs │ │ ├── MockShinyPrismModule.cs │ │ └── Services │ │ │ ├── IMockModuleServiceA.cs │ │ │ ├── IMockModuleServiceB.cs │ │ │ ├── MockModuleServiceA.cs │ │ │ └── MockModuleServiceB.cs │ └── ShinyPrismTestHost.cs │ ├── Shiny.Prism.Tests.csproj │ └── Tests │ ├── ModularityTests.cs │ ├── PrismStartupTests.cs │ ├── SharedTestCollection.cs │ └── ShinyTests.cs ├── theme └── partials │ └── footer.html ├── version.json └── xunit.runner.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text eol=lf 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | # 44 | ## These files are binary and should be left untouched 45 | # 46 | 47 | # (binary is a macro for -text -diff) 48 | *.png binary 49 | *.jpg binary 50 | *.jpeg binary 51 | *.gif binary 52 | *.ico binary 53 | *.mov binary 54 | *.mp4 binary 55 | *.mp3 binary 56 | *.flv binary 57 | *.fla binary 58 | *.swf binary 59 | *.gz binary 60 | *.zip binary 61 | *.7z binary 62 | *.ttf binary 63 | *.eot binary 64 | *.woff binary 65 | *.pyc binary 66 | *.pdf binary 67 | *.otf binary 68 | *.md text 69 | 70 | ############################################################################### 71 | # diff behavior for common document formats 72 | # 73 | # Convert binary document formats to text before diffing them. This feature 74 | # is only available from the command line. Turn it on by uncommenting the 75 | # entries below. 76 | ############################################################################### 77 | #*.doc diff=astextplain 78 | #*.DOC diff=astextplain 79 | #*.docx diff=astextplain 80 | #*.DOCX diff=astextplain 81 | #*.dot diff=astextplain 82 | #*.DOT diff=astextplain 83 | #*.pdf diff=astextplain 84 | #*.PDF diff=astextplain 85 | #*.rtf diff=astextplain 86 | #*.RTF diff=astextplain 87 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: dansiegel 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 3 9 | ignore: 10 | - dependency-name: DryIoc.dll 11 | versions: 12 | - 4.7.4 13 | - 4.7.5 14 | - dependency-name: Microsoft.EntityFrameworkCore.InMemory 15 | versions: 16 | - 5.0.4 17 | - dependency-name: Moq 18 | versions: 19 | - 4.16.0 20 | - dependency-name: Microsoft.NET.Test.Sdk 21 | versions: 22 | - 16.8.3 23 | - dependency-name: Microsoft.NETCore.UniversalWindowsPlatform 24 | versions: 25 | - 6.2.11 26 | -------------------------------------------------------------------------------- /.github/workflows/dotnet-format-daily.yml: -------------------------------------------------------------------------------- 1 | name: Daily code format check 2 | on: 3 | schedule: 4 | - cron: 0 0 * * * # Every day at midnight (UTC) 5 | jobs: 6 | dotnet-format: 7 | runs-on: windows-latest 8 | steps: 9 | - name: Install dotnet-format 10 | run: dotnet tool install -g dotnet-format 11 | 12 | - name: Checkout repo 13 | uses: actions/checkout@v2 14 | with: 15 | ref: ${{ github.head_ref }} 16 | 17 | - name: Run dotnet format 18 | id: format 19 | uses: jfversluis/dotnet-format@v1.0.5 20 | with: 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | action: "fix" 23 | #only-changed-files: true # only works for PRs 24 | workspace: "Prism.Container.Extensions.sln" 25 | 26 | - name: Commit files 27 | if: steps.format.outputs.has-changes == 'true' 28 | run: | 29 | git config --local user.name "github-actions[bot]" 30 | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" 31 | git commit -a -m 'Automated dotnet-format update' 32 | 33 | - name: Create Pull Request 34 | uses: peter-evans/create-pull-request@v3 35 | with: 36 | title: '[housekeeping] Automated PR to fix formatting errors' 37 | body: | 38 | Automated PR to fix formatting errors 39 | committer: GitHub 40 | author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 41 | labels: housekeeping 42 | assignees: dansiegel 43 | reviewers: dansiegel 44 | branch: housekeeping/fix-codeformatting 45 | 46 | # Pushing won't work to forked repos 47 | # - name: Commit files 48 | # if: steps.format.outputs.has-changes == 'true' 49 | # run: | 50 | # git config --local user.name "github-actions[bot]" 51 | # git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" 52 | # git commit -a -m 'Automated dotnet-format update 53 | # Co-authored-by: ${{ github.event.pull_request.user.login }} <${{ github.event.pull_request.user.id }}+${{ github.event.pull_request.user.login }}@users.noreply.github.com>' 54 | 55 | # - name: Push changes 56 | # if: steps.format.outputs.has-changes == 'true' 57 | # uses: ad-m/github-push-action@v0.6.0 58 | # with: 59 | # github_token: ${{ secrets.GITHUB_TOKEN }} 60 | # branch: ${{ github.event.pull_request.head.ref }} -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build-deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@master 13 | 14 | - name: Setup Python 15 | uses: actions/setup-python@v1 16 | with: 17 | python-version: '3.6' 18 | architecture: 'x64' 19 | 20 | - name: Cache dependencies 21 | uses: actions/cache@v1 22 | with: 23 | path: ~/.cache/pip 24 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 25 | restore-keys: | 26 | ${{ runner.os }}-pip- 27 | 28 | - name: Install dependencies 29 | run: | 30 | python3 -m pip install --upgrade pip 31 | python3 -m pip install -r ./.github/workflows/requirements.txt 32 | 33 | - run: mkdocs build 34 | 35 | - name: Deploy 36 | uses: peaceiris/actions-gh-pages@v2.5.0 37 | env: 38 | ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} 39 | PUBLISH_BRANCH: gh-pages 40 | PUBLISH_DIR: ./site 41 | with: 42 | emptyCommits: false -------------------------------------------------------------------------------- /.github/workflows/label-sponsors.yml: -------------------------------------------------------------------------------- 1 | name: Label sponsors 2 | on: 3 | pull_request: 4 | types: [opened] 5 | issues: 6 | types: [opened] 7 | jobs: 8 | build: 9 | name: Add Sponsor Labels 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Add Sponsor Labels 13 | id: sponsor-labels 14 | uses: brianlagunas/sponsor-action@v1.0 15 | with: 16 | github_token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs>=1.0.4 2 | mkdocs-material>=4.5.0 -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/Prism"] 2 | path = external/Prism 3 | url = https://github.com/PrismLibrary/Prism.git 4 | -------------------------------------------------------------------------------- /CodeCoverage.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | .*Prism.*\.dll$ 22 | 23 | 24 | .*Tests.* 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(AssemblyName) ($(TargetFramework)) 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2019 Dan Siegel 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /build/Process-Release.ps1: -------------------------------------------------------------------------------- 1 | try { 2 | $artifactDirectory = $env:searchDirectory 3 | 4 | Write-Host "Currect working directory: $artifactDirectory" 5 | 6 | $nupkg = Get-ChildItem -Path $artifactDirectory -Filter *.nupkg -Recurse | Select-Object -First 1 7 | 8 | if($null -eq $nupkg) 9 | { 10 | Throw "No NuGet Package could be found in the current directory" 11 | } 12 | 13 | Write-Host "Package Name: $($nupkg.Name)" 14 | $nupkg.Name -match '^(.*?)\.((?:\.?[0-9]+){3,}(?:[-a-z]+)?)\.nupkg$' 15 | 16 | $VersionName = $Matches[2] 17 | $IsPreview = $VersionName -match '-pre$' 18 | $ReleaseDisplayName = $VersionName 19 | 20 | if($null -eq $env:IS_PREVIEW) 21 | { 22 | Write-Output ("##vso[task.setvariable variable=IS_PREVIEW;]$IsPreview") 23 | } 24 | 25 | if($true -eq $IsPreview) 26 | { 27 | $ReleaseDisplayName = "$VersionName - Preview" 28 | } 29 | 30 | Write-Host "Version Name" $VersionName 31 | Write-Host "Release Display Name: $ReleaseDisplayName" 32 | 33 | Write-Output ("##vso[task.setvariable variable=VersionName;]$VersionName") 34 | Write-Output ("##vso[task.setvariable variable=ReleaseDisplayName;]$ReleaseDisplayName") 35 | } 36 | catch { 37 | Write-Error $_ 38 | exit 1 39 | } 40 | -------------------------------------------------------------------------------- /build/Sign-Packages.ps1: -------------------------------------------------------------------------------- 1 | $currentDirectory = split-path $MyInvocation.MyCommand.Definition 2 | 3 | # See if we have the ClientSecret available 4 | if([string]::IsNullOrEmpty($env:SignClientSecret)){ 5 | Write-Host "Client Secret not found, not signing packages" 6 | return; 7 | } 8 | 9 | dotnet tool install --tool-path . SignClient 10 | 11 | # Setup Variables we need to pass into the sign client tool 12 | 13 | $appSettings = "$currentDirectory\appsettings.json" 14 | $fileList = "$currentDirectory\filelist.txt" 15 | 16 | if (!(Test-Path $fileList)) 17 | { 18 | New-Item -path $currentDirectory -name filelist.txt -type "file" -value "**" 19 | } 20 | 21 | # Sanitize GitHub Repository Names 22 | $repoName = $env:BUILD_REPOSITORY_NAME -replace ".*/","" 23 | 24 | $azureAd = @{ 25 | SignClient = @{ 26 | AzureAd = @{ 27 | AADInstance = $env:SignClientAADInstance 28 | ClientId = $env:SignClientClientId 29 | TenantId = $env:SignClientTenantId 30 | } 31 | Service = @{ 32 | Url = $env:SignServiceUrl 33 | ResourceId = $env:SignServiceResourceId 34 | } 35 | } 36 | } 37 | 38 | $azureAd | ConvertTo-Json -Compress | Out-File $appSettings 39 | 40 | $nupkgs = Get-ChildItem $env:BUILD_ARTIFACTSTAGINGDIRECTORY\*.nupkg -recurse | Select-Object -ExpandProperty FullName 41 | 42 | foreach ($nupkg in $nupkgs){ 43 | Write-Host "Submitting $nupkg for signing" 44 | 45 | .\SignClient 'sign' -c $appSettings -i $nupkg -f $fileList -r $env:SignClientUser -s $env:SignClientSecret -n $repoName -d $repoName -u $env:BUILD_REPOSITORY_URI 46 | 47 | Write-Host "Finished signing $nupkg" 48 | } 49 | 50 | Write-Host "Sign-package complete" -------------------------------------------------------------------------------- /build/filelist.txt: -------------------------------------------------------------------------------- 1 | **/Prism.* -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/docs/.nojekyll -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | prismplugins.com -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/docs/assets/favicon.ico -------------------------------------------------------------------------------- /docs/assets/prism-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/docs/assets/prism-logo.png -------------------------------------------------------------------------------- /docs/containers/dryioc.md: -------------------------------------------------------------------------------- 1 | DryIoc is a fantastic container to use. It is extremely fast and performant and is the container that Dan recommends the most. 2 | 3 | ## Customizing the underlying container 4 | 5 | There are times that you may want to customize some behavior of the container. For these times you may want to access one of the overload Create methods available. 6 | 7 | !!! note "Note" 8 | This is for ADVANCED USERS ONLY!!! If you do not know what you're doing with the D.I. container do not use these methods! 9 | 10 | ```c# 11 | var rules = Rules.Default 12 | .WithAutoConcreteTypeResolution() 13 | .With(Made.Of(FactoryMethod.ConstructorWithResolvableArguments)) 14 | .WithoutThrowOnRegisteringDisposableTransient() 15 | .WithFuncAndLazyWithoutRegistration() 16 | .WithDefaultIfAlreadyRegistered(IfAlreadyRegistered.Replace); 17 | 18 | // Option 1 19 | PrismContainerExtension.Create(rules); 20 | 21 | // Option 2 22 | var container = new Container(rules); 23 | PrismContainerExtension.Create(container); 24 | ``` -------------------------------------------------------------------------------- /docs/containers/index.md: -------------------------------------------------------------------------------- 1 | The Prism.Container.Extensions project currently has support for 3 third party Dependency Injection Containers: 2 | 3 | - DryIoc 4 | - Microsoft.Extensions.DependencyInjection 5 | - Unity Container - (not to be confused with Unity Game Development...) 6 | 7 | ## Using the Containers 8 | 9 | All of the implementations follow some common practices for accessing the containers. 10 | 11 | !!! important "Important" 12 | There is absolutely ZERO that ties these container implementations to any platform. You can safely use them for WPF, Xamarin.Forms, or other platforms not officially supported by Prism. All examples shown here will be referencing the use for Xamarin applications. 13 | 14 | To access the container at any point you can access the current instance of the container from the `Current` property. Note that if no instance has been created yet, it will automatically initialize the container with our default configuration for the container. 15 | 16 | ```c# 17 | var container = PrismContainerExtension.Current; 18 | 19 | // Creates a new instance with the default configuration 20 | var container = PrismContainerExtension.Create(); 21 | ``` 22 | 23 | !!! warning "Warning" 24 | Create should only ever be called a single time. For this reason if an instance has already been created, subsquent calls to Create will result in a `NotSupportedException` being thrown. 25 | 26 | ## Modifying PrismApplication 27 | 28 | When using the extended container extension you simply need to add the following to your PrismApplication to ensure that it uses the same instance that may have been created prior to the initialization of PrismApplication. 29 | 30 | ```c# 31 | protected override IContainerExtension CreateContainerExtension() => PrismContainerExtension.Current; 32 | ``` 33 | 34 | **NOTE:** This section *ONLY* applies to applications that are based on the Official packages from Prism. If you're using an Extended PrismApplication from this repo you should not modify the PrismApplication. 35 | -------------------------------------------------------------------------------- /docs/containers/microsoft-extensions-dependencyinjection.md: -------------------------------------------------------------------------------- 1 | # Microsoft.Extensions.DependencyInjection 2 | 3 | !!! warning "Warning!!!" 4 | Support for this container is proof of concept. This may still have a number of bugs. It is not advised to use this for production code at this time. 5 | 6 | For a number of developers, the Service Provider in Microsoft.Extensions.DependencyInjection is a great lightweight D.I. container. Traditionally this has never been seriously considered for Prism support since Prism has a hard requirement on named services in order to resolve your Views. Prism also has a bit of a requirement that it be able to resolve a service that was never registered. 7 | 8 | ## What makes this different? 9 | 10 | The requirement for named services never went away, nor did the requirement that we can resolve types like your ViewModels which are never directly registered. This package provides some additions though that allow us to track mapping between keys and types as well as to resolve concrete types even if they haven't been registered. With these two enhancements built on top of Microsoft's DI Extensions we are able to support Prism with the container. 11 | 12 | ## Using the Container 13 | 14 | This container is most likely to be used any time that you're using Shiny, but this can be used completely independently from Shiny or even Prism. 15 | 16 | ## Customizing the underlying container 17 | 18 | There are times that you may want to customize some behavior of the container. For these times you may want to access one of the overload Create methods available. 19 | 20 | !!! note "Note" 21 | This is for ADVANCED USERS ONLY!!! If you do not know what you're doing with the D.I. container do not use these methods! 22 | 23 | ```c# 24 | public void RegisterServices(IServiceCollection services) 25 | { 26 | // DO NOT DO THIS with Shiny.Prism!!! 27 | PrismContainerExtensions.Create(services); 28 | } 29 | ``` -------------------------------------------------------------------------------- /docs/containers/unity.md: -------------------------------------------------------------------------------- 1 | ## Customizing the underlying container 2 | 3 | There are times that you may want to customize some behavior of the container. For these times you may want to access one of the overload Create methods available. 4 | 5 | !!! note "Note" 6 | This is for ADVANCED USERS ONLY!!! If you do not know what you're doing with the D.I. container do not use these methods! 7 | 8 | ```c# 9 | var container = new UnityContainer(); 10 | PrismContainerExtension.Create(container); 11 | ``` -------------------------------------------------------------------------------- /docs/forms/executionawarecommand.md: -------------------------------------------------------------------------------- 1 | Have you ever looked at ReactiveCommand and wished that the DelegateCommand could be more like that, while also wishing the ReactiveCommand could be more like the DelegateCommand. This was the reason that yet another command was introduced in the Prism.Forms.Extended package. The ExecutionAwareCommand solves a few problems. 2 | 3 | 1. Fluent API 4 | 1. Support for Async Delegates 5 | 1. Support for ObservesProperty 6 | 1. Support for ObservesCanExecute 7 | 1. Support for adding Exception Handlers directly on the Command 8 | 1. Support for adding a IsExecuting Changed delegate 9 | 1. Support for opting in or out of InvalidCastExceptions 10 | 11 | ## Using the ExecutionAwareCommand 12 | 13 | ```c# 14 | public class ViewAViewModel : BindableBase 15 | { 16 | public ViewAViewModel() 17 | { 18 | FooCommand = ExecutionAwareCommand.FromAction(DoFoo) 19 | .OnIsExecutingChanged(b => IsBusy = b) 20 | .Catch(e => { 21 | // equivalent to catch(Exception e) 22 | }) 23 | .Catch(e => { 24 | // e is strongly typed as NullReferenceException 25 | }); 26 | } 27 | 28 | private bool _isBusy; 29 | public bool IsBusy 30 | { 31 | get => _isBusy; 32 | set => SetProperty(ref _isBusy, value); 33 | } 34 | 35 | public ICommand FooCommand { get; } 36 | 37 | private void DoFoo() 38 | { 39 | // Do Foo 40 | } 41 | } 42 | ``` 43 | 44 | !!! note "Note" 45 | Both `ExecutionAwareCommand` and `ExecutionAwareCommand` only support creation from the factory methods: 46 | 47 | - FromAction 48 | - FromTask -------------------------------------------------------------------------------- /docs/forms/fluent-navigation.md: -------------------------------------------------------------------------------- 1 | The use of fluent API's and declartive syntax is gaining popularity. There is a lot to be said for this as it becomes very clear about what we might expect. 2 | 3 | ## Using the Fluent API 4 | 5 | ```c# 6 | navService.Navigate("ViewA") 7 | .WithParameter("message", "Hello World") 8 | .Catch(e => 9 | { 10 | // Equivalent to catch(Exception e) 11 | }) 12 | .Catch(e => 13 | { 14 | // Equivalent to catch(ArgumentNullException e) 15 | }) 16 | .ExecuteAsync(); 17 | ``` 18 | 19 | !!! note "Note" 20 | When using the Fluent API, ExecuteAsync returns a `Task` and not a `Task`. It is important that if you want to do something with an exception returned by the INavigationResult in the underlying API, you must provide a Catch to handle it in the Fluent API. -------------------------------------------------------------------------------- /docs/forms/navigationerrors.md: -------------------------------------------------------------------------------- 1 | Errors happen when navigating. Using the PrismApplication in Prism.Forms.Extended allows you to automatically and globally handle these errors. 2 | 3 | ## Default Behavior 4 | 5 | - Writes to the Console that there was a Navigation Error 6 | - Resolves the ILogger, and Reports the Error with the following additional properties 7 | - Serializes the NavigationParameters to a JSON string 8 | - Adds the Navigation Uri 9 | 10 | ## Overriding the Default Behavior 11 | 12 | If the output on the NavigationError isn't quite what you're hoping for you will need to override the `OnNavigationError` in `PrismApplication`. As an example below we will maintain the same logging behavior but ensure that while debugging we always hit a breakpoint so we can explore the values of the Navigation Error anytime this is encountered. 13 | 14 | ```c# 15 | protected override void OnNavigationError(INavigationError navigationError) 16 | { 17 | #if DEBUG 18 | // Ensure we always break here while debugging! 19 | System.Diagnostics.Debugger.Break(); 20 | #endif 21 | 22 | base.OnNavigationError(navigationError); 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/forms/pagebehaviorfactory.md: -------------------------------------------------------------------------------- 1 | Prism's IPageBehaviorFactory is a great way to apply some custom behaviors on to pages either globally or with a little business logic. The Extended Prism.Forms package uses a custom PageBehaviorFactory. In addition to the normal behaviors that Prism applies to your Pages behind the scenes, the Extended version provides support for the following: 2 | 3 | - Globally adding Platform Specifics on: 4 | - SetToolbarPlacement on Android TabbedPage 5 | - Use Safe Area on iOS 6 | - PreferLargeTitles on iOS 7 | - A custom behavior that changes the Title of a TabbedPage to always match the actively selected Tab 8 | 9 | To control these features you simply need to register an implementation of `IPageBehaviorFactoryOptions`. 10 | 11 | !!! note "Note" 12 | A default instance is provided automatically that enables all of these features. 13 | 14 | ```c# 15 | internal class MyPageBehaviorFactoryOptions : IPageBehaviorFactoryOptions 16 | { 17 | public bool UseBottomTabs => true; 18 | 19 | public bool UseSafeArea => true; 20 | 21 | public bool UseChildTitle => true; 22 | 23 | public bool PreferLargeTitles => true; 24 | } 25 | ``` 26 | 27 | ## Using Explicit Values 28 | 29 | While it's great to generalize certain Platform Specifics like `UseBottomTabs` or `UseSafeArea`, there may be times which you prefer to opt-out of these platform specifics from the PageBehaviorFactory and either use the default value or a custom value. For these times you can update your XAML as follows: 30 | 31 | ```xml 32 | 34 | ``` 35 | 36 | Or in Code: 37 | 38 | ```csharp 39 | public class ViewA : ContentPage 40 | { 41 | public ViewA() 42 | { 43 | PlatformSpecifics.SetUseExplicit(this, true); 44 | } 45 | } 46 | ``` -------------------------------------------------------------------------------- /docs/registerdelegates.md: -------------------------------------------------------------------------------- 1 | # Delegate Registration 2 | 3 | Sometimes you really need a bit more power behind constructing a service. For these times you may find yourself in one of the following scenarios: 4 | 5 | - You just need to perform some Action like: 6 | 7 | ```c# 8 | public static IBackendService CreateBackendService() 9 | { 10 | return new BackendService 11 | { 12 | Uri = Constants.BackendUri 13 | }; 14 | } 15 | ``` 16 | 17 | - You need to resolve something to do a more complex look up and properly construct your type: 18 | 19 | ```c# 20 | public static IBackendService CreateBackendService(IContainerProvider containerProvider) 21 | { 22 | var options = containerProvider.Resolve(); 23 | return containerProvider.Resolve((typeof(Uri), options.BackendUri)); 24 | } 25 | ``` 26 | 27 | !!! note "Note" 28 | This supports both Delegates with `IContainerProvider` and `IServiceProvider` 29 | 30 | Regardless of which way you need to resolve service the Delegate Registration extensions really help out for those scenarios where you can't just simply pass a raw implementing type. 31 | 32 | ```c# 33 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 34 | { 35 | containerRegistry.RegisterDelegate(FooFactory); 36 | containerRegistry.RegisterDelegate(BarFactory); 37 | } 38 | 39 | private static IFoo FooFactory() => new Foo(); 40 | 41 | private static IBar BarFactory(IContainerProvider container) 42 | { 43 | var options = container.Resolve(); 44 | return new Bar { HasCode = options.HasCode }; 45 | } 46 | 47 | private static IBar BarFactory(IServiceProvider serviceProvider) 48 | { 49 | var options = serviceProvider.GetService(); 50 | return new Bar { HasCode = options.HasCode }; 51 | } 52 | ``` -------------------------------------------------------------------------------- /docs/registermany.md: -------------------------------------------------------------------------------- 1 | # RegisterMany 2 | 3 | One of the very powerful new methods provided by the Container Extensions is the `RegisterMany` and `RegisterManySingleton` method. This really can help you reduce how much boilerplate code you need to write and provide some advanced scenarios. So what is it? 4 | 5 | ```c# 6 | public interface IFoo 7 | { 8 | void DoFoo(); 9 | } 10 | 11 | public interface IBar 12 | { 13 | void DoBar(); 14 | } 15 | ``` 16 | 17 | To start let's assume that you have 2 interfaces like the ones above `IFoo` and `IBar`. Now let's assume that you have a single implementing type like: 18 | 19 | ```c# 20 | public class FooBar : IFoo, IBar 21 | { 22 | 23 | public void DoFoo() 24 | { 25 | Console.WriteLine("Doing foo"); 26 | } 27 | 28 | public void DoBar() 29 | { 30 | Console.WriteLine("Doing Bar"); 31 | } 32 | } 33 | ``` 34 | 35 | Without the Container Extensions you might have a transient registration like: 36 | 37 | ```c# 38 | containerRegistry.Register(); 39 | containerRegistry.Register(); 40 | ``` 41 | 42 | While this may not be such a big deal, it suddenly starts making more sense when we expect the use of a singleton. The issue here is that if we were to do something similar to this to register a Singleton traditionally like: 43 | 44 | ```c# 45 | containerRegistry.RegisterSingleton(); 46 | containerRegistry.RegisterSingleton(); 47 | ``` 48 | 49 | We are under the impression that we have a singleton here. The issue of course is that if you check for equality like: 50 | 51 | ```c# 52 | if(Container.Resolve() == Container.Resolve()) 53 | { 54 | Console.WriteLine("Foo and Bar are the same instance"); 55 | } 56 | else 57 | { 58 | Console.WriteLine("Foo and Bar are difference instances"); 59 | } 60 | ``` 61 | 62 | We might expect that the first case would evaluate to true that Foo and Bar are the same instance, but in reality they are two different instances. The issue isn't that we somehow didn't register them as a singleton because if you resolve IFoo twice and do the same equality check it will actually evaluate to true because they would be the same instance. However, Foo and Bar are different instances because they were registered separately. This is where `RegisterManySingleton` really shines. If we were to update our registration like: 63 | 64 | ```c# 65 | // Implicitly registers any implemented interfaces 66 | containerRegistry.RegisterManySingleton(); 67 | 68 | // Explicitly registers implemented interfaces 69 | containerRegistry.RegisterManySingleton(typeof(IFoo), typeof(IBar)) 70 | ``` 71 | 72 | We can now perform the same equality check above only this time `IFoo` and `IBar` would equal one another because they would both have been resolved from the same instance of the `FooBar` implementation. 73 | -------------------------------------------------------------------------------- /docs/registerservices.md: -------------------------------------------------------------------------------- 1 | # Register Services 2 | 3 | For those coming from an ASP.NET Core background, you're already very familiar with the RegisterServices method in which we can add services to the `IServiceCollection`. In truth this doesn't make as much sense with Prism Applications to fully adopt this pattern. That said there are services which may already ship with Registration helpers for `IServiceCollection`. In these cases rather than making it more difficult on you, the PrismContainerExtensions aim to make your life a little easier by providing a simple extension method that will allow you to register certain services with the `IServiceCollection` which can then update the underlying container. 4 | 5 | !!! note "Note" 6 | For those using the Prism.Microsoft.DependencyInjection.Extensions package, the services are registered directly with the underlying `IServiceCollection`. 7 | 8 | ```c# 9 | PrismContainerExtension.Current.RegisterServices(s => { 10 | s.AddHttpClient(); 11 | s.AddDbContext(o => o.UseSqlite("my connection string")); 12 | }) 13 | ``` -------------------------------------------------------------------------------- /docs/scoping.md: -------------------------------------------------------------------------------- 1 | # Scoping 2 | 3 | TODO -------------------------------------------------------------------------------- /docs/shiny/index.md: -------------------------------------------------------------------------------- 1 | # Working With Shiny 2 | 3 | [Shiny](https://github.com/shinyorg/shiny) uses the Microsoft.Extensions.DependencyInjection pattern of service registration found in ASP.NET Core applications with a Startup class. This in particular is a use case in which you will need to initialize a container prior to Forms.Init being called on the native platform. To work with Shiny you simply need to do something like the following: 4 | 5 | 6 | ```c# 7 | // Android 8 | [Application] 9 | public class App : Android.App.Application 10 | { 11 | public override void OnCreate() 12 | { 13 | AndroidShinyHost.Init(this, new MyStartup()); 14 | } 15 | } 16 | 17 | // iOS 18 | [Register("AppDelegate")] 19 | public partial class AppDelegate : FormsApplicationDelegate 20 | { 21 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 22 | { 23 | // this needs to be loaded before EVERYTHING 24 | iOSShinyHost.Init(new MyStartup()); 25 | 26 | Forms.Init(); 27 | this.LoadApplication(new App()); 28 | return base.FinishedLaunching(app, options); 29 | } 30 | 31 | // if you are using jobs, you need this 32 | public override void PerformFetch(UIApplication application, Action completionHandler) 33 | => JobManager.OnBackgroundFetch(completionHandler); 34 | } 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /docs/shiny/modularity.md: -------------------------------------------------------------------------------- 1 | Modularity support for Shiny is a preview feature and can be used by overriding the `ConfigureModuleCatalog` method in the `PrismStartup`, and adding modules just as you would do in the PrismApplication. 2 | 3 | ## Why on earth would I use this 4 | 5 | Ok it's a fair question why should you use this? Let's say that you are trying to build out a Modular application with Prism, but you also need some things from Shiny like you need to register some sort of Background Service. Rather than push the buck to the consuming application to wire everything up this can be taken of in the Module which can now be reused across apps with a more minimalistic configuration. 6 | 7 | ## How to use Modules with Shiny and Prism 8 | 9 | ```c# 10 | public class AppStartup : PrismStartup 11 | { 12 | public MockModuleStartup(ITestOutputHelper testOutputHelper) 13 | : base(testOutputHelper) 14 | { 15 | } 16 | 17 | protected override void ConfigureServices(IServiceCollection services) 18 | { 19 | // Register your services here... 20 | } 21 | 22 | protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) 23 | { 24 | moduleCatalog.AddModule(); 25 | } 26 | } 27 | ``` 28 | 29 | !!! note "Note" 30 | If adding modules here do not add the same module in your PrismApplication! 31 | 32 | ### Creating a Shiny Module 33 | 34 | Ok as if Modularity wasn't confusing enough... now we had to go and add a Shiny Module... The Shiny Module lets us continue to work with the `ServiceCollection` that you may have started with in the Startup class. As you'll see by inheriting from `ShinyModule` or `StartupModule` we can add services that we may need to here. 35 | 36 | ```c# 37 | public class MyShinyModule : ShinyModule 38 | { 39 | protected override void ConfigureServices(IServiceCollection services) 40 | { 41 | services.AddTransient(); 42 | } 43 | 44 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 45 | { 46 | containerRegistry.Register(); 47 | } 48 | } 49 | ``` 50 | 51 | !!! critical "Critical Note" 52 | Depending on what you are registering you may need to use a `StartupModule` which forces the registration to be actually at Startup. -------------------------------------------------------------------------------- /docs/shiny/navigation.md: -------------------------------------------------------------------------------- 1 | #### Navigation from Shiny Services 2 | 3 | While this is generally not a great idea, there could potentially be times in which you need to navigate from a background service. For these times you will need to use the INavigationServiceDelegate. It is important to understand that the NavigationServiceDelegate differs from the NavigationService that you are used to using as it will attempt to determine what the currently displayed page is and Navigate from there. This will do exactly what you want if you are resetting the NavigationStack but may not work as expected if you are doing some sort of relative navigation. 4 | 5 | ```c# 6 | public class MyStartup : PrismStartup 7 | { 8 | public override void ConfigureServices(IServiceCollection services) 9 | { 10 | services.UseNavigationDelegate(); 11 | } 12 | } 13 | 14 | public class NotificationDelegate : INotificationDelegate 15 | { 16 | private INavigationServiceDelegate NavigationService { get; } 17 | 18 | public NotificationDelegate(INavigationServiceDelegate navigationServiceDelegate) 19 | { 20 | NavigationService = navigationServiceDelegate; 21 | } 22 | 23 | public async Task OnEntry(NotificationResponse response) 24 | { 25 | if(!string.IsNullOrEmpty(notification.Payload)) 26 | { 27 | await NavigationService.NavigateAsync(notification.Payload); 28 | } 29 | } 30 | 31 | public Task OnReceived(Notification notification) 32 | { 33 | if(!string.IsNullOrEmpty(notification.Payload)) 34 | { 35 | await NavigationService.NavigateAsync(notification.Payload); 36 | } 37 | } 38 | } 39 | ``` -------------------------------------------------------------------------------- /docs/shiny/startup.md: -------------------------------------------------------------------------------- 1 | ```c# 2 | public class PrismStartup : ShinyStartup 3 | { 4 | public override void ConfigureServices(IServiceCollection services) 5 | { 6 | // Register services with Shiny like: 7 | services.UseGpsBackground(); 8 | } 9 | 10 | public override IServiceProvider CreateServiceProvider(IServiceCollection services) 11 | { 12 | return PrismContainerExtension.Current.CreateServiceProvider(services); 13 | } 14 | } 15 | ``` 16 | 17 | ### Shiny.Prism 18 | 19 | With your App using the PrismApplication from Prism.DryIoc.Forms.Extended you now only need to reference the PrismStartup as the base class for your Startup class like: 20 | 21 | ```c# 22 | public class MyStartup : PrismStartup 23 | { 24 | public override void ConfigureServices(IServiceCollection services) 25 | { 26 | // Register services with Shiny like: 27 | services.UseGps(); 28 | } 29 | } 30 | ``` 31 | 32 | You can now pass your startup to the ShinyHost at your application's startup and use full Dependency Injection of Shiny's services in your app, full DI of services from Prism's container within services that are resolved by Shiny. 33 | 34 | **NOTE:** Shiny uses `IServiceProvider` which does not support the use of named services. -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "3.1.404", 4 | "rollForward": "latestMinor", 5 | "allowPrerelease": false 6 | }, 7 | "msbuild-sdks": { 8 | "MSBuild.Sdk.Extras": "3.0.23" 9 | } 10 | } -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | # Project Information 2 | site_name: Prism.Container.Extensions 3 | site_description: Documentation for the Prism Container Extensions 4 | site_author: Dan Siegel 5 | site_url: https://prismplugins.com 6 | 7 | # Repository 8 | repo_name: dansiegel/Prism.Container.Extensions 9 | repo_url: https://github.com/dansiegel/Prism.Container.Extensions 10 | edit_uri: '' 11 | 12 | # Copyright 13 | copyright: 'Copyright © 2016 - 2020 Dan Siegel' 14 | 15 | # Configuration 16 | theme: 17 | name: 'material' 18 | custom_dir: 'theme' 19 | icon: 20 | repo: fontawesome/brands/github 21 | logo: assets/prism-logo.png 22 | favicon: assets/favicon.ico 23 | language: en 24 | features: 25 | - navigation.tabs 26 | - navigation.tabs.sticky 27 | palette: 28 | primary: 'white' 29 | accent: 'cyan' 30 | 31 | # Social 32 | extra: 33 | social: 34 | - icon: fontawesome/brands/html5 35 | link: https://dansiegel.net 36 | - icon: fontawesome/brands/github 37 | link: https://github.com/dansiegel 38 | - icon: fontawesome/brands/twitch 39 | link: https://twitch.tv/dansiegel 40 | - icon: fontawesome/brands/twitter 41 | link: https://twitter.com/DanJSiegel 42 | - icon: fontawesome/brands/youtube 43 | link: https://www.youtube.com/DanSiegel 44 | - icon: fontawesome/brands/linkedin 45 | link: https://linkedin.com/in/DanSiegel 46 | 47 | # Extensions 48 | markdown_extensions: 49 | - admonition: 50 | - codehilite: 51 | linenums: false 52 | - toc: 53 | permalink: true 54 | 55 | nav: 56 | - Prism: 57 | - Prism Library: http://prismlibrary.github.io/docs 58 | - Logging: 59 | - Logging: http://logging.prismplugins.com 60 | - Popups: 61 | - Popups: http://popups.prismplugins.com 62 | - Container Extensions: 63 | - Getting Started: index.md 64 | - RegisterMany: registermany.md 65 | - Delegate Registration: registerdelegates.md 66 | - Scoped Services: scoping.md 67 | - Registration with IServiceCollection: registerservices.md 68 | - Containers: 69 | - Basics: containers/index.md 70 | - DryIoc: containers/dryioc.md 71 | - Microsoft D.I. Extensions: containers/microsoft-extensions-dependencyinjection.md 72 | - Unity: containers/unity.md 73 | - Prism.Forms Extended: 74 | - Intro: forms/index.md 75 | - Page Behavior Factory: forms/pagebehaviorfactory.md 76 | - Global Navigation Errors: forms/navigationerrors.md 77 | - Fluent Navigation: forms/fluent-navigation.md 78 | - ExecutionAwareCommand: forms/executionawarecommand.md 79 | - Shiny Support: 80 | - Intro: shiny/index.md 81 | - Startup: shiny/startup.md 82 | - Modularity: shiny/modularity.md 83 | - Navigation: shiny/navigation.md 84 | - Mobile.BuildTools: 85 | - Mobile.BuildTools: http://mobilebuildtools.com 86 | 87 | google_analytics: 88 | - UA-153405647-1 89 | - auto 90 | -------------------------------------------------------------------------------- /plugin.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/plugin.snk -------------------------------------------------------------------------------- /prism-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/prism-logo.png -------------------------------------------------------------------------------- /sample/.editorconfig: -------------------------------------------------------------------------------- 1 | # Suppress: EC112 2 | # top-most EditorConfig file 3 | root = true 4 | 5 | # Don't use tabs for indentation. 6 | [*] 7 | indent_style = space 8 | # (Please don't specify an indent_size here; that has too many unintended consequences.) 9 | 10 | [*.yml] 11 | indent_size = 2 12 | 13 | # Code files 14 | [*.{cs,csx,vb,vbx}] 15 | indent_size = 4 16 | 17 | # Code files 18 | [*.sln] 19 | indent_size = 4 20 | 21 | # Xml project files 22 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] 23 | indent_size = 2 24 | 25 | # Xml config files 26 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] 27 | indent_size = 2 28 | 29 | # XAML files 30 | [*.xaml] 31 | indent_size = 2 32 | 33 | # JSON files 34 | [*.json] 35 | indent_size = 2 36 | 37 | # XML files 38 | [*.xml] 39 | indent_size = 2 40 | 41 | # PList Files 42 | [*.plist] 43 | indent_size = 2 44 | 45 | # YAML files 46 | [*.{yaml,yml}] 47 | indent_size = 2 -------------------------------------------------------------------------------- /sample/PrismSample.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace PrismSample.Droid 6 | { 7 | [Activity(Theme = "@style/MainTheme", 8 | ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 9 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 10 | { 11 | protected override void OnCreate(Bundle savedInstanceState) 12 | { 13 | TabLayoutResource = Resource.Layout.Tabbar; 14 | ToolbarResource = Resource.Layout.Toolbar; 15 | 16 | base.OnCreate(savedInstanceState); 17 | 18 | global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 19 | LoadApplication(new App()); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /sample/PrismSample.Android/MainApplication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.App; 3 | using Android.Runtime; 4 | using Shiny; 5 | using PrismSample.Shiny; 6 | 7 | namespace PrismSample.Droid 8 | { 9 | [Application( 10 | Label = "Prism Sample", 11 | Icon = "@mipmap/icon" 12 | )] 13 | public class MainApplication : Application 14 | { 15 | public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) 16 | : base(javaReference, transfer) 17 | { 18 | } 19 | 20 | public override void OnCreate() 21 | { 22 | base.OnCreate(); 23 | this.ShinyOnCreate(new Startup()); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /sample/PrismSample.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("PrismSample.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("PrismSample.Android")] 14 | [assembly: AssemblyCopyright("Copyright © Prism Library 2019")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Add some common permissions, these can be removed if not needed 20 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 21 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 22 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/layout/Tabbar.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/layout/Toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-anydpi-v26/icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-anydpi-v26/icon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-hdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-hdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-hdpi/launcher_foreground.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-mdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-mdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-mdpi/launcher_foreground.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xxxhdpi/icon.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #7E7D81 5 | #5f5f61 6 | #00A5F2 7 | 8 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 26 | 27 | 30 | 31 | 38 | 39 | -------------------------------------------------------------------------------- /sample/PrismSample.Android/SplashActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.OS; 3 | using Android.Content; 4 | using Android.Util; 5 | using AndroidX.AppCompat.App; 6 | 7 | namespace PrismSample.Droid 8 | { 9 | [Activity(Theme = "@style/MainTheme.Splash", 10 | MainLauncher = true, 11 | NoHistory = true)] 12 | public class SplashActivity : AppCompatActivity 13 | { 14 | static readonly string TAG = "X:" + typeof(SplashActivity).Name; 15 | 16 | public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState) 17 | { 18 | base.OnCreate(savedInstanceState, persistentState); 19 | Log.Debug(TAG, "SplashActivity.OnCreate"); 20 | } 21 | 22 | // Launches the startup task 23 | protected override void OnResume() 24 | { 25 | base.OnResume(); 26 | StartActivity(new Intent(Application.Context, typeof(MainActivity))); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /sample/PrismSample.UWP/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SmallTile.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/StoreLogo.backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/StoreLogo.backup.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.UWP/Assets/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /sample/PrismSample.UWP/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /sample/PrismSample.UWP/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.Foundation; 7 | using Windows.Foundation.Collections; 8 | using Windows.UI.Xaml; 9 | using Windows.UI.Xaml.Controls; 10 | using Windows.UI.Xaml.Controls.Primitives; 11 | using Windows.UI.Xaml.Data; 12 | using Windows.UI.Xaml.Input; 13 | using Windows.UI.Xaml.Media; 14 | using Windows.UI.Xaml.Navigation; 15 | 16 | namespace PrismSample.UWP 17 | { 18 | public sealed partial class MainPage 19 | { 20 | public MainPage() 21 | { 22 | this.InitializeComponent(); 23 | 24 | LoadApplication(new PrismSample.App()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | PrismSample.UWP 18 | bd7518f2-03fc-45a4-b350-42248a9373f1 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PrismSample.UWP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PrismSample.UWP")] 13 | [assembly: AssemblyCopyright("Copyright © Prism Library 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /sample/PrismSample.UWP/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Foundation; 5 | using Prism.DryIoc; 6 | using UIKit; 7 | using Shiny; 8 | using PrismSample.Shiny; 9 | using Prism.DryIoc.Internals; 10 | 11 | // Force the assembly into the App Domain 12 | // Required for the Sample... this should be brought in automatically for NuGet references 13 | [assembly: PrismContainerExtension] 14 | namespace PrismSample.iOS 15 | { 16 | // The UIApplicationDelegate for the application. This class is responsible for launching the 17 | // User Interface of the application, as well as listening (and optionally responding) to 18 | // application events from iOS. 19 | [Register("AppDelegate")] 20 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 21 | { 22 | // 23 | // This method is invoked when the application has loaded and is ready to run. In this 24 | // method you should instantiate the window, load the UI into it and then make the window 25 | // visible. 26 | // 27 | // You have 17 seconds to return from this method, or iOS will terminate your application. 28 | // 29 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 30 | { 31 | this.ShinyFinishedLaunching(new Startup()); 32 | global::Xamarin.Forms.Forms.Init(); 33 | LoadApplication(new App()); 34 | 35 | return base.FinishedLaunching(app, options); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "scale": "2x", 5 | "size": "20x20", 6 | "idiom": "iphone", 7 | "filename": "Icon40.png" 8 | }, 9 | { 10 | "scale": "3x", 11 | "size": "20x20", 12 | "idiom": "iphone", 13 | "filename": "Icon60.png" 14 | }, 15 | { 16 | "scale": "2x", 17 | "size": "29x29", 18 | "idiom": "iphone", 19 | "filename": "Icon58.png" 20 | }, 21 | { 22 | "scale": "3x", 23 | "size": "29x29", 24 | "idiom": "iphone", 25 | "filename": "Icon87.png" 26 | }, 27 | { 28 | "scale": "2x", 29 | "size": "40x40", 30 | "idiom": "iphone", 31 | "filename": "Icon80.png" 32 | }, 33 | { 34 | "scale": "3x", 35 | "size": "40x40", 36 | "idiom": "iphone", 37 | "filename": "Icon120.png" 38 | }, 39 | { 40 | "scale": "2x", 41 | "size": "60x60", 42 | "idiom": "iphone", 43 | "filename": "Icon120.png" 44 | }, 45 | { 46 | "scale": "3x", 47 | "size": "60x60", 48 | "idiom": "iphone", 49 | "filename": "Icon180.png" 50 | }, 51 | { 52 | "scale": "1x", 53 | "size": "20x20", 54 | "idiom": "ipad", 55 | "filename": "Icon20.png" 56 | }, 57 | { 58 | "scale": "2x", 59 | "size": "20x20", 60 | "idiom": "ipad", 61 | "filename": "Icon40.png" 62 | }, 63 | { 64 | "scale": "1x", 65 | "size": "29x29", 66 | "idiom": "ipad", 67 | "filename": "Icon29.png" 68 | }, 69 | { 70 | "scale": "2x", 71 | "size": "29x29", 72 | "idiom": "ipad", 73 | "filename": "Icon58.png" 74 | }, 75 | { 76 | "scale": "1x", 77 | "size": "40x40", 78 | "idiom": "ipad", 79 | "filename": "Icon40.png" 80 | }, 81 | { 82 | "scale": "2x", 83 | "size": "40x40", 84 | "idiom": "ipad", 85 | "filename": "Icon80.png" 86 | }, 87 | { 88 | "scale": "1x", 89 | "size": "76x76", 90 | "idiom": "ipad", 91 | "filename": "Icon76.png" 92 | }, 93 | { 94 | "scale": "2x", 95 | "size": "76x76", 96 | "idiom": "ipad", 97 | "filename": "Icon152.png" 98 | }, 99 | { 100 | "scale": "2x", 101 | "size": "83.5x83.5", 102 | "idiom": "ipad", 103 | "filename": "Icon167.png" 104 | }, 105 | { 106 | "scale": "1x", 107 | "size": "1024x1024", 108 | "idiom": "ios-marketing", 109 | "filename": "Icon1024.png" 110 | } 111 | ], 112 | "properties": {}, 113 | "info": { 114 | "version": 1, 115 | "author": "xcode" 116 | } 117 | } -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UISupportedInterfaceOrientations 11 | 12 | UIInterfaceOrientationPortrait 13 | UIInterfaceOrientationLandscapeLeft 14 | UIInterfaceOrientationLandscapeRight 15 | 16 | UISupportedInterfaceOrientations~ipad 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationPortraitUpsideDown 20 | UIInterfaceOrientationLandscapeLeft 21 | UIInterfaceOrientationLandscapeRight 22 | 23 | MinimumOSVersion 24 | 10.0 25 | CFBundleDisplayName 26 | Prism Extended 27 | CFBundleIdentifier 28 | com.prismlibrary.prismextensions 29 | CFBundleVersion 30 | 1.0 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | CFBundleName 34 | PrismSample 35 | XSAppIconAssets 36 | Assets.xcassets/AppIcon.appiconset 37 | CFBundleShortVersionString 38 | 1 39 | 40 | 41 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace PrismSample.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PrismSample.iOS")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PrismSample.iOS")] 13 | [assembly: AssemblyCopyright("Copyright © Prism Library 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] 24 | -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Resources/Default.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dansiegel/Prism.Container.Extensions/82d64498fd8fd3e48041ccc774433e7e8120d7e5/sample/PrismSample.iOS/Resources/Default@2x.png -------------------------------------------------------------------------------- /sample/PrismSample.iOS/Resources/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /sample/PrismSample/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 9 | 10 | -------------------------------------------------------------------------------- /sample/PrismSample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Ioc; 3 | using PrismSample.ViewModels; 4 | using PrismSample.Views; 5 | using Xamarin.Forms; 6 | 7 | namespace PrismSample 8 | { 9 | public partial class App 10 | { 11 | public App() 12 | { 13 | } 14 | 15 | protected override async void OnInitialized() 16 | { 17 | InitializeComponent(); 18 | 19 | var result = await NavigationService.NavigateAsync("MainPage"); 20 | 21 | if (!result.Success) 22 | { 23 | MainPage = new MainPage 24 | { 25 | BindingContext = new MainPageViewModel 26 | { 27 | Message = result.Exception.Message 28 | } 29 | }; 30 | System.Diagnostics.Debugger.Break(); 31 | } 32 | } 33 | 34 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 35 | { 36 | containerRegistry.RegisterForNavigation(); 37 | containerRegistry.RegisterForNavigation(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sample/PrismSample/PrismSample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | true 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sample/PrismSample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms.Xaml; 2 | 3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)] -------------------------------------------------------------------------------- /sample/PrismSample/Shiny/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Shiny; 3 | using Shiny.Prism; 4 | 5 | namespace PrismSample.Shiny 6 | { 7 | public class Startup : PrismStartup 8 | { 9 | protected override void ConfigureServices(IServiceCollection services, IPlatform platform) 10 | { 11 | // Register Stuff 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sample/PrismSample/ViewModels/MainPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Prism.Mvvm; 5 | using Shiny.Net; 6 | 7 | namespace PrismSample.ViewModels 8 | { 9 | public class MainPageViewModel : BindableBase 10 | { 11 | private IConnectivity _connectivity { get; set; } 12 | 13 | public MainPageViewModel() { } 14 | 15 | public MainPageViewModel(IConnectivity connectivity) 16 | { 17 | _connectivity = connectivity; 18 | 19 | _connectivity.WhenInternetStatusChanged() 20 | .Subscribe(OnConnectivityChanged); 21 | 22 | OnConnectivityChanged(_connectivity.IsInternetAvailable()); 23 | } 24 | 25 | private string _message; 26 | public string Message 27 | { 28 | get => _message; 29 | set => SetProperty(ref _message, value); 30 | } 31 | 32 | private void OnConnectivityChanged(bool connected) 33 | { 34 | if (connected) 35 | { 36 | Message = "The internet is connected... We can now do our anti-Social Media... and swipe right, and like our friend's lunch..."; 37 | } 38 | else 39 | { 40 | Message = "Whoops! It seems the internet has gone missing... we're going into withdrawls... please bring it back..."; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample/PrismSample/Views/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 9 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sample/PrismSample/Views/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace PrismSample.Views 4 | { 5 | // Learn more about making custom code visible in the Xamarin.Forms previewer 6 | // by visiting https://aka.ms/xamarinforms-previewer 7 | [DesignTimeVisible(false)] 8 | public partial class MainPage 9 | { 10 | public MainPage() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/IServiceCollectionAware.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Prism.Ioc; 5 | 6 | namespace Prism.Container.Extensions 7 | { 8 | [EditorBrowsable(EditorBrowsableState.Never)] 9 | public interface IServiceCollectionAware 10 | { 11 | [EditorBrowsable(EditorBrowsableState.Never)] 12 | IContainerRegistry RegisterServices(Action registerServices); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/IServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Prism.Container.Extensions; 5 | 6 | namespace Prism.Ioc 7 | { 8 | /// 9 | /// Adds extensions for to use 10 | /// 11 | public static class IServiceCollectionExtensions 12 | { 13 | /// 14 | /// Registers services with the Container using the 15 | /// 16 | /// The 17 | /// The to perform on the 18 | /// 19 | public static IContainerRegistry RegisterServices(this IContainerRegistry containerRegistry, Action registerServices) 20 | { 21 | if (containerRegistry is IServiceCollectionAware sca) 22 | { 23 | sca.RegisterServices(registerServices); 24 | } 25 | else 26 | { 27 | var services = new ServiceCollection(); 28 | registerServices(services); 29 | IServiceProviderExtensions.RegisterTypesWithPrismContainer(containerRegistry, services); 30 | } 31 | 32 | return containerRegistry; 33 | } 34 | } 35 | 36 | internal class ServiceCollection : List, IServiceCollection 37 | { 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/Internals/ContainerExtensionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Prism.Ioc; 4 | 5 | namespace Prism.Container.Extensions.Internals 6 | { 7 | [EditorBrowsable(EditorBrowsableState.Never)] 8 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 9 | public abstract class ContainerExtensionAttribute : Attribute 10 | { 11 | public IContainerExtension GetContainer() 12 | { 13 | var container = Init(); 14 | ContainerLocator.SetContainerExtension(() => container); 15 | return ContainerLocator.Current; 16 | } 17 | 18 | protected abstract IContainerExtension Init(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/Internals/ContainerLocationHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Reflection; 6 | using Prism.Ioc; 7 | 8 | namespace Prism.Container.Extensions.Internals 9 | { 10 | [EditorBrowsable(EditorBrowsableState.Never)] 11 | public static class ContainerLocationHelper 12 | { 13 | [EditorBrowsable(EditorBrowsableState.Never)] 14 | public static IContainerExtension LocateContainer(IContainerExtension container = null) 15 | { 16 | if (container != null) 17 | { 18 | ContainerLocator.SetContainerExtension(() => container); 19 | } 20 | 21 | try 22 | { 23 | var located = ContainerLocator.Current; 24 | if (located != null) 25 | return located; 26 | 27 | // If somehow we have an actual null container let's be sure to refresh the Locator 28 | ContainerLocator.ResetContainer(); 29 | } 30 | catch 31 | { 32 | // suppress any errors 33 | ContainerLocator.ResetContainer(); 34 | } 35 | 36 | var containerAttributes = AppDomain.CurrentDomain.GetAssemblies() 37 | .Where(x => x.GetCustomAttributes().Any()) 38 | .Select(x => x.GetCustomAttribute()) 39 | .Distinct(); 40 | 41 | if (!containerAttributes.Any()) 42 | throw new InvalidOperationException("An instance of the IContainerExtension has not been registered with the ContainerLocator, and no ContainerExtensionAttribute has been found in the entry assembly."); 43 | else if (containerAttributes.Count() > 1) 44 | throw new InvalidOperationException("More than one ContainerExtensionAttribute has been found on the entry assembly. Only a single ContainerExtension should be referenced."); 45 | 46 | var containerExtensionAttribute = containerAttributes.First(); 47 | return containerExtensionAttribute.GetContainer(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/Prism.Container.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net461;net47 5 | Prism Container Extension Abstractions 6 | prism di extensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/PrismServiceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Ioc 4 | { 5 | internal class PrismServiceProvider : IServiceProvider 6 | { 7 | private IContainerProvider _container { get; } 8 | 9 | public PrismServiceProvider(IContainerExtension container) 10 | : this((IContainerProvider)container) { } 11 | 12 | public PrismServiceProvider(IContainerRegistry container) 13 | : this(container as IContainerProvider) { } 14 | 15 | public PrismServiceProvider(IContainerProvider container) 16 | { 17 | _container = container; 18 | } 19 | 20 | object IServiceProvider.GetService(Type serviceType) => _container.Resolve(serviceType); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/PrismServiceScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace Prism.Ioc 5 | { 6 | public class PrismServiceScope : IServiceScope 7 | { 8 | private IScopedProvider _scopedProvider; 9 | 10 | public PrismServiceScope(IScopedProvider scopedProvider) 11 | { 12 | _scopedProvider = scopedProvider; 13 | ServiceProvider = new PrismServiceProvider(scopedProvider.CurrentScope); 14 | } 15 | 16 | public IServiceProvider ServiceProvider { get; } 17 | 18 | public void Dispose() 19 | { 20 | if (_scopedProvider != null) 21 | { 22 | _scopedProvider.Dispose(); 23 | _scopedProvider = null; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Prism.Container.Extensions/RegisterOnceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Prism.Ioc; 6 | 7 | namespace Prism.Ioc 8 | { 9 | public static class RegisterOnceExtensions 10 | { 11 | public static IContainerRegistry RegisterSingletonOnce(this IContainerRegistry containerRegistry) 12 | where TTo : TFrom 13 | { 14 | if (!containerRegistry.IsRegistered()) 15 | { 16 | containerRegistry.RegisterSingleton(); 17 | } 18 | 19 | return containerRegistry; 20 | } 21 | 22 | public static IContainerRegistry RegisterManySingletonOnce(this IContainerRegistry containerRegistry, params Type[] services) 23 | { 24 | if (!containerRegistry.IsRegistered() && !services.Any(s => containerRegistry.IsRegistered(s))) 25 | { 26 | containerRegistry.RegisterManySingleton(services); 27 | } 28 | 29 | return containerRegistry; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/ContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using DryIoc; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Prism.DryIoc; 7 | using Prism.Ioc; 8 | 9 | namespace Prism.DryIoc 10 | { 11 | partial class DryIocContainerExtension : IServiceScopeFactory 12 | { 13 | public DryIocContainerExtension(IContainer container) 14 | { 15 | Instance = container; 16 | Instance.RegisterInstanceMany(new[] 17 | { 18 | typeof(IContainerExtension), 19 | typeof(IContainerProvider), 20 | typeof(IServiceScopeFactory) 21 | }, this); 22 | Instance.RegisterDelegate(r => r); 23 | } 24 | 25 | IServiceScope IServiceScopeFactory.CreateScope() 26 | { 27 | var scope = CreateScopeInternal(); 28 | return new PrismServiceScope(scope); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/Extensions/PrismIocExtensions.cs: -------------------------------------------------------------------------------- 1 | using DryIoc; 2 | using Prism.Ioc; 3 | 4 | namespace Prism.DryIoc.Extensions 5 | { 6 | public static class PrismIocExtensions 7 | { 8 | public static IContainer GetContainer(this IContainerProvider containerProvider) 9 | { 10 | return ((IContainerExtension)containerProvider).Instance; 11 | } 12 | 13 | public static IContainer GetContainer(this IContainerRegistry containerRegistry) 14 | { 15 | return ((IContainerExtension)containerRegistry).Instance; 16 | } 17 | 18 | public static bool IsRegistered(this IContainerProvider containerProvider) 19 | { 20 | return ((IContainerExtension)containerProvider).Instance.IsRegistered(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/Internals/PrismContainerExtensionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Prism.Container.Extensions.Internals; 4 | using Prism.Ioc; 5 | 6 | namespace Prism.DryIoc.Internals 7 | { 8 | [EditorBrowsable(EditorBrowsableState.Never)] 9 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 10 | public sealed class PrismContainerExtensionAttribute : ContainerExtensionAttribute 11 | { 12 | protected override IContainerExtension Init() => PrismContainerExtension.Init(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/Prism.DryIoc.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;Xamarin.iOS10 5 | Prism Container Extensions for DryIoc 6 | $(DefineConstants);ContainerExtensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/PrismContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using DryIoc; 3 | using Prism.Ioc; 4 | 5 | namespace Prism.DryIoc 6 | { 7 | public static class PrismContainerExtension 8 | { 9 | public static Rules DefaultRules => DryIocContainerExtension.DefaultRules; 10 | 11 | public static IContainerExtension Current => ContainerLocator.Current ?? Init(); 12 | 13 | public static IContainerExtension Init() => 14 | Init(DefaultRules); 15 | 16 | public static IContainerExtension Init(Rules rules) => 17 | Init(new global::DryIoc.Container(rules)); 18 | 19 | public static IContainerExtension Init(IContainer container) 20 | { 21 | if (ContainerLocator.Current != null) 22 | throw new NotSupportedException("The PrismContainerExtension has already been initialized."); 23 | 24 | var extension = new DryIocContainerExtension(container); 25 | ContainerLocator.SetContainerExtension(() => extension); 26 | return ContainerLocator.Current; 27 | } 28 | 29 | internal static void Reset() 30 | { 31 | ContainerLocator.ResetContainer(); 32 | GC.Collect(int.MaxValue, GCCollectionMode.Forced); 33 | GC.WaitForFullGCComplete(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Prism.DryIoc.Extensions.Tests")] 4 | [assembly: InternalsVisibleTo("Prism.DryIoc.Forms.Extended.Tests")] 5 | [assembly: InternalsVisibleTo("Shiny.Prism.Tests")] 6 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Thank you for using the Prism.Container.Extensions! 2 | 3 | Please note that as of Prism 8, this library is in maintenance mode. The extensions first introduced here, are now mostly included out of the box with Prism 8 with the exception of the IServiceCollection & ShinyLib support. This support is better provided via the Prism.Magician. The Magician is available to all GitHub sponsors for their use, and available via corporate license through AvantiPoint. 4 | 5 | Docs are available at https://prismplugins.com 6 | 7 | ** SUPPORT ** 8 | 9 | This is an open source project and is provided as is. If you require support please contact AvantiPoint for a Support Contract. 10 | 11 | ** NOTE ** 12 | 13 | This package is meant to replace the container package shipped by the Prism team for the platform of your choice. You should reference the base platform package and update your app from PrismApplication to instead inherit from PrismApplicationBase and add the following code to your app: 14 | 15 | protected override IContainerExtension CreateContainerExtension() 16 | { 17 | return ContainerLocator.Current; 18 | } 19 | 20 | If building a Xamarin.Forms app you may instead use Prism.Forms.Extended which requires no changes to your code. -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/build/PreserveContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using Prism.DryIoc.Internals; 2 | 3 | // Force the assembly into the App Domain 4 | [assembly: PrismContainerExtension] 5 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Extensions/build/Prism.DryIoc.Extensions.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Behaviors/DefaultPageBehaviorFactoryOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Behaviors 2 | { 3 | internal class DefaultPageBehaviorFactoryOptions : IPageBehaviorFactoryOptions 4 | { 5 | public bool UseBottomTabs => true; 6 | 7 | public bool UseSafeArea => true; 8 | 9 | public bool UseChildTitle => true; 10 | 11 | public bool PreferLargeTitles => true; 12 | } 13 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Behaviors/ExtendedPageBehaviorFactory.cs: -------------------------------------------------------------------------------- 1 | using Prism.Forms.Extended.ViewModels; 2 | using Prism.Platform; 3 | using Xamarin.Forms; 4 | using AndroidTabbedPage = Xamarin.Forms.PlatformConfiguration.AndroidSpecific.TabbedPage; 5 | using iOSNavPage = Xamarin.Forms.PlatformConfiguration.iOSSpecific.NavigationPage; 6 | using iOSPage = Xamarin.Forms.PlatformConfiguration.iOSSpecific.Page; 7 | using TabbedPage = Xamarin.Forms.TabbedPage; 8 | 9 | namespace Prism.Behaviors 10 | { 11 | public class ExtendedPageBehaviorFactory : PageBehaviorFactory 12 | { 13 | private IPageBehaviorFactoryOptions _options { get; } 14 | 15 | public ExtendedPageBehaviorFactory(IPageBehaviorFactoryOptions options) 16 | { 17 | _options = options; 18 | } 19 | 20 | protected override void ApplyTabbedPageBehaviors(TabbedPage page) 21 | { 22 | base.ApplyTabbedPageBehaviors(page); 23 | 24 | if (page.BindingContext is DefaultViewModel) 25 | { 26 | page.SetBinding(Page.TitleProperty, new Binding { Path = "Title" }); 27 | } 28 | 29 | if (_options.UseBottomTabs && !PlatformSpecifics.GetUseExplicit(page)) 30 | { 31 | AndroidTabbedPage.SetToolbarPlacement(page, Xamarin.Forms.PlatformConfiguration.AndroidSpecific.ToolbarPlacement.Bottom); 32 | } 33 | 34 | if (_options.UseChildTitle) 35 | { 36 | page.Behaviors.Add(new TabbedPageChildTitleBehavior()); 37 | } 38 | } 39 | 40 | protected override void ApplyPageBehaviors(Page page) 41 | { 42 | base.ApplyPageBehaviors(page); 43 | 44 | if (!PlatformSpecifics.GetUseExplicit(page)) 45 | { 46 | iOSPage.SetUseSafeArea(page, _options.UseSafeArea); 47 | } 48 | } 49 | 50 | protected override void ApplyNavigationPageBehaviors(NavigationPage page) 51 | { 52 | base.ApplyNavigationPageBehaviors(page); 53 | 54 | if (!PlatformSpecifics.GetUseExplicit(page)) 55 | { 56 | iOSNavPage.SetPrefersLargeTitles(page, _options.PreferLargeTitles); 57 | } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Behaviors/IPageBehaviorFactoryOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Behaviors 2 | { 3 | public interface IPageBehaviorFactoryOptions 4 | { 5 | bool UseBottomTabs { get; } 6 | 7 | bool UseSafeArea { get; } 8 | 9 | bool UseChildTitle { get; } 10 | 11 | bool PreferLargeTitles { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Behaviors/TabbedPageChildTitleBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Xamarin.Forms; 3 | 4 | namespace Prism.Behaviors 5 | { 6 | public class TabbedPageChildTitleBehavior : BehaviorBase 7 | { 8 | protected override void OnAttachedTo(TabbedPage bindable) 9 | { 10 | base.OnAttachedTo(bindable); 11 | bindable.SetBinding(Page.TitleProperty, new Binding { Path = "CurrentPage.Title", Source = bindable }); 12 | 13 | if (bindable.BindingContext is INotifyPropertyChanged vm) 14 | { 15 | vm.PropertyChanged += OnViewModelPropertyChanged; 16 | } 17 | } 18 | 19 | protected override void OnDetachingFrom(TabbedPage bindable) 20 | { 21 | base.OnDetachingFrom(bindable); 22 | 23 | if (bindable.BindingContext is INotifyPropertyChanged vm) 24 | { 25 | vm.PropertyChanged -= OnViewModelPropertyChanged; 26 | } 27 | } 28 | 29 | private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) 30 | { 31 | if (e.PropertyName == "Title") 32 | { 33 | AssociatedObject.RemoveBinding(Page.TitleProperty); 34 | var property = AssociatedObject.BindingContext.GetType().GetProperty(e.PropertyName); 35 | AssociatedObject.Title = (string)property.GetValue(AssociatedObject.BindingContext); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Commands/ExecutionAwareCommandBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Runtime.CompilerServices; 5 | using System.Threading.Tasks; 6 | using System.Windows.Input; 7 | using Prism.Forms.Extended.Common; 8 | 9 | namespace Prism.Commands 10 | { 11 | public abstract class ExecutionAwareCommandBase : DelegateCommandBase, ICommand, INotifyPropertyChanged 12 | { 13 | protected readonly ErrorHandlerRegistry _registry = new ErrorHandlerRegistry(); 14 | 15 | private bool _isExecuting; 16 | public bool IsExecuting 17 | { 18 | get => _isExecuting; 19 | set => SetProperty(ref _isExecuting, value, OnIsExecutingChanged); 20 | } 21 | 22 | private void OnIsExecutingChanged() 23 | { 24 | onIsExecutingDelegate?.Invoke(IsExecuting); 25 | } 26 | 27 | internal Action onIsExecutingDelegate; 28 | 29 | public event PropertyChangedEventHandler PropertyChanged; 30 | 31 | protected bool SetProperty(ref T storage, T value, Action onChange, [CallerMemberName] string propertyName = null) 32 | { 33 | if (EqualityComparer.Default.Equals(storage, value)) return false; 34 | 35 | storage = value; 36 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 37 | onChange(); 38 | 39 | return true; 40 | } 41 | } 42 | 43 | public static class ExecutionAwareCommandExtensions 44 | { 45 | public static T OnIsExecutingChanged(this T command, Action delegateAction) 46 | where T : ExecutionAwareCommandBase 47 | { 48 | command.onIsExecutingDelegate = delegateAction; 49 | return command; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Commands/UnhandledCommandException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Commands 4 | { 5 | public class UnhandledCommandException : Exception 6 | { 7 | internal UnhandledCommandException(Exception innerException) 8 | : base("No Handler was found to handle an exception encountered by the Command", innerException) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Common/ErrorHandlerRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace Prism.Forms.Extended.Common 7 | { 8 | public class ErrorHandlerRegistry : IDictionary> 9 | { 10 | private readonly Dictionary> _handlers = new Dictionary>(); 11 | 12 | public Action this[Type key] 13 | { 14 | get => _handlers[key]; 15 | set => _handlers[key] = value; 16 | } 17 | 18 | public Action CatchAll { get; set; } 19 | public ICollection Keys => _handlers.Keys; 20 | public ICollection> Values => _handlers.Values; 21 | public int Count => _handlers.Count; 22 | public bool IsReadOnly => false; 23 | 24 | public void Add(Type key, Action value) => 25 | _handlers.Add(key, value); 26 | 27 | public void Add(KeyValuePair> item) => 28 | Add(item.Key, item.Value); 29 | 30 | public void Clear() => _handlers.Clear(); 31 | 32 | public bool Contains(KeyValuePair> item) => 33 | _handlers.Any(x => x.Equals(item)); 34 | 35 | public bool ContainsKey(Type key) => 36 | _handlers.ContainsKey(key); 37 | 38 | public void CopyTo(KeyValuePair>[] array, int arrayIndex) 39 | { 40 | var dict = (IDictionary)_handlers; 41 | dict.CopyTo(array, arrayIndex); 42 | } 43 | 44 | public IEnumerator>> GetEnumerator() => 45 | _handlers.GetEnumerator(); 46 | 47 | public bool HandledException(Exception ex) 48 | { 49 | if (ex is null) return true; 50 | 51 | var type = ex.GetType(); 52 | foreach (var key in Keys) 53 | { 54 | if (type.IsAssignableFrom(key)) 55 | { 56 | var handler = this[key]; 57 | handler?.Invoke(ex); 58 | return true; 59 | } 60 | } 61 | 62 | if (ex is AggregateException ae) 63 | { 64 | var results = ae.InnerExceptions.Select(e => HandledException(e)); 65 | return results.Where(x => x == false).Count() == 0; 66 | } 67 | 68 | if (CatchAll is null) 69 | { 70 | return false; 71 | } 72 | 73 | CatchAll.Invoke(ex); 74 | return true; 75 | } 76 | 77 | public bool Remove(Type key) => 78 | _handlers.Remove(key); 79 | 80 | public bool Remove(KeyValuePair> item) => 81 | _handlers.Remove(item.Key); 82 | 83 | public bool TryGetValue(Type key, out Action value) => 84 | _handlers.TryGetValue(key, out value); 85 | 86 | IEnumerator IEnumerable.GetEnumerator() => 87 | _handlers.GetEnumerator(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Events/NavigationErrorEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Events; 3 | using Prism.Navigation; 4 | 5 | namespace Prism.Events 6 | { 7 | public class NavigationErrorEvent : PubSubEvent 8 | { 9 | } 10 | 11 | public interface INavigationError 12 | { 13 | string NavigationUri { get; } 14 | INavigationParameters Parameters { get; } 15 | Exception Exception { get; } 16 | } 17 | 18 | internal class NavigationError : INavigationError 19 | { 20 | public string NavigationUri { get; set; } 21 | public INavigationParameters Parameters { get; set; } 22 | public Exception Exception { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Navigation/ErrorReportingNavigationService.cs: -------------------------------------------------------------------------------- 1 | using Prism.Behaviors; 2 | using Prism.Common; 3 | using Prism.Events; 4 | using Prism.Ioc; 5 | using Prism.Logging; 6 | using System; 7 | using System.Threading.Tasks; 8 | 9 | namespace Prism.Navigation 10 | { 11 | public class ErrorReportingNavigationService : PageNavigationService 12 | { 13 | private IEventAggregator EventAggregator { get; } 14 | 15 | public ErrorReportingNavigationService(IContainerExtension container, 16 | IApplicationProvider applicationProvider, 17 | IPageBehaviorFactory pageBehaviorFactory, 18 | IEventAggregator eventAggregator) 19 | : base(container, applicationProvider, pageBehaviorFactory) 20 | { 21 | EventAggregator = eventAggregator; 22 | } 23 | 24 | protected async override Task GoBackInternal(INavigationParameters parameters, bool? useModalNavigation, bool animated) 25 | { 26 | var result = await base.GoBackInternal(parameters, useModalNavigation, animated); 27 | 28 | if (result.Exception != null) 29 | { 30 | EventAggregator.GetEvent().Publish(new NavigationError 31 | { 32 | Exception = result.Exception, 33 | Parameters = parameters, 34 | NavigationUri = nameof(GoBackAsync) 35 | }); 36 | } 37 | 38 | return result; 39 | } 40 | 41 | protected override async Task GoBackToRootInternal(INavigationParameters parameters) 42 | { 43 | var result = await base.GoBackToRootInternal(parameters); 44 | 45 | if (result.Exception != null) 46 | { 47 | EventAggregator.GetEvent().Publish(new NavigationError 48 | { 49 | Exception = result.Exception, 50 | Parameters = parameters, 51 | NavigationUri = nameof(INavigationServiceExtensions.GoBackToRootAsync) 52 | }); 53 | } 54 | 55 | return result; 56 | } 57 | 58 | protected override async Task NavigateInternal(Uri uri, INavigationParameters parameters, bool? useModalNavigation, bool animated) 59 | { 60 | var result = await base.NavigateInternal(uri, parameters, useModalNavigation, animated); 61 | 62 | if (result.Exception != null) 63 | { 64 | EventAggregator.GetEvent().Publish( 65 | new NavigationError 66 | { 67 | Exception = result.Exception, 68 | Parameters = parameters, 69 | NavigationUri = uri.ToString() 70 | }); 71 | } 72 | 73 | return result; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Navigation/NavigationBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Forms.Extended.Navigation; 3 | using Prism.Navigation; 4 | 5 | namespace Prism.Navigation 6 | { 7 | public static class NavigationBuilderExtensions 8 | { 9 | public static NavigationBuilder Navigate(this INavigationService navigationService, string name) => 10 | new NavigationBuilder(navigationService, name); 11 | 12 | public static NavigationBuilder Navigate(this INavigationService navigationService, Uri uri) => 13 | new NavigationBuilder(navigationService, uri); 14 | 15 | public static NavigationBuilder GoBack(this INavigationService navigationService) => 16 | new NavigationBuilder(navigationService, NavigationInstruction.GoBack); 17 | 18 | public static NavigationBuilder GoBackToRoot(this INavigationService navigationService) => 19 | new NavigationBuilder(navigationService, NavigationInstruction.GoBackToRoot); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Navigation/NavigationInstruction.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Forms.Extended.Navigation 2 | { 3 | internal enum NavigationInstruction 4 | { 5 | Navigate, 6 | GoBack, 7 | GoBackToRoot 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Platform/PlatformSpecifics.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Prism.Platform 4 | { 5 | public static class PlatformSpecifics 6 | { 7 | public static readonly BindableProperty UseExplicitProperty = 8 | BindableProperty.CreateAttached("UseExplicit", typeof(bool), typeof(PlatformSpecifics), false); 9 | 10 | public static bool GetUseExplicit(BindableObject bindable) => 11 | (bool)bindable.GetValue(UseExplicitProperty); 12 | 13 | public static void SetUseExplicit(BindableObject bindable, bool value) => 14 | bindable.SetValue(UseExplicitProperty, value); 15 | } 16 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Prism.Forms.Extended.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;MonoAndroid90;Xamarin.iOS10 5 | Provides an extended PrismApplication with additional helpers. This can assist with capturing errors and debugging. Additional helpers exist to provide better use of Platform Specifics and styling. 6 | prism xamarin.forms forms extensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/PrismApplication.android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Android.Runtime; 4 | using Java.Lang; 5 | using Prism.Events; 6 | using Prism.Forms.Extended.Styles; 7 | using Prism.Ioc; 8 | using Prism.Logging; 9 | using Xamarin.Forms.Internals; 10 | 11 | namespace Prism 12 | { 13 | public abstract partial class PrismApplication 14 | { 15 | protected override void Initialize() 16 | { 17 | Resources = new DefaultResources(); 18 | Logger = new ConsoleLoggingService(); 19 | 20 | AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; 21 | 22 | Thread.DefaultUncaughtExceptionHandler = new ExceptHandler(TrackError); 23 | 24 | AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException; 25 | 26 | TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 27 | 28 | base.Initialize(); 29 | 30 | Logger = Container.Resolve(); 31 | Log.Listeners.Add(new FormsLogListener(Logger)); 32 | Container.Resolve().GetEvent().Subscribe(OnNavigationError); 33 | } 34 | 35 | private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs args) 36 | { 37 | TrackError(args.Exception, nameof(AndroidEnvironment_UnhandledExceptionRaiser)); 38 | } 39 | 40 | private class ExceptHandler : Java.Lang.Object, Thread.IUncaughtExceptionHandler 41 | { 42 | public delegate void TrackErrorHandler(System.Exception ex, string fromEvent, object errorObject = null); 43 | 44 | private TrackErrorHandler _handler { get; } 45 | 46 | public ExceptHandler(TrackErrorHandler handler) 47 | { 48 | _handler = handler; 49 | } 50 | 51 | public void UncaughtException(Thread t, Throwable e) 52 | { 53 | _handler(e.GetBaseException(), "Thread_DefaultUncaughtExceptionHandler"); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/PrismApplication.iosmac.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using ObjCRuntime; 4 | using Prism.Events; 5 | using Prism.Forms.Extended.Styles; 6 | using Prism.Ioc; 7 | using Prism.Logging; 8 | using Xamarin.Forms.Internals; 9 | 10 | namespace Prism 11 | { 12 | public abstract partial class PrismApplication 13 | { 14 | protected override void Initialize() 15 | { 16 | Resources = new DefaultResources(); 17 | Logger = new ConsoleLoggingService(); 18 | 19 | Runtime.MarshalObjectiveCException += Runtime_MarshalObjectiveCException; 20 | 21 | AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException; 22 | 23 | TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 24 | 25 | base.Initialize(); 26 | 27 | Logger = Container.Resolve(); 28 | Log.Listeners.Add(new FormsLogListener(Logger)); 29 | Container.Resolve().GetEvent().Subscribe(OnNavigationError); 30 | } 31 | 32 | private void Runtime_MarshalObjectiveCException(object sender, MarshalObjectiveCExceptionEventArgs args) 33 | { 34 | Console.WriteLine($"Encountered Marshal Objective-C Exception:\nMode: {args.ExceptionMode}\nException:\n{args.Exception}"); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/PrismApplication.netstandard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Prism.Events; 4 | using Prism.Forms.Extended.Styles; 5 | using Prism.Ioc; 6 | using Prism.Logging; 7 | using Xamarin.Forms.Internals; 8 | 9 | namespace Prism 10 | { 11 | public abstract partial class PrismApplication 12 | { 13 | protected override void Initialize() 14 | { 15 | Resources = new DefaultResources(); 16 | Logger = new ConsoleLoggingService(); 17 | 18 | AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException; 19 | 20 | TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 21 | 22 | base.Initialize(); 23 | 24 | Logger = Container.Resolve(); 25 | Log.Listeners.Add(new FormsLogListener(Logger)); 26 | Container.Resolve().GetEvent().Subscribe(OnNavigationError); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/Styles/DefaultResources.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace Prism.Forms.Extended.Styles 6 | { 7 | internal sealed class DefaultResources : ResourceDictionary 8 | { 9 | public DefaultResources() 10 | { 11 | var primary = Color.FromHex("#2196F3"); 12 | var primaryDark = Color.FromHex("#1976D2"); 13 | var primarylight = Color.FromHex("#BBDEFB"); 14 | var accent = Color.FromHex("#9E9E9E"); 15 | var navigationText = Color.FromHex("#FFFFFF"); 16 | var primaryText = Color.FromHex("#212121"); 17 | var secondaryText = Color.FromHex("#757575"); 18 | var dividerColor = Color.FromHex("#BDBDBD"); 19 | 20 | Add("Primary", primary); 21 | Add("PrimaryDark", primaryDark); 22 | Add("PrimaryLight", primarylight); 23 | Add("Accent", accent); 24 | Add("NavigationText", navigationText); 25 | Add("PrimaryText", primaryText); 26 | Add("SecondaryText", secondaryText); 27 | Add("DividerColor", dividerColor); 28 | 29 | var tabbedStyle = new Style(typeof(TabbedPage)); 30 | tabbedStyle.Setters.Add(new Setter { Property = TabbedPage.BarBackgroundColorProperty, Value = primary }); 31 | tabbedStyle.Setters.Add(new Setter { Property = TabbedPage.BarTextColorProperty, Value = navigationText }); 32 | 33 | var navigationStyle = new Style(typeof(NavigationPage)); 34 | navigationStyle.Setters.Add(new Setter { Property = NavigationPage.BarBackgroundColorProperty, Value = primary }); 35 | navigationStyle.Setters.Add(new Setter { Property = NavigationPage.BarTextColorProperty, Value = navigationText }); 36 | 37 | var button = new Style(typeof(Button)); 38 | button.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = primaryDark }); 39 | button.Setters.Add(new Setter { Property = Button.TextColorProperty, Value = navigationText }); 40 | 41 | var label = new Style(typeof(Label)); 42 | label.Setters.Add(new Setter { Property = Label.TextColorProperty, Value = primaryText }); 43 | 44 | Add(tabbedStyle); 45 | Add(navigationStyle); 46 | Add(button); 47 | Add(label); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/Prism.Forms.Extended/ViewModels/DefaultViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Mvvm; 2 | using Prism.Navigation; 3 | 4 | namespace Prism.Forms.Extended.ViewModels 5 | { 6 | internal class DefaultViewModel : BindableBase, IInitialize 7 | { 8 | private string _title; 9 | public string Title 10 | { 11 | get => _title; 12 | set => SetProperty(ref _title, value); 13 | } 14 | 15 | public void Initialize(INavigationParameters parameters) 16 | { 17 | if (parameters.TryGetValue("Title", out string title) || 18 | parameters.TryGetValue("title", out title)) 19 | { 20 | Title = title; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/ConcreteAwareOverrideProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace Prism.Microsoft.DependencyInjection.Extensions 6 | { 7 | internal class ConcreteAwareOverrideProvider : IServiceProvider 8 | { 9 | private IServiceProvider _rootProvider { get; } 10 | private IServiceCollection _services { get; } 11 | private (Type type, object instance)[] _overrides { get; } 12 | 13 | public ConcreteAwareOverrideProvider(IServiceProvider serviceProvider, IServiceCollection services, (Type type, object instance)[] overrides) 14 | { 15 | _rootProvider = serviceProvider; 16 | _overrides = overrides; 17 | } 18 | 19 | public object GetService(Type serviceType) 20 | { 21 | if (!serviceType.IsAbstract && serviceType.IsClass && serviceType != typeof(object)) 22 | { 23 | return BuildInstance(serviceType); 24 | } 25 | 26 | var serviceDescriptor = _services.LastOrDefault(x => x.ServiceType == serviceType); 27 | 28 | if (serviceDescriptor?.ImplementationType is null) 29 | return _rootProvider.GetService(serviceType); 30 | 31 | var implType = serviceDescriptor.ImplementationType; 32 | return BuildInstance(implType); 33 | } 34 | 35 | private object BuildInstance(Type implType) 36 | { 37 | var constructors = implType.GetConstructors(); 38 | 39 | if (constructors is null || !constructors.Any()) 40 | return Activator.CreateInstance(implType); 41 | 42 | var ctor = constructors.OrderByDescending(x => x.GetParameters().Length).First(); 43 | var parameters = ctor.GetParameters().Select(x => 44 | { 45 | (var t, var instance) = _overrides.FirstOrDefault(o => x.ParameterType == o.type); 46 | if (t != null) 47 | { 48 | return instance; 49 | } 50 | 51 | return _rootProvider.GetService(x.ParameterType); 52 | }).ToArray(); 53 | 54 | return ctor.Invoke(parameters); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/ConcreteAwareServiceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace Prism.Microsoft.DependencyInjection 6 | { 7 | public class ConcreteAwareServiceProvider : IServiceProvider 8 | { 9 | private bool _isScoped { get; } 10 | 11 | public ConcreteAwareServiceProvider(IServiceProvider serviceProvider) 12 | { 13 | ServiceProvider = serviceProvider; 14 | } 15 | 16 | public ConcreteAwareServiceProvider(IServiceScope serviceScope) 17 | { 18 | ServiceProvider = serviceScope.ServiceProvider; 19 | _isScoped = true; 20 | } 21 | 22 | public IServiceProvider ServiceProvider { get; } 23 | 24 | public object GetService(Type serviceType) => 25 | ServiceProvider.GetService(serviceType) ?? GetConcreteImplementation(serviceType); 26 | 27 | private object GetConcreteImplementation(Type serviceType) 28 | { 29 | if (serviceType.IsInterface || serviceType.IsAbstract) return null; 30 | 31 | if (serviceType.IsClass) 32 | { 33 | if (_isScoped) 34 | BuildConcreteImplementation(serviceType); 35 | 36 | PrismContainerExtension.Current.Register(serviceType, serviceType); 37 | var sp = PrismContainerExtension.Current.ServiceCollection().BuildServiceProvider(); 38 | return sp.GetService(serviceType); 39 | } 40 | 41 | if (serviceType.IsValueType) 42 | { 43 | return Activator.CreateInstance(serviceType); 44 | } 45 | 46 | return null; 47 | } 48 | 49 | private object BuildConcreteImplementation(Type serviceType) 50 | { 51 | var constructors = serviceType.GetConstructors(); 52 | 53 | if (!constructors.Any()) 54 | return Activator.CreateInstance(serviceType); 55 | 56 | var ctor = constructors.OrderByDescending(x => x.GetParameters().Length).First(); 57 | 58 | var parameters = ctor.GetParameters().Select(p => GetService(p.ParameterType)).ToArray(); 59 | return ctor.Invoke(parameters); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/ConcreteAwareServiceScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace Prism.Microsoft.DependencyInjection 5 | { 6 | public class ConcreteAwareServiceScope : IServiceScope 7 | { 8 | public ConcreteAwareServiceScope(IServiceScope serviceScope) 9 | { 10 | ServiceProvider = new ConcreteAwareServiceProvider(serviceScope.ServiceProvider); 11 | } 12 | 13 | public IServiceProvider ServiceProvider { get; } 14 | 15 | #region IDisposable Support 16 | 17 | 18 | protected virtual void Dispose(bool disposing) 19 | { 20 | 21 | } 22 | 23 | // This code added to correctly implement the disposable pattern. 24 | public void Dispose() 25 | { 26 | Dispose(true); 27 | } 28 | #endregion 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/Internals/PrismContainerExtensionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Prism.Container.Extensions.Internals; 4 | using Prism.Ioc; 5 | 6 | namespace Prism.Microsoft.DependencyInjection.Internals 7 | { 8 | [EditorBrowsable(EditorBrowsableState.Never)] 9 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 10 | public sealed class PrismContainerExtensionAttribute : ContainerExtensionAttribute 11 | { 12 | protected override IContainerExtension Init() => PrismContainerExtension.Init(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/MicrsoftDependencyInjectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Runtime.CompilerServices; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Prism.Ioc; 6 | 7 | [assembly: InternalsVisibleTo("Prism.Microsoft.DependencyInjection.Extensions.Tests")] 8 | [assembly: InternalsVisibleTo("Prism.Microsoft.DependencyInjection.Forms.Extended.Tests")] 9 | [assembly: InternalsVisibleTo("Shiny.Prism.Tests")] 10 | namespace Prism.Microsoft.DependencyInjection 11 | { 12 | public static class MicrsoftDependencyInjectionExtensions 13 | { 14 | public static IServiceCollection ServiceCollection(this IContainerRegistry containerRegistry) 15 | { 16 | if (containerRegistry is PrismContainerExtension pce) 17 | { 18 | return pce.Services; 19 | } 20 | 21 | throw new NotImplementedException("IContainerRegistry must be implmented from the concrete type PrismContainerExtension"); 22 | } 23 | 24 | internal static object GetOrConstructService(this IServiceProvider provider, Type type, params (Type Type, object Instance)[] parameters) 25 | { 26 | var instance = provider.GetService(type); 27 | if (instance is null && !type.IsInterface && !type.IsAbstract) 28 | { 29 | var ctor = type.GetConstructors().OrderByDescending(x => x.GetParameters().Length).FirstOrDefault(); 30 | if (ctor is null) 31 | throw new NullReferenceException($"Could not locate a public constructor for {type.FullName}"); 32 | 33 | var ctorParameters = ctor.GetParameters(); 34 | var args = ctor.GetParameters().Select(x => 35 | { 36 | object arg = parameters.FirstOrDefault(p => x.ParameterType.IsAssignableFrom(p.Instance.GetType())).Instance; 37 | if (arg != null) 38 | return arg; 39 | 40 | return provider.GetService(x.ParameterType); 41 | }); 42 | return ctor.Invoke(args.ToArray()); 43 | } 44 | return instance; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/Prism.Microsoft.DependencyInjection.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | prism di iserviceprovider iservicecollection microsoft-dependencyinjection 6 | dansiegel 7 | Prism Container Extensions for the Microsoft.Extensions.DependencyInjection implementations of IServiceCollection / IServiceProvider. NOTE: This is an EXPERIMENTAL Container! While this may basic basic tests, this container may still have unknown issues as the Microsoft.Extensions.DependencyInjection package inheriently does not support either Named Types or Container Mutability. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Thank you for using the Prism.Container.Extensions! 2 | 3 | Please note that as of Prism 8, this library is in maintenance mode. The extensions first introduced here, are now mostly included out of the box with Prism 8 with the exception of the IServiceCollection & ShinyLib support. This support is better provided via the Prism.Magician. The Magician is available to all GitHub sponsors for their use, and available via corporate license through AvantiPoint. 4 | 5 | Docs are available at https://prismplugins.com 6 | 7 | ** SUPPORT ** 8 | 9 | This is an open source project and is provided as is. If you require support please contact AvantiPoint for a Support Contract. 10 | 11 | ** IMPORTANT ** 12 | 13 | This is an experimental package. There may be numerous issues with it and it is not recommended that you use this for production. This uses the Microsoft.Extensions.DependencyInjection package as the Prism Container. Do NOT use this with any other container packages! 14 | 15 | ** NOTE ** 16 | 17 | This package is meant to replace the container package shipped by the Prism team for the platform of your choice. You should reference the base platform package and update your app from PrismApplication to instead inherit from PrismApplicationBase and add the following code to your app: 18 | 19 | protected override IContainerExtension CreateContainerExtension() 20 | { 21 | return ContainerLocator.Current; 22 | } 23 | 24 | If building a Xamarin.Forms app you may instead use Prism.Forms.Extended which requires no changes to your code. -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/build/PreserveContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using Prism.Microsoft.DependencyInjection.Internals; 2 | 3 | // Force the assembly into the App Domain 4 | [assembly: PrismContainerExtension] 5 | -------------------------------------------------------------------------------- /src/Prism.Microsoft.DependencyInjection.Extensions/build/Prism.Microsoft.DependencyInjection.Extensions.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/ContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Prism.Ioc; 4 | using Unity; 5 | 6 | namespace Prism.Unity 7 | { 8 | partial class UnityContainerExtension : IServiceScopeFactory 9 | { 10 | public UnityContainerExtension(IUnityContainer container) 11 | { 12 | Instance = container; 13 | string currentContainer = "CurrentContainer"; 14 | Instance.RegisterInstance(currentContainer, this); 15 | Instance.RegisterFactory(typeof(IContainerExtension), c => c.Resolve(currentContainer)); 16 | Instance.RegisterFactory(typeof(IContainerProvider), c => c.Resolve(currentContainer)); 17 | Instance.RegisterFactory(typeof(IServiceScopeFactory), c => c.Resolve(currentContainer)); 18 | Instance.RegisterFactory(typeof(IServiceProvider), c => new UnityProvider(c)); 19 | } 20 | 21 | IServiceScope IServiceScopeFactory.CreateScope() 22 | { 23 | var scope = CreateScopeInternal(); 24 | return new PrismServiceScope(scope); 25 | } 26 | 27 | private class UnityProvider : IServiceProvider 28 | { 29 | private IUnityContainer _container { get; } 30 | 31 | public UnityProvider(IUnityContainer container) 32 | { 33 | _container = container; 34 | } 35 | 36 | public object GetService(Type serviceType) 37 | { 38 | try 39 | { 40 | return _container.Resolve(serviceType); 41 | } 42 | catch 43 | { 44 | return null; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/Internals/PrismContainerExtensionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Prism.Container.Extensions.Internals; 4 | using Prism.Ioc; 5 | 6 | namespace Prism.Unity.Internals 7 | { 8 | [EditorBrowsable(EditorBrowsableState.Never)] 9 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 10 | public sealed class PrismContainerExtensionAttribute : ContainerExtensionAttribute 11 | { 12 | protected override IContainerExtension Init() => PrismContainerExtension.Init(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/Prism.Unity.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Provides an extended PrismApplication with additional helpers. This can assist with capturing errors and debugging. Additional helpers exist to provide better use of Platform Specifics and styling. 6 | $(DefineConstants);ContainerExtensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/PrismContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Ioc; 3 | using Unity; 4 | 5 | namespace Prism.Unity 6 | { 7 | public static class PrismContainerExtension 8 | { 9 | public static IContainerExtension Current => ContainerLocator.Current ?? Init(); 10 | 11 | public static IContainerExtension Init() => 12 | Init(new UnityContainer()); 13 | 14 | public static IContainerExtension Init(IUnityContainer container) 15 | { 16 | if (ContainerLocator.Current != null) 17 | throw new NotSupportedException("The PrismContainerExtension has already been initialized."); 18 | 19 | var extension = new UnityContainerExtension(container); 20 | ContainerLocator.SetContainerExtension(() => extension); 21 | return ContainerLocator.Current; 22 | } 23 | 24 | internal static void Reset() 25 | { 26 | ContainerLocator.ResetContainer(); 27 | GC.Collect(int.MaxValue, GCCollectionMode.Forced); 28 | GC.WaitForFullGCComplete(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Prism.Unity.Extensions.Tests")] 4 | [assembly: InternalsVisibleTo("Prism.Unity.Forms.Extended.Tests")] 5 | [assembly: InternalsVisibleTo("Shiny.Prism.Tests")] 6 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Thank you for using the Prism.Container.Extensions! 2 | 3 | Please note that as of Prism 8, this library is in maintenance mode. The extensions first introduced here, are now mostly included out of the box with Prism 8 with the exception of the IServiceCollection & ShinyLib support. This support is better provided via the Prism.Magician. The Magician is available to all GitHub sponsors for their use, and available via corporate license through AvantiPoint. 4 | 5 | Docs are available at https://prismplugins.com 6 | 7 | ** SUPPORT ** 8 | 9 | This is an open source project and is provided as is. If you require support please contact AvantiPoint for a Support Contract. 10 | 11 | ** NOTE ** 12 | 13 | This package is meant to replace the container package shipped by the Prism team for the platform of your choice. You should reference the base platform package and update your app from PrismApplication to instead inherit from PrismApplicationBase and add the following code to your app: 14 | 15 | protected override IContainerExtension CreateContainerExtension() 16 | { 17 | return ContainerLocator.Current; 18 | } 19 | 20 | If building a Xamarin.Forms app you may instead use Prism.Forms.Extended which requires no changes to your code. 21 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/build/PreserveContainerExtension.cs: -------------------------------------------------------------------------------- 1 | using Prism.Unity.Internals; 2 | 3 | // Force the assembly into the App Domain 4 | [assembly: PrismContainerExtension] 5 | -------------------------------------------------------------------------------- /src/Prism.Unity.Extensions/build/Prism.Unity.Extensions.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/IModuleCatalogExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using Prism.Modularity; 6 | 7 | namespace Shiny.Prism.Modularity 8 | { 9 | [EditorBrowsable(EditorBrowsableState.Never)] 10 | public static class IModuleCatalogExtensions 11 | { 12 | [EditorBrowsable(EditorBrowsableState.Never)] 13 | public static bool HasStartupModules(this IModuleCatalog moduleCatalog, out IEnumerable startupModules) 14 | { 15 | startupModules = FilterForStartup(moduleCatalog.Modules); 16 | 17 | if (startupModules.Any()) 18 | { 19 | startupModules = moduleCatalog.CompleteListWithDependencies(startupModules); 20 | } 21 | 22 | return startupModules.Any(); 23 | } 24 | 25 | private static IEnumerable FilterForStartup(IEnumerable modules) => 26 | modules.Where(m => Type.GetType(m.ModuleType) 27 | .GetInterfaces() 28 | .Any(x => x == typeof(IStartupModule)) 29 | && m.InitializationMode == InitializationMode.WhenAvailable); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/IShinyModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Prism.Modularity; 4 | 5 | namespace Shiny.Prism.Modularity 6 | { 7 | public interface IShinyModule : IModule 8 | { 9 | void ConfigureApp(IServiceProvider provider); 10 | void ConfigureServices(IServiceCollection services); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/IShinyPrismModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | using Prism.Modularity; 2 | 3 | namespace Shiny.Prism.Modularity 4 | { 5 | internal interface IShinyPrismModuleInitializer 6 | { 7 | IModule LoadShinyModule(IModuleInfo moduleInfo); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/IStartupModule.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Modularity 2 | { 3 | public interface IStartupModule : IShinyModule 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/ShinyModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Prism.Ioc; 6 | using Prism.Modularity; 7 | 8 | namespace Shiny.Prism.Modularity 9 | { 10 | public abstract class ShinyModule : IShinyModule 11 | { 12 | protected virtual void ConfigureApp(IServiceProvider provider) { } 13 | 14 | void IShinyModule.ConfigureApp(IServiceProvider provider) => ConfigureApp(provider); 15 | 16 | protected abstract void ConfigureServices(IServiceCollection services); 17 | 18 | void IShinyModule.ConfigureServices(IServiceCollection services) => ConfigureServices(services); 19 | 20 | protected virtual void OnInitialized(IContainerProvider containerProvider) { } 21 | 22 | void IModule.OnInitialized(IContainerProvider containerProvider) => OnInitialized(containerProvider); 23 | 24 | protected abstract void RegisterTypes(IContainerRegistry containerRegistry); 25 | 26 | void IModule.RegisterTypes(IContainerRegistry containerRegistry) => RegisterTypes(containerRegistry); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/ShinyPrismModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Prism.Ioc; 5 | using Prism.Modularity; 6 | 7 | namespace Shiny.Prism.Modularity 8 | { 9 | internal class ShinyPrismModuleInitializer : IModuleInitializer, IShinyPrismModuleInitializer 10 | { 11 | private IContainerExtension _container { get; } 12 | 13 | private List _loadedShinyModules { get; } 14 | 15 | public ShinyPrismModuleInitializer(IContainerExtension container) 16 | { 17 | _container = container; 18 | _loadedShinyModules = new List(); 19 | } 20 | 21 | public void Initialize(IModuleInfo moduleInfo) 22 | { 23 | var module = LoadShinyModule(moduleInfo); 24 | 25 | if (module != null) 26 | { 27 | module.RegisterTypes(_container); 28 | module.OnInitialized(_container); 29 | } 30 | } 31 | 32 | public IModule LoadShinyModule(IModuleInfo moduleInfo) 33 | { 34 | var module = CreateModule(Type.GetType(moduleInfo.ModuleType, true)); 35 | 36 | if (_loadedShinyModules.Contains(moduleInfo.ModuleName)) return module; 37 | 38 | if (module is IShinyModule shinyModule) 39 | { 40 | var services = new ServiceCollection(); 41 | shinyModule.ConfigureServices(services); 42 | var sp = _container.CreateServiceProvider(services); 43 | shinyModule.ConfigureApp(sp); 44 | 45 | _loadedShinyModules.Add(moduleInfo.ModuleName); 46 | } 47 | 48 | return module; 49 | } 50 | 51 | private IModule CreateModule(Type moduleType) => 52 | (IModule)_container.Resolve(moduleType); 53 | } 54 | 55 | internal static class IShinyPrismModuleInitailzierExtensions 56 | { 57 | public static void LoadShinyModules(this IShinyPrismModuleInitializer initializer, IEnumerable modules) 58 | { 59 | foreach (var module in modules) 60 | { 61 | initializer.LoadShinyModule(module); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Modularity/StartupModule.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Modularity 2 | { 3 | public abstract class StartupModule : ShinyModule, IStartupModule 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Navigation/INavigationServiceDelegate.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Navigation 2 | { 3 | public interface INavigationServiceDelegate : INavigationService 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Navigation/NavigationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Prism.Common; 4 | using Prism.Navigation; 5 | 6 | namespace Shiny 7 | { 8 | public static class NavigationExtensions 9 | { 10 | public static void UseNavigationDelegate(this IServiceCollection services) 11 | { 12 | services.AddSingleton(); 13 | if (!services.Any(x => x.ServiceType == typeof(IApplicationProvider))) 14 | { 15 | services.AddSingleton(); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Shiny.Prism/PrismStartup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Logging; 5 | using Prism.Container.Extensions.Internals; 6 | using Prism.Ioc; 7 | using Prism.Modularity; 8 | using Shiny.Prism.Modularity; 9 | 10 | namespace Shiny.Prism 11 | { 12 | public abstract class PrismStartup : IShinyStartup 13 | { 14 | protected PrismStartup() 15 | { 16 | } 17 | 18 | protected PrismStartup(IContainerExtension container) 19 | { 20 | WithContainer(container); 21 | } 22 | 23 | protected virtual void ConfigureLogging(ILoggingBuilder builder, IPlatform platform) { } 24 | 25 | protected abstract void ConfigureServices(IServiceCollection services, IPlatform platform); 26 | 27 | protected virtual void RegisterServices(IContainerRegistry containerRegistry) { } 28 | 29 | void IShinyStartup.ConfigureLogging(ILoggingBuilder builder, IPlatform platform) => 30 | ConfigureLogging(builder, platform); 31 | 32 | void IShinyStartup.ConfigureServices(IServiceCollection services, IPlatform platform) 33 | { 34 | ConfigureServices(services, platform); 35 | services.RegisterPrismCoreServices(); 36 | services.Remove(services.First(x => x.ServiceType == typeof(IModuleInitializer))); 37 | services.AddSingleton(); 38 | } 39 | 40 | IServiceProvider IShinyStartup.CreateServiceProvider(IServiceCollection services) 41 | { 42 | var container = ContainerLocationHelper.LocateContainer(CreateContainerExtension()) ?? 43 | throw new NullReferenceException("Call PrismContainerExtension.Init() prior to initializing PrismApplication"); 44 | 45 | var sp = container.CreateServiceProvider(services); 46 | RegisterServices(container); 47 | 48 | var moduleCatalog = container.Resolve(); 49 | ConfigureModuleCatalog(moduleCatalog); 50 | 51 | if (moduleCatalog.Modules.Any() && moduleCatalog.HasStartupModules(out var startupModules)) 52 | { 53 | var moduleInitializer = container.Resolve() as IShinyPrismModuleInitializer; 54 | moduleInitializer.LoadShinyModules(startupModules); 55 | } 56 | 57 | return sp; 58 | } 59 | 60 | protected virtual IContainerExtension CreateContainerExtension() 61 | { 62 | return null; 63 | } 64 | 65 | public IShinyStartup WithContainer(IContainerExtension container) 66 | { 67 | ContainerLocator.SetContainerExtension(() => container); 68 | var _ = ContainerLocator.Container; 69 | return this; 70 | } 71 | 72 | protected virtual void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Shiny.Prism/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Shiny.Prism.Tests")] 4 | -------------------------------------------------------------------------------- /src/Shiny.Prism/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Thank you for using the Prism.Container.Extensions! 2 | 3 | Please note that as of Prism 8, this library is in maintenance mode. The extensions first introduced here, are now mostly included out of the box with Prism 8 with the exception of the IServiceCollection & ShinyLib support. This support is better provided via the Prism.Magician. The Magician is available to all GitHub sponsors for their use, and available via corporate license through AvantiPoint. 4 | 5 | Docs are available at https://prismplugins.com 6 | 7 | ** SUPPORT ** 8 | 9 | This is an open source project and is provided as is. If you require support please contact AvantiPoint for a Support Contract. 10 | 11 | ** NOTE ** 12 | 13 | This package is meant to be used with one of the Container Extensions that are part of this project: 14 | 15 | - Prism.DryIoc.Extensions 16 | - Prism.Microsoft.DependencyInjection.Extensions 17 | - Prism.Unity.Extensions 18 | 19 | You should not be using a container package from Prism directly such as Prism.DryIoc.Forms or Prism.Unity.Forms. Be sure to use Prism.Forms.Extended along with one of the above container extensions to properly support Shiny.Prism. Alternatively you may use Prism.Forms along with one of the above container extensions. In that case you will need to update your app to inherit from PrismApplicationBase and add the following override to your App class: 20 | 21 | protected override IContainerExtension CreateContainerExtension() 22 | { 23 | return ContainerLocator.Current; 24 | } -------------------------------------------------------------------------------- /src/Shiny.Prism/Shiny.Prism.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Provides a seemless wrapper for Prism apps using Shiny 6 | 8.0 7 | prism shiny background 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Mocks/Bar.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Container.Extensions.Tests.Mocks 2 | { 3 | public class Bar : IBar 4 | { 5 | public Bar(IFoo foo) 6 | { 7 | Foo = foo; 8 | } 9 | 10 | public IFoo Foo { get; } 11 | 12 | public string Message { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Mocks/Foo.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Container.Extensions.Tests.Mocks 2 | { 3 | public class Foo : IFoo 4 | { 5 | public string Message { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Mocks/FooBarImpl.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Container.Extensions.Tests.Mocks 2 | { 3 | public class FooBarImpl : IFoo, IBar 4 | { 5 | public string Message { get; set; } 6 | public IFoo Foo => this; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Mocks/IBar.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Container.Extensions.Tests.Mocks 2 | { 3 | public interface IBar 4 | { 5 | IFoo Foo { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Mocks/IFoo.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Container.Extensions.Tests.Mocks 2 | { 3 | public interface IFoo 4 | { 5 | string Message { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Mocks/Prism.Container.Extensions.Mocks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | false 6 | Prism.Container.Extensions.Tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Shared.Tests/Mocks/GenericService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Prism.Container.Extensions.Shared.Mocks 6 | { 7 | public class GenericService : IGenericService 8 | { 9 | public string Name { get; set; } 10 | } 11 | 12 | public class AltGenericService : IGenericService 13 | { 14 | public string Name { get; set; } 15 | } 16 | 17 | public interface IGenericService 18 | { 19 | string Name { get; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Shared.Tests/Mocks/MockDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | using System.Text; 5 | using JetBrains.Annotations; 6 | using Microsoft.EntityFrameworkCore; 7 | 8 | namespace Prism.Container.Extensions.Shared.Mocks 9 | { 10 | public class MockDbContext : DbContext 11 | { 12 | public MockDbContext([NotNull] DbContextOptions options) 13 | : base(options) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Shared.Tests/Prism.Container.Extensions.Shared.Tests.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | a000e151-d04b-4f18-92a9-173e60975fbc 7 | 8 | 9 | Prism.Container.Extensions.Shared 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Shared.Tests/Prism.Container.Extensions.Shared.Tests.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a000e151-d04b-4f18-92a9-173e60975fbc 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/Prism.Container.Extensions.Shared.Tests/Tests/SharedTestCollection.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace Prism.Container.Extensions.Shared.Tests 4 | { 5 | public class SharedTests { } 6 | 7 | [CollectionDefinition(nameof(SharedTests), DisableParallelization = true)] 8 | public class SharedTestCollection : ICollectionFixture 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Extensions.Tests/Prism.DryIoc.Extensions.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | $(DefineConstants);DRYIOC 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Forms.Extended.Tests/Prism.DryIoc.Forms.Extended.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | Prism.DryIoc.Forms.Extended 7 | $(DefineConstants);DRYIOC 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/AppMock.xaml: -------------------------------------------------------------------------------- 1 |  2 | 7 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/AppMock.xaml.cs: -------------------------------------------------------------------------------- 1 | using Prism.Forms.Extended.Mocks.Views; 2 | using Prism.Ioc; 3 | using Prism.Navigation; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Xaml; 6 | 7 | namespace Prism.Forms.Extended.Mocks 8 | { 9 | [XamlCompilation(XamlCompilationOptions.Compile)] 10 | public partial class AppMock : PrismApplication 11 | { 12 | public AppMock() 13 | { 14 | 15 | } 16 | 17 | public new INavigationService NavigationService => base.NavigationService; 18 | 19 | protected override void OnInitialized() 20 | { 21 | InitializeComponent(); 22 | } 23 | 24 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 25 | { 26 | containerRegistry.RegisterForNavigation(); 27 | containerRegistry.RegisterForNavigation(); 28 | containerRegistry.RegisterForNavigation(); 29 | containerRegistry.RegisterForNavigation(); 30 | containerRegistry.RegisterForNavigation(); 31 | containerRegistry.RegisterForNavigation(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/ViewModels/ViewAViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Prism.Forms.Extended.Mocks.Views; 5 | using Prism.Navigation; 6 | 7 | namespace Prism.Forms.Extended.Mocks.ViewModels 8 | { 9 | public class ViewAViewModel 10 | { 11 | public INavigationService NavigationService { get; } 12 | 13 | public ViewAViewModel(INavigationService navigationService) 14 | { 15 | NavigationService = navigationService; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/ViewModels/ViewBViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Navigation; 2 | 3 | namespace Prism.Forms.Extended.Mocks.ViewModels 4 | { 5 | public class ViewBViewModel 6 | { 7 | public INavigationService NavigationService { get; } 8 | 9 | public ViewBViewModel(INavigationService navigationService) 10 | { 11 | NavigationService = navigationService; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/ViewModels/ViewCViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Navigation; 2 | 3 | namespace Prism.Forms.Extended.Mocks.ViewModels 4 | { 5 | public class ViewCViewModel 6 | { 7 | public INavigationService NavigationService { get; } 8 | 9 | public ViewCViewModel(INavigationService navigationService) 10 | { 11 | NavigationService = navigationService; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/ViewModels/ViewDViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Navigation; 2 | 3 | namespace Prism.Forms.Extended.Mocks.ViewModels 4 | { 5 | public class ViewDViewModel 6 | { 7 | public INavigationService NavigationService { get; } 8 | 9 | public ViewDViewModel(INavigationService navigationService) 10 | { 11 | NavigationService = navigationService; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/Views/ViewA.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Prism.Forms.Extended.Mocks.Views 4 | { 5 | public class ViewA : ContentPage 6 | { 7 | public ViewA() 8 | { 9 | Title = "ViewA"; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/Views/ViewB.cs: -------------------------------------------------------------------------------- 1 | using Prism.Platform; 2 | using Xamarin.Forms; 3 | 4 | namespace Prism.Forms.Extended.Mocks.Views 5 | { 6 | public class ViewB : ContentPage 7 | { 8 | public ViewB() 9 | { 10 | Title = "ViewB"; 11 | PlatformSpecifics.SetUseExplicit(this, true); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/Views/ViewC.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Prism.Forms.Extended.Mocks.Views 4 | { 5 | public class ViewC : ContentPage 6 | { 7 | public ViewC() 8 | { 9 | Title = "ViewC"; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/Views/ViewD.xaml: -------------------------------------------------------------------------------- 1 |  2 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Mocks/Views/ViewD.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace Prism.Forms.Extended.Mocks.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class ViewD : ContentPage 14 | { 15 | public ViewD() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Prism.Forms.Extended.Mocks.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | e13e43d5-6a03-401c-b7e6-298e829e5a2f 7 | 8 | 9 | Prism.Forms.Extended 10 | 11 | 12 | 13 | Code 14 | AppMock.xaml 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ViewD.xaml 23 | Code 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Designer 36 | MSBuild:UpdateDesignTimeXaml 37 | 38 | 39 | 40 | 41 | Designer 42 | MSBuild:Compile 43 | 44 | 45 | -------------------------------------------------------------------------------- /tests/Prism.Forms.Extended.Mocks/Prism.Forms.Extended.Mocks.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | e13e43d5-6a03-401c-b7e6-298e829e5a2f 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/Prism.Microsoft.DependencyInjection.Extensions.Forms.Tests/Prism.Microsoft.DependencyInjection.Forms.Extended.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | $(DefineConstants);MICROSOFT_DI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/Prism.Microsoft.DependencyInjection.Extensions.Tests/Prism.Microsoft.DependencyInjection.Extensions.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | $(DefineConstants);MICROSOFT_DI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/Prism.Unity.Extensions.Tests/Prism.Unity.Extensions.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | $(DefineConstants);UNITY 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/Prism.Unity.Forms.Extended.Tests/Prism.Unity.Forms.Extended.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | $(DefineConstants);UNITY 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Delegates/MockBeaconDelegate.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Threading.Tasks; 3 | //using Shiny.Beacons; 4 | 5 | //namespace Shiny.Prism.Mocks.Delegates 6 | //{ 7 | // public class MockBeaconDelegate : IBeaconDelegate 8 | // { 9 | // public Task OnStatusChanged(BeaconRegionState newStatus, BeaconRegion region) 10 | // { 11 | // throw new NotImplementedException(); 12 | // } 13 | // } 14 | //} 15 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Delegates/MockBleAdapterDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shiny.BluetoothLE; 3 | 4 | namespace Shiny.Prism.Mocks.Delegates 5 | { 6 | //public class MockBleAdapterDelegate : IBleAdapterDelegate 7 | //{ 8 | // public void OnBleAdapterStateChanged(AccessState state) 9 | // { 10 | // throw new NotImplementedException(); 11 | // } 12 | //} 13 | } 14 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Delegates/MockGeofenceDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Shiny.Locations; 4 | 5 | namespace Shiny.Prism.Mocks.Delegates 6 | { 7 | public class MockGeofenceDelegate : IGeofenceDelegate 8 | { 9 | public Task OnStatusChanged(GeofenceState newStatus, GeofenceRegion region) 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Delegates/MockGpsDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Shiny.Locations; 4 | 5 | namespace Shiny.Prism.Mocks.Delegates 6 | { 7 | public class MockGpsDelegate : IGpsDelegate 8 | { 9 | public Task OnReading(IGpsReading reading) 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/MockModuleStartup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Prism.Modularity; 5 | using Xunit.Abstractions; 6 | 7 | namespace Shiny.Prism.Mocks.Modularity 8 | { 9 | public class MockModuleStartup : MockStartup 10 | { 11 | public MockModuleStartup(ITestOutputHelper testOutputHelper) 12 | : base(testOutputHelper) 13 | { 14 | } 15 | 16 | protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) 17 | { 18 | moduleCatalog.AddModule(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/MockShinyPrismModule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Prism.Ioc; 3 | using Shiny.Prism.Mocks.Modularity.Services; 4 | using Shiny.Prism.Modularity; 5 | 6 | namespace Shiny.Prism.Mocks.Modularity 7 | { 8 | public class MockShinyPrismModule : StartupModule 9 | { 10 | protected override void ConfigureServices(IServiceCollection services) 11 | { 12 | services.AddTransient(); 13 | } 14 | 15 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 16 | { 17 | containerRegistry.Register(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/Services/IMockModuleServiceA.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Mocks.Modularity.Services 2 | { 3 | public interface IMockModuleServiceA 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/Services/IMockModuleServiceB.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Mocks.Modularity.Services 2 | { 3 | public interface IMockModuleServiceB 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/Services/MockModuleServiceA.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Mocks.Modularity.Services 2 | { 3 | public class MockModuleServiceA : IMockModuleServiceA 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/Modularity/Services/MockModuleServiceB.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Mocks.Modularity.Services 2 | { 3 | public class MockModuleServiceB : IMockModuleServiceB 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Mocks/ShinyPrismTestHost.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reactive.Subjects; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Shiny.Infrastructure; 5 | using Shiny.Jobs; 6 | using Shiny.Net; 7 | using Shiny.Power; 8 | using Shiny.Settings; 9 | using Shiny.Testing; 10 | using Shiny.Testing.Jobs; 11 | using Shiny.Testing.Net; 12 | using Shiny.Testing.Power; 13 | using Shiny.Testing.Settings; 14 | using Xunit.Abstractions; 15 | 16 | namespace Shiny.Prism.Mocks 17 | { 18 | class ShinyPrismTestHost : TestPlatform 19 | { 20 | private readonly Action _platformBuild; 21 | 22 | private ShinyPrismTestHost(Action platformBuild) 23 | { 24 | _platformBuild = platformBuild; 25 | } 26 | 27 | public static void Init(ITestOutputHelper testOutputHelper) => Init(new MockStartup(testOutputHelper)); 28 | 29 | public static void Init(IShinyStartup startup = null, Action platformBuild = null) 30 | { 31 | ShinyHost.Init(new ShinyPrismTestHost(platformBuild), startup); 32 | } 33 | 34 | public override void Register(IServiceCollection services) 35 | { 36 | base.Register(services); 37 | services.AddSingleton(); 38 | services.AddSingleton(); 39 | services.AddSingleton(); 40 | services.AddSingleton(); 41 | services.AddSingleton(); 42 | _platformBuild?.Invoke(services); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Shiny.Prism.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | Shiny.Prism 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Tests/ModularityTests.cs: -------------------------------------------------------------------------------- 1 | using Prism.DryIoc; 2 | using Prism.Ioc; 3 | using Shiny.Prism.Mocks; 4 | using Shiny.Prism.Mocks.Modularity; 5 | using Shiny.Prism.Mocks.Modularity.Services; 6 | using Xunit; 7 | using Xunit.Abstractions; 8 | 9 | namespace Shiny.Prism.Tests 10 | { 11 | [Collection(nameof(ShinyTests))] 12 | public class ModularityTests 13 | { 14 | private ITestOutputHelper _testOutputHelper { get; } 15 | 16 | public ModularityTests(ITestOutputHelper testOutputHelper) 17 | { 18 | _testOutputHelper = testOutputHelper; 19 | } 20 | 21 | [Fact] 22 | public void StartupModuleServicesAreRegisteredFromServiceCollection() 23 | { 24 | ShinyPrismTestHost.Init(new MockModuleStartup(_testOutputHelper)); 25 | 26 | Assert.True(((IContainerProvider)PrismContainerExtension.Current).IsRegistered()); 27 | } 28 | 29 | [Fact] 30 | public void StartupModuleServicesAreNotRegisteredFromContainerRegistry() 31 | { 32 | ShinyPrismTestHost.Init(new MockModuleStartup(_testOutputHelper)); 33 | 34 | Assert.False(((IContainerProvider)PrismContainerExtension.Current).IsRegistered()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Tests/PrismStartupTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Prism.DryIoc; 4 | using Prism.Ioc; 5 | using Shiny.Jobs; 6 | using Shiny.Net; 7 | using Shiny.Power; 8 | using Shiny.Prism.Mocks; 9 | using Shiny.Settings; 10 | using Shiny.Testing.Jobs; 11 | using Shiny.Testing.Net; 12 | using Shiny.Testing.Power; 13 | using Shiny.Testing.Settings; 14 | using Xunit; 15 | using Xunit.Abstractions; 16 | 17 | namespace Shiny.Prism.Tests 18 | { 19 | [Collection(nameof(ShinyTests))] 20 | public class PrismStartupTests 21 | { 22 | private ITestOutputHelper _testOutputHelper { get; } 23 | 24 | public PrismStartupTests(ITestOutputHelper testOutputHelper) 25 | { 26 | _testOutputHelper = testOutputHelper; 27 | } 28 | 29 | [Fact] 30 | public void DoesNotThrowExceptionOnStartup() 31 | { 32 | var ex = Record.Exception(() => ShinyPrismTestHost.Init(_testOutputHelper)); 33 | 34 | Assert.Null(ex); 35 | } 36 | 37 | [Theory] 38 | [InlineData(typeof(IPlatform), typeof(ShinyPrismTestHost))] 39 | [InlineData(typeof(IJobManager), typeof(TestJobManager))] 40 | [InlineData(typeof(IConnectivity), typeof(TestConnectivity))] 41 | [InlineData(typeof(IPowerManager), typeof(TestPowerManager))] 42 | [InlineData(typeof(ISettings), typeof(TestSettings))] 43 | public void ExpectedTypesAreRegisteredAndResolve(Type serviceType, Type implementingType) 44 | { 45 | ShinyPrismTestHost.Init(_testOutputHelper); 46 | var types = ContainerLocator.Container 47 | .GetContainer() 48 | .GetServiceRegistrations() 49 | .Where(x => x.ServiceType.Assembly.GetName().Name == "Shiny.Core"); 50 | foreach (var type in types) 51 | _testOutputHelper.WriteLine($"Found: {type.ServiceType.FullName} - {type.ImplementationType?.FullName}"); 52 | 53 | Assert.True(PrismContainerExtension.Current.IsRegistered(serviceType)); 54 | 55 | var fromShiny = ShinyHost.Container.GetService(serviceType); 56 | Assert.IsType(implementingType, fromShiny); 57 | Assert.Same(fromShiny, PrismContainerExtension.Current.Resolve(serviceType)); 58 | } 59 | 60 | [Fact] 61 | public void PrismStartupLocatesContainerExtension() 62 | { 63 | var ex = Record.Exception(() => ShinyPrismTestHost.Init(new MockStartup(_testOutputHelper, false))); 64 | 65 | Assert.Null(ex); 66 | Assert.NotNull(PrismContainerExtension.Current.Resolve()); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Tests/SharedTestCollection.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace Shiny.Prism.Tests 4 | { 5 | [CollectionDefinition(nameof(ShinyTests), DisableParallelization = true)] 6 | public class SharedTestCollection : ICollectionFixture 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Shiny.Prism.Tests/Tests/ShinyTests.cs: -------------------------------------------------------------------------------- 1 | namespace Shiny.Prism.Tests 2 | { 3 | public class ShinyTests { } 4 | } 5 | -------------------------------------------------------------------------------- /theme/partials/footer.html: -------------------------------------------------------------------------------- 1 | {% import "partials/language.html" as lang with context %} 2 | 3 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", 3 | "version": "8.0", 4 | "assemblyVersion": { 5 | "precision": "revision" 6 | }, 7 | "publicReleaseRefSpec": [ 8 | "^refs/heads/master$", 9 | "^refs/heads/develop$", 10 | "^refs/heads/v\\d+\\.\\d+$" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "maxParallelThreads": 1, 3 | "parallelizeAssembly": false, 4 | "parallelizeTestCollections": false, 5 | "diagnosticMessages": true 6 | } --------------------------------------------------------------------------------