diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..609614f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,121 @@ +name: Build + +on: + workflow_run: + workflows: [ "Changelog generator" ] + types: + - completed + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: windows-latest + env: + # Dotnet Setup + DOTNET_VERSION: 3.1.401 + + # Stop wasting time caching packages + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + + # Disable sending usage data to Microsoft + DOTNET_CLI_TELEMETRY_OPTOUT: true + + # Solution Setup + CONFIG: 'Release' + PROJECT_NAME: 'Cogworks.AzureSearch' + VERSION: '1.0.0' + SOURCE_PATH: './Source' + + # Nuget Setup + NUGET_VERSION: 'latest' + NUGET_OUTPUT: '.output/' + + steps: + - name: Checkout reference commit + if: ${{ github.event_name == 'pull_request' }} + uses: actions/checkout@v2 + + - name: Checkout master + if: ${{ github.event_name != 'pull_request' }} + uses: actions/checkout@v2 + with: + ref: master + fetch-depth: 0 + + - name: Get version + if: ${{ github.event_name != 'pull_request' }} + shell: bash + run: | + tag_check=$(git describe --exact-match `git rev-parse HEAD` | head -1) + echo "VERSION=$tag_check" >> $GITHUB_ENV + + - name: Setup MSBuild + uses: microsoft/setup-msbuild@v1 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Configure NuGet + uses: nuget/setup-nuget@v1 + with: + nuget-version: ${{ env.NUGET_VERSION }} + + - name: NuGet Restore + shell: powershell + working-directory: ${{ github.workspace }} + run: | + $solutions = Get-ChildItem -Path ${{ env.SOURCE_PATH}} -Recurse -Include *.sln + + foreach ($solutionFile in $solutions){ + nuget restore "$solutionFile" + } + + - name: Install Dependencies + shell: powershell + working-directory: ${{ github.workspace }} + run: | + $solutions = Get-ChildItem -Path ${{ env.SOURCE_PATH}} -Recurse -Include *.sln + + foreach ($solutionFile in $solutions){ + dotnet restore "$solutionFile" + } + + - name: Build + shell: powershell + working-directory: ${{ github.workspace }} + run: | + $solutions = Get-ChildItem -Path ${{ env.SOURCE_PATH}} -Recurse -Include *.sln + + foreach ($solutionFile in $solutions){ + msbuild.exe "$solutionFile" ` + /p:Configuration=${{ env.CONFIG }} ` + /p:DeployOnBuild=false ` + /p:SkipInvalidConfigurations=true ` + /p:TransformWebConfigEnabled=False ` + /p:AutoParameterizationWebConfigConnectionStrings=False ` + /p:MarkWebConfigAssistFilesAsExclude=False + } + + - name: Pack all nuspec files + if: ${{ github.event_name != 'pull_request' }} + shell: powershell + working-directory: ${{ github.workspace }} + run: | + $nuspecFiles = Get-ChildItem -Path ${{ env.SOURCE_PATH}} -Recurse -Include *.nuspec + + foreach ($nuspecFile in $nuspecFiles){ + nuget pack "$nuspecFile" ` + -Version ${{ env.VERSION }} ` + -Properties Configuration=${{ env.CONFIG }} ` + -OutputDirectory ${{ env.NUGET_OUTPUT }} + } + + - name: Upload build artifact + if: ${{ github.event_name != 'pull_request' }} + uses: actions/upload-artifact@v2 + with: + name: build_${{ env.PROJECT_NAME }}.${{ env.VERSION }} + path: ${{ github.workspace }}/${{ env.NUGET_OUTPUT }} diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000..ffb918b --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,85 @@ +name: Changelog generator + +on: + push: + tags: + - '*' + +jobs: + changelog_generator: + name: Changelog Generator + runs-on: ubuntu-latest + env: + branch: master + CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set local user + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + - name: Get tag branch + run: | + branch_check=$(git branch -r --contains $(git rev-parse $GITHUB_REF~0) | sed 's/remotes\/origin\///' | sed 's/origin\///' | sed 's/develop//' | sed 's/* //' | sed -r '/^\s*$/d' | head -1) + + echo $branch_check + + if [[ $branch_check =~ ^(release|master)$ ]]; then + echo "Not correct branch. Allowed branches release and master." + exit 1 + fi + + echo "branch=$branch_check" >> $GITHUB_ENV + + - uses: actions/checkout@v2 + name: Checkout tag branch + with: + fetch-depth: 0 + ref: ${{ env.branch }} + + - name: Get tag + run: | + echo "Describe: $(git describe)" + echo "Rev parse: $(git rev-parse $GITHUB_REF~0)" + + tag_check=$(git describe --exact-match `git rev-parse $GITHUB_REF~0`) + echo "tag=$tag_check" >> $GITHUB_ENV + + - name: Install dependencies + run: | + rm -rf node_modules + npm install + + - name: Generate changelog and update npm version + run: | + npm run release + + - name: Remove tag + run: | + git tag -d ${{ env.tag }} + + - name: Updating tags + run: | + git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master + git tag -a ${{ env.tag }} -m "${{ env.tag }}" + git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" --tag -f + + - name: Pushing latest changes to master + run: | + git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master + git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" ${{ env.branch }}:master + + - name: Checkout master + run: | + git checkout master + git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master + + - name: Generate GitHub release notes + run: | + npm run github-release + continue-on-error: true diff --git a/.github/workflows/gitflow.yml b/.github/workflows/gitflow.yml new file mode 100644 index 0000000..38a9959 --- /dev/null +++ b/.github/workflows/gitflow.yml @@ -0,0 +1,54 @@ +name: Git Flow + +on: + workflow_run: + workflows: [ "Changelog generator" ] + types: + - completed +jobs: + gitflow: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + name: Git Flow + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + ref: master + fetch-depth: 0 + + - name: Set local user + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + - name: Get latest tag + run: | + tag_check=$(git describe --exact-match `git rev-parse HEAD` | head -1) + echo "tag=$tag_check" >> $GITHUB_ENV + + - name: Clear release branch + run: | + branch_check=$(git branch -r | grep release/${{ env.tag }} | sed 's/remotes\/origin\///' | sed 's/origin\///' | sed 's/* //' | sed -r '/^\s*$/d' | head -1) + if [[ $branch_check ]]; then + git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" --delete $branch_check + fi + + - name: Checkout develop and pull latest develop + run: | + git checkout develop + git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" develop + + - name: Pull master into develop + run: | + Conflicts=$(git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master -q --ff || echo "fatal: Not possible to fast-forward, aborting") + AbortingMsg='aborting' + + if [[ "$Conflicts" == *"$AbortingMsg"* ]]; then + exit 1 + fi + + - name: Pushing develop to origin if pulling successfully + if: success() + run: | + git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" develop:develop diff --git a/.github/workflows/release-github.yml b/.github/workflows/release-github.yml new file mode 100644 index 0000000..d304cff --- /dev/null +++ b/.github/workflows/release-github.yml @@ -0,0 +1,49 @@ +name: (NuGet) GitHub Packages Release + +on: + workflow_run: + workflows: [ "Build" ] + types: + - completed +jobs: + github_packages_release: + name: GitHub Packages Release + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' }} + runs-on: ubuntu-latest + env: + # GitHub Packages Feed settings + GITHUB_USER: thecogworks + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_FEED: https://nuget.pkg.github.com/thecogworks + GITHUB_PACKAGES_OUTPUT: ${{ github.workspace }}/github_packages + + # Project Setup + PROJECT_NAME: 'Cogworks.AzureSearch' + + steps: + - name: Checkout master + uses: actions/checkout@v2 + with: + ref: master + fetch-depth: 0 + + - name: Get version + shell: bash + run: | + tag_check=$(git describe --exact-match `git rev-parse HEAD` | head -1) + echo "VERSION=$tag_check" >> $GITHUB_ENV + + - name: Download a single artifact + uses: aochmann/actions-download-artifact@1.0.2 + with: + name: build_${{ env.PROJECT_NAME }}.${{ env.VERSION }} + path: ${{ env.GITHUB_PACKAGES_OUTPUT }} + + - name: Push to GitHub Feed + shell: bash + working-directory: ${{ env.GITHUB_PACKAGES_OUTPUT }} + run: | + for nugetFile in ./*.nupkg + do + curl -vX PUT -u "$GITHUB_USER:$GITHUB_TOKEN" -F package=@$nugetFile $GITHUB_FEED + done diff --git a/.github/workflows/release-nuget.yml b/.github/workflows/release-nuget.yml new file mode 100644 index 0000000..c9add94 --- /dev/null +++ b/.github/workflows/release-nuget.yml @@ -0,0 +1,54 @@ +name: (NuGet) NuGet Release + +on: + workflow_run: + workflows: [ "Build" ] + types: + - completed +jobs: + nuget_release: + name: NuGet Release + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' }} + runs-on: ubuntu-latest + env: + # Nuget Setup + NUGET_VERSION: 'latest' + NUGET_OUTPUT: ${{ github.workspace }}/nuget/ + NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} + NUGET_FEED: https://api.nuget.org/v3/index.json + + # Project Setup + PROJECT_NAME: 'Cogworks.AzureSearch' + + steps: + - name: Checkout master + uses: actions/checkout@v2 + with: + ref: master + fetch-depth: 0 + + - name: Get version + shell: bash + run: | + tag_check=$(git describe --exact-match `git rev-parse HEAD` | head -1) + echo "VERSION=$tag_check" >> $GITHUB_ENV + + - name: Download a single artifact + uses: aochmann/actions-download-artifact@1.0.2 + with: + name: build_${{ env.PROJECT_NAME }}.${{ env.VERSION }} + path: ${{ env.NUGET_OUTPUT }} + + - name: Configure NuGet + uses: nuget/setup-nuget@v1 + with: + nuget-version: ${{ env.NUGET_VERSION }} + + - name: Push to NuGet Feed + shell: bash + working-directory: ${{ env.NUGET_OUTPUT }} + run: | + for nugetFile in ./*.nupkg + do + nuget push $nugetFile ${{ env.NUGET_TOKEN }} -Source ${{ env.NUGET_FEED }} + done diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 7f2ba8f..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,284 +0,0 @@ -name: Changelog generator and NuGet Releasing - -on: - push: - tags: - - '*' - -jobs: - changelog-generator: - runs-on: ubuntu-latest - env: - TagOnMaster: false - Branch: master - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - steps: - - uses: actions/checkout@v1 - - name: Set local user - run: | - git config --local user.email "devteam@thecogworks.com" - git config --local user.name "cogworks-infrastructure" - - name: Checkout to master from current head - run: | - git checkout master - git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master - - name: Checking if hotfix applied to master - run: | - HotFixOnMaster=$(git branch --contains refs/tags/`basename $GITHUB_REF` | sed 's/remotes\/origin\///' | sed 's/* //' | grep master) - - if [[ "$HotFixOnMaster" == *"master"* ]]; then - echo ::set-env name=TagOnMaster::true - fi - continue-on-error: true - - name: Set branch variable - if: env.TagOnMaster == 'false' || env.TagOnMaster == 0 - run: echo ::set-env name=Branch::$(git branch -a --contains refs/tags/`basename $GITHUB_REF` | sed 's/remotes\/origin\///' | sed 's/master//' | sed 's/* //' | grep release/`basename $GITHUB_REF`) - - name: Checkout to branch - run: | - echo Branch: $Branch - git checkout $Branch - - name: Check the tag - run: git describe --exact-match `git rev-parse HEAD` - - name: Get tag - run: echo ::set-env name=Tag::$(git describe --exact-match `git rev-parse HEAD`) - - name: Install dependencies - run: | - rm -rf node_modules - npm install - - name: Generate changelog and update npm version - run: npm run release - - name: Remove tag - run: git tag -d $Tag - - name: Updating tags - run: | - git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master - git tag -a $Tag -m "$Tag" - git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" --tag -f - - name: Pushing latest changes to master - run: | - git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master - git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" $Branch:master - - - name: Deleting release branch - if: env.TagOnMaster == 'false' || env.TagOnMaster == 0 - run: git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" --delete $Branch - - - name: Create file status_changelog-generator.txt and write the job status into it - if: always() - run: echo ${{ job.status }} > status_changelog-generator.txt - - name: Upload file status_changelog-generator.txt as an artifact - if: always() - uses: actions/upload-artifact@v1 - with: - name: pass_status_changelog-generator - path: status_changelog-generator.txt - - updating-branches: - needs: changelog-generator - runs-on: ubuntu-latest - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - - steps: - - uses: actions/checkout@v1 - - name: Set local user - run: | - git config --local user.email "devteam@thecogworks.com" - git config --local user.name "cogworks-infrastructure" - - name: Checkout develop and pull latest develop - run: | - git checkout develop - git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" develop - - name: Pull master into develop - run: | - Conflicts=$(git pull "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" master -q --ff-only || echo "fatal: Not possible to fast-forward, aborting") - AbortingMsg='aborting' - - if [[ "$Conflicts" == *"$AbortingMsg"* ]]; then - exit 1 - fi - - name: Pushing develop to origin if pulling successfully - if: success() - run: git push "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git" develop:develop - - - name: Create file status_updating-branches.txt and write the job status into it - if: always() - run: echo ${{ job.status }} > status_updating-branches.txt - - name: Upload file status_updating-branches.txt as an artifact - if: always() - uses: actions/upload-artifact@v1 - with: - name: pass_status_updating-branches - path: status_updating-branches.txt - - nuget-release: - needs: changelog-generator - runs-on: windows-latest - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - - # Dotnet Setup - DOTNET_VERSION: 3.1.401 - - # Stop wasting time caching packages - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - - # Disable sending usage data to Microsoft - DOTNET_CLI_TELEMETRY_OPTOUT: true - - # Nuget Setup - NUGET_VERSION: 'latest' - NUGET_OUTPUT: output - - # Solution Setup - CONFIG: 'Release' - SOLUTION: 'Cogworks.AzureSearch.sln' - - # GitHub Packages Feed settings - GITHUB_USER: thecogworks - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_FEED: https://nuget.pkg.github.com/thecogworks - - # Official NuGet Feed settings - NUGET_FEED: https://api.nuget.org/v3/index.json - NUGET_KEY: ${{ secrets.NUGET_KEY }} - - steps: - - name: Checkout commit - uses: actions/checkout@v2 - with: - ref: master - - - name: Set Version based on tag - shell: bash - run: echo ::set-env name=VERSION::$(basename $GITHUB_REF) - - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - - uses: nuget/setup-nuget@v1 - with: - nuget-version: ${{ env.NUGET_VERSION }} - - - name: NuGet Restore - run: nuget restore ${{ env.SOLUTION }} -LockedMode - - - name: Install dependencies - run: dotnet restore ${{env.SOLUTION}} - - - name: Build - working-directory: ${{ github.workspace }} - run: dotnet build --configuration ${{ env.CONFIG }} ${{ env.SOLUTION }} - - - name: Pack all nuspec files - shell: bash - run: | - for nuspecFile in ./src/**/*.nuspec - do - nuget pack $nuspecFile -Version ${{ env.VERSION }} -Properties Configuration=${{ env.CONFIG }} -OutputDirectory .\${{ env.NUGET_OUTPUT }} - done - - - name: Push to GitHub Feed - shell: bash - run: | - for f in ./${{ env.NUGET_OUTPUT }}/*.nupkg - do - curl -vX PUT -u "$GITHUB_USER:$GITHUB_TOKEN" -F package=@$f $GITHUB_FEED - done - - - name: Push to NuGet Feed - run: dotnet nuget push .\${{ env.NUGET_OUTPUT }}\*.nupkg --source ${{ env.NUGET_FEED }} --skip-duplicate --api-key ${{ env.NUGET_KEY }} - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: packages - path: ${{ env.NUGET_OUTPUT }}\*.nupkg - - finalization-and-notification: - needs: [changelog-generator, updating-branches] - if: always() - runs-on: ubuntu-latest - env: - Failure: "Failure" - Success: "Success" - steps: - - name: Download artifact pass_status_changelog-generator - uses: actions/download-artifact@v1 - with: - name: pass_status_changelog-generator - continue-on-error: true - - - name: Download artifact pass_status_updating-branches - uses: actions/download-artifact@v1 - with: - name: pass_status_updating-branches - continue-on-error: true - - - name: Set the statuses of jobs - id: set_outputs - run: | - if [ -f "pass_status_changelog-generator/status_changelog-generator.txt" ]; then - echo "::set-output name=status_changelog-generator::$( @@ -81,7 +81,7 @@ public class SomeDocumentService Id = "some-id" }); - + public async Task RemoveItems() { var items = new List @@ -107,9 +107,9 @@ public class SomeDocumentService ```csharp public class SomeService { - private readonly IAzureSearch _documentSearch; + private readonly ISearcher _documentSearch; - public SomeService(IAzureSearch documentSearch) + public SomeService(ISearcher documentSearch) => _documentSearch = documentSearch; public void Search() @@ -207,7 +207,7 @@ public class SomeStartupService ``` ## License - + - Cogworks.AzureSearch is licensed under the [Apache License, Version 2.0](https://opensource.org/licenses/Apache-2.0) ## Code of Conduct diff --git a/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/AzureSearchBuilder.cs b/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/AzureSearchBuilder.cs deleted file mode 100644 index d6b7731..0000000 --- a/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/AzureSearchBuilder.cs +++ /dev/null @@ -1,138 +0,0 @@ -using Autofac; -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Indexes; -using Cogworks.AzureSearch.Initializers; -using Cogworks.AzureSearch.Interfaces.Indexes; -using Cogworks.AzureSearch.Interfaces.Initializers; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Interfaces.Repositories; -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Interfaces.Wrappers; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Options; -using Cogworks.AzureSearch.Repositories; -using Cogworks.AzureSearch.Searchers; -using Cogworks.AzureSearch.Wrappers; -using Microsoft.Azure.Search.Models; - -namespace Cogworks.AzureSearch.Autofac.Builders -{ - public class AzureSearchBuilder : IAzureSearchBuilder - { - private readonly ContainerBuilder _builder; - - public AzureSearchBuilder(ContainerBuilder builder) - => _builder = builder; - - internal AzureSearchBuilder RegisterInitializers() - { - _builder.RegisterGeneric(typeof(AzureInitializer<>)) - .As(typeof(IAzureInitializer<>)) - .InstancePerDependency(); - - return this; - } - - public IAzureSearchBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) - { - _ = _builder.Register(_ => new AzureSearchIndexOption(recreate, recreateOnUpdateFailure)) - .AsSelf() - .SingleInstance(); - - return this; - } - - public IAzureSearchBuilder RegisterClientOptions(string serviceName, string credentials) - { - _ = _builder.Register(_ => new AzureSearchClientOption(serviceName, credentials)) - .AsSelf() - .SingleInstance(); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(string indexName) - where TDocument : class, IAzureModel, new() - { - _ = _builder.Register(_ => new AzureIndexDefinition(indexName)) - .AsSelf() - .SingleInstance(); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(Index customIndex) - where TDocument : class, IAzureModel, new() - { - _ = _builder.Register(_ => new AzureIndexDefinition(customIndex)) - .AsSelf() - .SingleInstance(); - - return this; - } - - internal AzureSearchBuilder RegisterIndexes() - { - _ = _builder.RegisterGeneric(typeof(AzureIndex<>)) - .As(typeof(IAzureIndex<>)) - .InstancePerDependency(); - - return this; - } - - internal AzureSearchBuilder RegisterWrappers() - { - _ = _builder.RegisterGeneric(typeof(DocumentOperationWrapper<>)) - .As(typeof(IDocumentOperationWrapper<>)) - .InstancePerDependency(); - - _ = _builder.RegisterType() - .AsImplementedInterfaces() - .InstancePerDependency(); - - return this; - } - - internal AzureSearchBuilder RegisterRepositories() - { - _ = _builder.RegisterGeneric(typeof(AzureSearchRepository<>)) - .As(typeof(IAzureSearchRepository<>)) - .As(typeof(IAzureIndexOperation<>)) - .As(typeof(IAzureDocumentOperation<>)) - .As(typeof(IAzureDocumentSearch<>)) - .InstancePerDependency(); - - return this; - } - - internal AzureSearchBuilder RegisterSearchers() - { - _ = _builder.RegisterGeneric(typeof(AzureSearch<>)) - .As(typeof(IAzureSearch<>)) - .InstancePerDependency(); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher() - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - { - _ = _builder.RegisterType() - .As() - .AsSelf() - .SingleInstance(); - - return this; - } - - IAzureSearchBuilder IAzureSearchBuilder.RegisterDomainSearcher( - TSearcherType instance) - { - _ = _builder.RegisterInstance(instance).As(); - - return this; - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/ContainerBuilder.cs b/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/ContainerBuilder.cs new file mode 100644 index 0000000..0f79410 --- /dev/null +++ b/src/Cogworks.AzureSearch.Autofac.IocExtension/Builders/ContainerBuilder.cs @@ -0,0 +1,156 @@ +using Autofac; +using AutofacContainerBuilder = Autofac.ContainerBuilder; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Indexes; +using Cogworks.AzureSearch.Initializers; +using Cogworks.AzureSearch.Interfaces.Builder; +using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Initializers; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Repositories; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; +using Cogworks.AzureSearch.Options; +using Cogworks.AzureSearch.Repositories; +using Cogworks.AzureSearch.Searchers; +using Cogworks.AzureSearch.Wrappers; + +namespace Cogworks.AzureSearch.Autofac.Builders +{ + + public class ContainerBuilder : IContainerBuilder + { + private readonly AutofacContainerBuilder _builder; + + public ContainerBuilder(AutofacContainerBuilder builder) + => _builder = builder; + + internal ContainerBuilder RegisterInitializers() + { + _builder.RegisterGeneric(typeof(Initializer<>)) + .As(typeof(IInitializer<>)) + .InstancePerDependency(); + + return this; + } + + public IContainerBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) + { + _ = _builder.Register(_ => new IndexOption(recreate, recreateOnUpdateFailure)) + .AsSelf() + .SingleInstance(); + + return this; + } + + public IContainerBuilder RegisterClientOptions(string serviceName, string credentials, string serviceEndpointUrl) + { + _ = _builder.Register(_ => new ClientOption( + serviceName, + credentials, + serviceEndpointUrl)) + .AsSelf() + .SingleInstance(); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(string indexName) + where TDocument : class, IModel, new() + { + _ = _builder.Register(_ => new IndexDefinition(indexName)) + .AsSelf() + .SingleInstance(); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(SearchIndex customIndex) + where TDocument : class, IModel, new() + { + _ = _builder.Register(_ => new IndexDefinition(customIndex)) + .AsSelf() + .SingleInstance(); + + return this; + } + + internal ContainerBuilder RegisterIndexes() + { + _ = _builder.RegisterGeneric(typeof(Index<>)) + .As(typeof(IIndex<>)) + .InstancePerDependency(); + + return this; + } + + internal ContainerBuilder RegisterWrappers() + { + _ = _builder.RegisterGeneric(typeof(DocumentOperationWrapper<>)) + .As(typeof(IDocumentOperationWrapper<>)) + .InstancePerDependency(); + + _ = _builder.RegisterType() + .AsImplementedInterfaces() + .InstancePerDependency(); + + return this; + } + + internal ContainerBuilder RegisterRepositories() + { + _ = _builder.RegisterGeneric(typeof(Repository<>)) + .As(typeof(IRepository<>)) + .InstancePerDependency(); + + return this; + } + + internal ContainerBuilder RegisterSearchers() + { + _ = _builder.RegisterGeneric(typeof(Searcher<>)) + .As(typeof(ISearcher<>)) + .InstancePerDependency(); + + return this; + } + + internal ContainerBuilder RegisterOperations() + { + _ = _builder.RegisterGeneric(typeof(DocumentOperation<>)) + .As(typeof(IDocumentOperation<>)) + .InstancePerDependency(); + + _ = _builder.RegisterGeneric(typeof(IndexOperation<>)) + .As(typeof(IIndexOperation<>)) + .InstancePerDependency(); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher() + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _ = _builder.RegisterType() + .As() + .AsSelf() + .SingleInstance(); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher(TSearcherType instance) + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _ = _builder.RegisterInstance(instance).As(); + + return this; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Autofac.IocExtension/Extensions/AutofacExtensions.cs b/src/Cogworks.AzureSearch.Autofac.IocExtension/Extensions/AutofacExtensions.cs index 2ed258c..222e1c4 100644 --- a/src/Cogworks.AzureSearch.Autofac.IocExtension/Extensions/AutofacExtensions.cs +++ b/src/Cogworks.AzureSearch.Autofac.IocExtension/Extensions/AutofacExtensions.cs @@ -1,16 +1,17 @@ -using Autofac; +using AutofacContainerBuilder = Autofac.ContainerBuilder; using Cogworks.AzureSearch.Autofac.Builders; namespace Cogworks.AzureSearch.Autofac.Extensions { public static class AutofacExtensions { - public static AzureSearchBuilder RegisterAzureSearch(this ContainerBuilder builder) - => new AzureSearchBuilder(builder) + public static ContainerBuilder RegisterAzureSearch(this AutofacContainerBuilder builder) + => new ContainerBuilder(builder) .RegisterRepositories() .RegisterIndexes() .RegisterSearchers() .RegisterInitializers() - .RegisterWrappers(); + .RegisterWrappers() + .RegisterOperations(); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/AzureSearchBuilder.cs b/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/AzureSearchBuilder.cs deleted file mode 100644 index 2a72534..0000000 --- a/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/AzureSearchBuilder.cs +++ /dev/null @@ -1,144 +0,0 @@ -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Indexes; -using Cogworks.AzureSearch.Initializers; -using Cogworks.AzureSearch.Interfaces.Indexes; -using Cogworks.AzureSearch.Interfaces.Initializers; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Interfaces.Repositories; -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Interfaces.Wrappers; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Options; -using Cogworks.AzureSearch.Repositories; -using Cogworks.AzureSearch.Searchers; -using Cogworks.AzureSearch.Wrappers; -using LightInject; -using Microsoft.Azure.Search.Models; - -namespace Cogworks.AzureSearch.LightInject.IocExtension.Builders -{ - public class AzureSearchBuilder : IAzureSearchBuilder - { - private readonly IServiceContainer _container; - - public AzureSearchBuilder(IServiceContainer serviceContainer) - => _container = serviceContainer; - - internal AzureSearchBuilder RegisterInitializers() - { - _ = _container.Register( - typeof(IAzureInitializer<>), - typeof(AzureInitializer<>)); - - return this; - } - - public IAzureSearchBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) - { - _ = _container.Register( - _ => new AzureSearchIndexOption(recreate, recreateOnUpdateFailure), - new PerContainerLifetime()); - - return this; - } - - public IAzureSearchBuilder RegisterClientOptions(string serviceName, string credentials) - { - _ = _container.Register( - _ => new AzureSearchClientOption(serviceName, credentials), - new PerContainerLifetime()); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(string indexName) - where TDocument : class, IAzureModel, new() - { - _ = _container.Register( - _ => new AzureIndexDefinition(indexName), - new PerContainerLifetime()); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(Index customIndex) - where TDocument : class, IAzureModel, new() - { - _ = _container.Register( - _ => new AzureIndexDefinition(customIndex), - new PerContainerLifetime()); - - return this; - } - - internal AzureSearchBuilder RegisterIndexes() - { - _ = _container.Register( - typeof(IAzureIndex<>), - typeof(AzureIndex<>)); - - return this; - } - - internal AzureSearchBuilder RegisterWrappers() - { - _ = _container.Register( - typeof(IDocumentOperationWrapper<>), - typeof(DocumentOperationWrapper<>)); - - _ = _container.Register(); - - return this; - } - - internal AzureSearchBuilder RegisterRepositories() - { - _ = _container.Register( - typeof(IAzureSearchRepository<>), - typeof(AzureSearchRepository<>)); - - _ = _container.Register( - typeof(IAzureIndexOperation<>), - typeof(AzureSearchRepository<>)); - - _ = _container.Register( - typeof(IAzureDocumentOperation<>), - typeof(AzureSearchRepository<>)); - - _ = _container.Register( - typeof(IAzureDocumentSearch<>), - typeof(AzureSearchRepository<>)); - - return this; - } - - internal AzureSearchBuilder RegisterSearchers() - { - _ = _container.Register( - typeof(IAzureSearch<>), - typeof(AzureSearch<>)); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher() - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - { - _ = _container.Register(typeof(TSearcherType), typeof(TSearcher), new PerContainerLifetime()); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher(TSearcherType instance) - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - where TDocument : class, IAzureModel, new() - { - _ = _container.RegisterInstance(instance); ; - - return this; - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/ContainerBuilder.cs b/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/ContainerBuilder.cs new file mode 100644 index 0000000..75815b4 --- /dev/null +++ b/src/Cogworks.AzureSearch.LightInject.IocExtension/Builders/ContainerBuilder.cs @@ -0,0 +1,150 @@ +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Indexes; +using Cogworks.AzureSearch.Initializers; +using Cogworks.AzureSearch.Interfaces.Builder; +using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Initializers; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Repositories; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; +using Cogworks.AzureSearch.Options; +using Cogworks.AzureSearch.Repositories; +using Cogworks.AzureSearch.Searchers; +using Cogworks.AzureSearch.Wrappers; +using LightInject; + +namespace Cogworks.AzureSearch.LightInject.IocExtension.Builders +{ + public class ContainerBuilder : IContainerBuilder + { + private readonly IServiceContainer _container; + + public ContainerBuilder(IServiceContainer serviceContainer) + => _container = serviceContainer; + + internal ContainerBuilder RegisterInitializers() + { + _ = _container.Register( + typeof(IInitializer<>), + typeof(Initializer<>)); + + return this; + } + + public IContainerBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) + { + _ = _container.Register( + _ => new IndexOption(recreate, recreateOnUpdateFailure), + new PerContainerLifetime()); + + return this; + } + + public IContainerBuilder RegisterClientOptions(string serviceName, string credentials, string serviceEndpointUrl) + { + _ = _container.Register( + _ => new ClientOption( + serviceName, + credentials, + serviceEndpointUrl), + new PerContainerLifetime()); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(string indexName) + where TDocument : class, IModel, new() + { + _ = _container.Register( + _ => new IndexDefinition(indexName), + new PerContainerLifetime()); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(SearchIndex customIndex) + where TDocument : class, IModel, new() + { + _ = _container.Register( + _ => new IndexDefinition(customIndex), + new PerContainerLifetime()); + + return this; + } + + internal ContainerBuilder RegisterIndexes() + { + _ = _container.Register( + typeof(IIndex<>), + typeof(Index<>)); + + return this; + } + + internal ContainerBuilder RegisterWrappers() + { + _ = _container.Register( + typeof(IDocumentOperationWrapper<>), + typeof(DocumentOperationWrapper<>)); + + _ = _container.Register(); + + return this; + } + + internal ContainerBuilder RegisterRepositories() + { + _ = _container.Register( + typeof(IRepository<>), + typeof(Repository<>)); + + return this; + } + + internal ContainerBuilder RegisterSearchers() + { + _ = _container.Register( + typeof(ISearcher<>), + typeof(Searcher<>)); + + return this; + } + internal ContainerBuilder RegisterOperations() + { + _ = _container.Register( + typeof(IDocumentOperation<>), + typeof(DocumentOperation<>), + new PerContainerLifetime()); + + _ = _container.Register( + typeof(IIndexOperation<>), + typeof(IndexOperation<>), + new PerContainerLifetime()); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher() + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _ = _container.Register(typeof(TSearcherType), typeof(TSearcher), new PerContainerLifetime()); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher(TSearcherType instance) + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _ = _container.RegisterInstance(instance); ; + + return this; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.LightInject.IocExtension/Cogworks.AzureSearch.LightInject.IocExtension.csproj b/src/Cogworks.AzureSearch.LightInject.IocExtension/Cogworks.AzureSearch.LightInject.IocExtension.csproj index f313719..9205d7d 100644 --- a/src/Cogworks.AzureSearch.LightInject.IocExtension/Cogworks.AzureSearch.LightInject.IocExtension.csproj +++ b/src/Cogworks.AzureSearch.LightInject.IocExtension/Cogworks.AzureSearch.LightInject.IocExtension.csproj @@ -13,10 +13,10 @@ - + - + \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.LightInject.IocExtension/Extensions/RegisterExtensions.cs b/src/Cogworks.AzureSearch.LightInject.IocExtension/Extensions/RegisterExtensions.cs index 26faf5e..c447a5c 100644 --- a/src/Cogworks.AzureSearch.LightInject.IocExtension/Extensions/RegisterExtensions.cs +++ b/src/Cogworks.AzureSearch.LightInject.IocExtension/Extensions/RegisterExtensions.cs @@ -5,12 +5,13 @@ namespace Cogworks.AzureSearch.LightInject.IocExtension.Extensions { public static class RegisterExtensions { - public static AzureSearchBuilder RegisterAzureSearch(this IServiceContainer serviceContainer) - => new AzureSearchBuilder(serviceContainer) + public static ContainerBuilder RegisterAzureSearch(this IServiceContainer serviceContainer) + => new ContainerBuilder(serviceContainer) .RegisterRepositories() .RegisterIndexes() .RegisterSearchers() .RegisterInitializers() - .RegisterWrappers(); + .RegisterWrappers() + .RegisterOperations(); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/AzureSearchBuilder.cs b/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/AzureSearchBuilder.cs deleted file mode 100644 index bc1b205..0000000 --- a/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/AzureSearchBuilder.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Indexes; -using Cogworks.AzureSearch.Initializers; -using Cogworks.AzureSearch.Interfaces.Indexes; -using Cogworks.AzureSearch.Interfaces.Initializers; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Interfaces.Repositories; -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Interfaces.Wrappers; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Options; -using Cogworks.AzureSearch.Repositories; -using Cogworks.AzureSearch.Searchers; -using Cogworks.AzureSearch.Wrappers; -using Microsoft.Azure.Search.Models; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; - -namespace Cogworks.AzureSearch.Microsoft.IocExtension.Builders -{ - public class AzureSearchBuilder : IAzureSearchBuilder - { - private readonly IServiceCollection _serviceCollection; - - public AzureSearchBuilder(IServiceCollection serviceCollection) - => _serviceCollection = serviceCollection; - - internal AzureSearchBuilder RegisterInitializers() - { - _serviceCollection.TryAddScoped(typeof(IAzureInitializer<>), typeof(AzureInitializer<>)); - - return this; - } - - public IAzureSearchBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) - { - _serviceCollection.TryAddSingleton(_ => new AzureSearchIndexOption(recreate, recreateOnUpdateFailure)); - - return this; - } - - public IAzureSearchBuilder RegisterClientOptions(string serviceName, string credentials) - { - _serviceCollection.TryAddSingleton(_ => new AzureSearchClientOption(serviceName, credentials)); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(string indexName) - where TDocument : class, IAzureModel, new() - { - _serviceCollection.TryAddSingleton(_ => new AzureIndexDefinition(indexName)); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(Index customIndex) - where TDocument : class, IAzureModel, new() - { - _serviceCollection.TryAddSingleton(_ => new AzureIndexDefinition(customIndex)); - - return this; - } - - internal AzureSearchBuilder RegisterIndexes() - { - _serviceCollection.TryAddScoped(typeof(IAzureIndex<>), typeof(AzureIndex<>)); - - return this; - } - - internal AzureSearchBuilder RegisterWrappers() - { - _serviceCollection.TryAddScoped(typeof(IDocumentOperationWrapper<>), typeof(DocumentOperationWrapper<>)); - - _serviceCollection.TryAddScoped(); - - return this; - } - - internal AzureSearchBuilder RegisterRepositories() - { - _serviceCollection.TryAddScoped(typeof(IAzureSearchRepository<>), typeof(AzureSearchRepository<>)); - _serviceCollection.TryAddScoped(typeof(IAzureIndexOperation<>), typeof(AzureSearchRepository<>)); - _serviceCollection.TryAddScoped(typeof(IAzureDocumentOperation<>), typeof(AzureSearchRepository<>)); - _serviceCollection.TryAddScoped(typeof(IAzureDocumentSearch<>), typeof(AzureSearchRepository<>)); - - return this; - } - - internal AzureSearchBuilder RegisterSearchers() - { - _serviceCollection.TryAddScoped(typeof(IAzureSearch<>), typeof(AzureSearch<>)); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher() - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - { - _serviceCollection.TryAddSingleton(); - - return this; - } - - IAzureSearchBuilder IAzureSearchBuilder.RegisterDomainSearcher( - TSearcherType instance) - { - _serviceCollection.TryAddSingleton(instance); - - return this; - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/ContainerBuilder.cs b/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/ContainerBuilder.cs new file mode 100644 index 0000000..af00b58 --- /dev/null +++ b/src/Cogworks.AzureSearch.Microsoft.IocExtension/Builders/ContainerBuilder.cs @@ -0,0 +1,130 @@ +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Indexes; +using Cogworks.AzureSearch.Initializers; +using Cogworks.AzureSearch.Interfaces.Builder; +using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Initializers; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Repositories; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; +using Cogworks.AzureSearch.Options; +using Cogworks.AzureSearch.Repositories; +using Cogworks.AzureSearch.Searchers; +using Cogworks.AzureSearch.Wrappers; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Cogworks.AzureSearch.Microsoft.IocExtension.Builders +{ + public class ContainerBuilder : IContainerBuilder + { + private readonly IServiceCollection _serviceCollection; + + public ContainerBuilder(IServiceCollection serviceCollection) + => _serviceCollection = serviceCollection; + + internal ContainerBuilder RegisterInitializers() + { + _serviceCollection.TryAddScoped(typeof(IInitializer<>), typeof(Initializer<>)); + + return this; + } + + public IContainerBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) + { + _serviceCollection.TryAddSingleton(_ => new IndexOption(recreate, recreateOnUpdateFailure)); + + return this; + } + + public IContainerBuilder RegisterClientOptions(string serviceName, string credentials, string serviceEndpointUrl) + { + _serviceCollection.TryAddSingleton(_ => new ClientOption( + serviceName, + credentials, + serviceEndpointUrl)); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(string indexName) + where TDocument : class, IModel, new() + { + _serviceCollection.TryAddSingleton(_ => new IndexDefinition(indexName)); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(SearchIndex customIndex) + where TDocument : class, IModel, new() + { + _serviceCollection.TryAddSingleton(_ => new IndexDefinition(customIndex)); + + return this; + } + + internal ContainerBuilder RegisterIndexes() + { + _serviceCollection.TryAddScoped(typeof(IIndex<>), typeof(Index<>)); + + return this; + } + + internal ContainerBuilder RegisterWrappers() + { + _serviceCollection.TryAddScoped(typeof(IDocumentOperationWrapper<>), typeof(DocumentOperationWrapper<>)); + + _serviceCollection.TryAddScoped(); + + return this; + } + + internal ContainerBuilder RegisterRepositories() + { + _serviceCollection.TryAddScoped( + typeof(IRepository<>), + typeof(Repository<>)); + + return this; + } + + internal ContainerBuilder RegisterSearchers() + { + _serviceCollection.TryAddScoped(typeof(ISearcher<>), typeof(Searcher<>)); + + return this; + } + + internal ContainerBuilder RegisterOperations() + { + _serviceCollection.TryAddScoped(typeof(IDocumentOperation<>), typeof(DocumentOperation<>)); + + _serviceCollection.TryAddScoped(typeof(IIndexOperation<>), typeof(IndexOperation<>)); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher() + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _serviceCollection.TryAddSingleton(); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher(TSearcherType instance) + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _serviceCollection.TryAddSingleton(instance); + + return this; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Microsoft.IocExtension/Extensions/BuilderExtensions.cs b/src/Cogworks.AzureSearch.Microsoft.IocExtension/Extensions/BuilderExtensions.cs index 913caf1..99b98f8 100644 --- a/src/Cogworks.AzureSearch.Microsoft.IocExtension/Extensions/BuilderExtensions.cs +++ b/src/Cogworks.AzureSearch.Microsoft.IocExtension/Extensions/BuilderExtensions.cs @@ -5,12 +5,13 @@ namespace Cogworks.AzureSearch.Microsoft.IocExtension.Extensions { public static class BuilderExtensions { - public static AzureSearchBuilder RegisterAzureSearch(this IServiceCollection serviceCollection) - => new AzureSearchBuilder(serviceCollection) + public static ContainerBuilder RegisterAzureSearch(this IServiceCollection serviceCollection) + => new ContainerBuilder(serviceCollection) .RegisterRepositories() .RegisterIndexes() .RegisterSearchers() .RegisterInitializers() - .RegisterWrappers(); + .RegisterWrappers() + .RegisterOperations(); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/AzureSearchBuilder.cs b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/AzureSearchBuilder.cs deleted file mode 100644 index a70ac44..0000000 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/AzureSearchBuilder.cs +++ /dev/null @@ -1,145 +0,0 @@ -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Indexes; -using Cogworks.AzureSearch.Initializers; -using Cogworks.AzureSearch.Interfaces.Indexes; -using Cogworks.AzureSearch.Interfaces.Initializers; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Interfaces.Repositories; -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Interfaces.Wrappers; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Options; -using Cogworks.AzureSearch.Repositories; -using Cogworks.AzureSearch.Searchers; -using Cogworks.AzureSearch.Wrappers; -using Microsoft.Azure.Search.Models; -using Umbraco.Core; -using Umbraco.Core.Composing; - -namespace Cogworks.AzureSearch.Umbraco.IocExtension.Builders -{ - public class AzureSearchBuilder : IAzureSearchBuilder - { - private readonly IRegister _composingRegister; - - public AzureSearchBuilder(IRegister composingRegister) - => _composingRegister = composingRegister; - - internal AzureSearchBuilder RegisterInitializers() - { - _composingRegister.Register( - typeof(IAzureInitializer<>), - typeof(AzureInitializer<>)); - - return this; - } - - public IAzureSearchBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) - { - _composingRegister.Register( - _ => new AzureSearchIndexOption(recreate, recreateOnUpdateFailure), - Lifetime.Singleton); - - return this; - } - - public IAzureSearchBuilder RegisterClientOptions(string serviceName, string credentials) - { - _composingRegister.Register( - _ => new AzureSearchClientOption(serviceName, credentials), - Lifetime.Singleton); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(string indexName) - where TDocument : class, IAzureModel, new() - { - _composingRegister.Register( - _ => new AzureIndexDefinition(indexName), - Lifetime.Singleton); - - return this; - } - - public IAzureSearchBuilder RegisterIndexDefinitions(Index customIndex) - where TDocument : class, IAzureModel, new() - { - _composingRegister.Register( - _ => new AzureIndexDefinition(customIndex), - Lifetime.Singleton); - - return this; - } - - internal AzureSearchBuilder RegisterIndexes() - { - _composingRegister.Register( - typeof(IAzureIndex<>), - typeof(AzureIndex<>)); - - return this; - } - - internal AzureSearchBuilder RegisterWrappers() - { - _composingRegister.Register( - typeof(IDocumentOperationWrapper<>), - typeof(DocumentOperationWrapper<>)); - - _composingRegister.Register(); - - return this; - } - - internal AzureSearchBuilder RegisterRepositories() - { - _composingRegister.Register( - typeof(IAzureSearchRepository<>), - typeof(AzureSearchRepository<>)); - - _composingRegister.Register( - typeof(IAzureIndexOperation<>), - typeof(AzureSearchRepository<>)); - - _composingRegister.Register( - typeof(IAzureDocumentOperation<>), - typeof(AzureSearchRepository<>)); - - _composingRegister.Register( - typeof(IAzureDocumentSearch<>), - typeof(AzureSearchRepository<>)); - - return this; - } - - internal AzureSearchBuilder RegisterSearchers() - { - _composingRegister.Register( - typeof(IAzureSearch<>), - typeof(AzureSearch<>)); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher() - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - { - _composingRegister.Register(Lifetime.Singleton); - - return this; - } - - public IAzureSearchBuilder RegisterDomainSearcher(TSearcherType instance) - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class - { - _composingRegister.Register(instance); - - return this; - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/ContainerBuilder.cs b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/ContainerBuilder.cs new file mode 100644 index 0000000..65b39b1 --- /dev/null +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Builders/ContainerBuilder.cs @@ -0,0 +1,150 @@ +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Indexes; +using Cogworks.AzureSearch.Initializers; +using Cogworks.AzureSearch.Interfaces.Builder; +using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Initializers; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Repositories; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; +using Cogworks.AzureSearch.Options; +using Cogworks.AzureSearch.Repositories; +using Cogworks.AzureSearch.Searchers; +using Cogworks.AzureSearch.Wrappers; +using Umbraco.Core; +using Umbraco.Core.Composing; + +namespace Cogworks.AzureSearch.Umbraco.IocExtension.Builders +{ + public class ContainerBuilder : IContainerBuilder + { + private readonly IRegister _composingRegister; + + public ContainerBuilder(IRegister composingRegister) + => _composingRegister = composingRegister; + + internal ContainerBuilder RegisterInitializers() + { + _composingRegister.Register( + typeof(IInitializer<>), + typeof(Initializer<>)); + + return this; + } + + public IContainerBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false) + { + _composingRegister.Register( + _ => new IndexOption(recreate, recreateOnUpdateFailure), + Lifetime.Singleton); + + return this; + } + + public IContainerBuilder RegisterClientOptions(string serviceName, string credentials, string serviceEndpointUrl) + { + _composingRegister.Register( + _ => new ClientOption( + serviceName, + credentials, + serviceEndpointUrl), + Lifetime.Singleton); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(string indexName) + where TDocument : class, IModel, new() + { + _composingRegister.Register( + _ => new IndexDefinition(indexName), + Lifetime.Singleton); + + return this; + } + + public IContainerBuilder RegisterIndexDefinitions(SearchIndex customIndex) + where TDocument : class, IModel, new() + { + _composingRegister.Register( + _ => new IndexDefinition(customIndex), + Lifetime.Singleton); + + return this; + } + + internal ContainerBuilder RegisterIndexes() + { + _composingRegister.Register( + typeof(IIndex<>), + typeof(Index<>)); + + return this; + } + + internal ContainerBuilder RegisterWrappers() + { + _composingRegister.Register( + typeof(IDocumentOperationWrapper<>), + typeof(DocumentOperationWrapper<>)); + + _composingRegister.Register(); + + return this; + } + + internal ContainerBuilder RegisterRepositories() + { + _composingRegister.Register( + typeof(IRepository<>), + typeof(Repository<>)); + + return this; + } + + internal ContainerBuilder RegisterSearchers() + { + _composingRegister.Register( + typeof(ISearcher<>), + typeof(Searcher<>)); + + return this; + } + + internal ContainerBuilder RegisterOperations() + { + _composingRegister.Register( + typeof(IDocumentOperation<>), + typeof(DocumentOperation<>)); + + _composingRegister.Register( + typeof(IIndexOperation<>), + typeof(IndexOperation<>)); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher() + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _composingRegister.Register(Lifetime.Singleton); + + return this; + } + + public IContainerBuilder RegisterDomainSearcher(TSearcherType instance) + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class + { + _composingRegister.Register(instance); + + return this; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.csproj b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.csproj index f94f7ee..897f01b 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.csproj +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.csproj @@ -4,12 +4,12 @@ Debug AnyCPU - {FC38DB43-401F-4E88-BAF5-A28325E4C461} + {E1317854-28A7-491E-97B1-FBEEEF7B5982} Library Properties Cogworks.AzureSearch.Umbraco.IocExtension Cogworks.AzureSearch.Umbraco.IocExtension - v4.8 + v4.7.2 512 true @@ -33,6 +33,12 @@ 4 + + ..\..\packages\Azure.Core.1.9.0\lib\net461\Azure.Core.dll + + + ..\..\packages\Azure.Search.Documents.11.2.0\lib\netstandard2.0\Azure.Search.Documents.dll + ..\..\packages\LightInject.5.4.0\lib\net46\LightInject.dll @@ -45,11 +51,8 @@ ..\..\packages\Microsoft.AspNet.Identity.Core.2.2.2\lib\net45\Microsoft.AspNet.Identity.Core.dll - - ..\..\packages\Microsoft.Azure.Search.Common.10.1.0\lib\net461\Microsoft.Azure.Search.Common.dll - - - ..\..\packages\Microsoft.Azure.Search.Service.10.1.0\lib\net461\Microsoft.Azure.Search.Service.dll + + ..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll @@ -57,15 +60,6 @@ ..\..\packages\Microsoft.Owin.4.0.1\lib\net45\Microsoft.Owin.dll - - ..\..\packages\Microsoft.Rest.ClientRuntime.2.3.20\lib\net461\Microsoft.Rest.ClientRuntime.dll - - - ..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.18\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll - - - ..\..\packages\Microsoft.Spatial.7.5.3\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll - ..\..\packages\MiniProfiler.4.0.138\lib\net461\MiniProfiler.dll @@ -118,6 +112,9 @@ ..\..\packages\Superpower.2.0.0\lib\net45\Superpower.dll + + ..\..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + @@ -128,20 +125,43 @@ ..\..\packages\Umbraco.SqlServerCE.4.0.0.1\lib\net472\System.Data.SqlServerCe.Entity.dll - - ..\..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll - + + ..\..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + ..\..\packages\System.Memory.Data.1.0.1\lib\net461\System.Memory.Data.dll + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll - + + + ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Text.Encodings.Web.4.6.0\lib\netstandard2.0\System.Text.Encodings.Web.dll + + + ..\..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll + + + ..\..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + ..\..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll @@ -159,14 +179,7 @@ - - - - - - - - + @@ -174,10 +187,15 @@ Cogworks.AzureSearch.LightInject.IocExtension - {64b55c63-5070-430f-a92d-747ff2cd57a6} + {94f77e26-4e02-4ed5-bd54-45e3aaa70090} Cogworks.AzureSearch + + + + + diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.nuspec b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.nuspec index 9108e3c..0d24c29 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.nuspec +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Cogworks.AzureSearch.Umbraco.IocExtension.nuspec @@ -1,4 +1,4 @@ - + Cogworks.AzureSearch.Umbraco.IocExtension @@ -14,16 +14,17 @@ The Cogworks Limited 2020 Azure Search, Umbraco - + + - - - + + + \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Extensions/RegisterExtensions.cs b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Extensions/RegisterExtensions.cs index bd9acf3..4761066 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Extensions/RegisterExtensions.cs +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Extensions/RegisterExtensions.cs @@ -1,4 +1,4 @@ -using Cogworks.AzureSearch.Builder; +using Cogworks.AzureSearch.Interfaces.Builder; using Cogworks.AzureSearch.LightInject.IocExtension.Extensions; using Cogworks.AzureSearch.Umbraco.IocExtension.Builders; using LightInject; @@ -8,14 +8,15 @@ namespace Cogworks.AzureSearch.Umbraco.IocExtension.Extensions { public static class RegisterExtensions { - public static IAzureSearchBuilder RegisterAzureSearch(this IRegister composingRegister, bool useConcreteContainer = false) + public static IContainerBuilder RegisterAzureSearch(this IRegister composingRegister, bool useConcreteContainer = false) => useConcreteContainer - ? (composingRegister.Concrete as IServiceContainer).RegisterAzureSearch() as IAzureSearchBuilder - : new AzureSearchBuilder(composingRegister) + ? (composingRegister.Concrete as IServiceContainer).RegisterAzureSearch() as IContainerBuilder + : new ContainerBuilder(composingRegister) .RegisterRepositories() .RegisterIndexes() .RegisterSearchers() .RegisterInitializers() - .RegisterWrappers(); + .RegisterWrappers() + .RegisterOperations(); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Properties/AssemblyInfo.cs b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Properties/AssemblyInfo.cs index 8f94a8d..937b250 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/Properties/AssemblyInfo.cs +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -10,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Cogworks.AzureSearch.Umbraco.IocExtension")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +19,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("fc38db43-401f-4e88-baf5-a28325e4c461")] +[assembly: Guid("e1317854-28a7-491e-97b1-fbeeef7b5982")] // Version information for an assembly consists of the following four values: // diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/app.config b/src/Cogworks.AzureSearch.Umbraco.IocExtension/app.config index e936cc1..1eb6c7e 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/app.config +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/app.config @@ -6,6 +6,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Cogworks.AzureSearch.Umbraco.IocExtension/packages.config b/src/Cogworks.AzureSearch.Umbraco.IocExtension/packages.config index d935827..5f0eb16 100644 --- a/src/Cogworks.AzureSearch.Umbraco.IocExtension/packages.config +++ b/src/Cogworks.AzureSearch.Umbraco.IocExtension/packages.config @@ -1,36 +1,43 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Builder/IAzureSearchBuilder.cs b/src/Cogworks.AzureSearch/Builder/IAzureSearchBuilder.cs deleted file mode 100644 index 1319536..0000000 --- a/src/Cogworks.AzureSearch/Builder/IAzureSearchBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search.Models; - -namespace Cogworks.AzureSearch.Builder -{ - public interface IAzureSearchBuilder - { - IAzureSearchBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false); - - IAzureSearchBuilder RegisterClientOptions(string serviceName, string credentials); - - IAzureSearchBuilder RegisterIndexDefinitions(string indexName) - where TDocument : class, IAzureModel, new(); - - IAzureSearchBuilder RegisterIndexDefinitions(Index customIndex) - where TDocument : class, IAzureModel, new(); - - IAzureSearchBuilder RegisterDomainSearcher() - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class; - - IAzureSearchBuilder RegisterDomainSearcher(TSearcherType instance) - where TDocument : class, IAzureModel, new() - where TSearcher : class, IAzureSearch, TSearcherType - where TSearcherType : class; - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Cogworks.AzureSearch.csproj b/src/Cogworks.AzureSearch/Cogworks.AzureSearch.csproj index 7c46776..db3f70d 100644 --- a/src/Cogworks.AzureSearch/Cogworks.AzureSearch.csproj +++ b/src/Cogworks.AzureSearch/Cogworks.AzureSearch.csproj @@ -9,11 +9,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + - + @@ -21,7 +20,7 @@ - + @@ -29,4 +28,5 @@ - \ No newline at end of file + + diff --git a/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/AddOrUpdateDocumentException.cs b/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/AddOrUpdateDocumentException.cs new file mode 100644 index 0000000..b2df78a --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/AddOrUpdateDocumentException.cs @@ -0,0 +1,18 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.DocumentsExceptions +{ + public class AddOrUpdateDocumentException : DomainException + { + + public override string Code => "add_or_update_document_exception"; + + public AddOrUpdateDocumentException(string message) : base(message) + { + } + + public AddOrUpdateDocumentException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/RemoveDocumentException.cs b/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/RemoveDocumentException.cs new file mode 100644 index 0000000..b8436d0 --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/DocumentsExceptions/RemoveDocumentException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.DocumentsExceptions +{ + public class RemoveDocumentException : DomainException + { + public override string Code => "remove_document_exception"; + + public RemoveDocumentException(string message) : base(message) + { + } + + public RemoveDocumentException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/DomainException.cs b/src/Cogworks.AzureSearch/Exceptions/DomainException.cs new file mode 100644 index 0000000..b8ad05d --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/DomainException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions +{ + public abstract class DomainException : Exception + { + public abstract string Code { get; } + + protected DomainException(string message) : base(message) + { + } + + protected DomainException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexClearException.cs b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexClearException.cs new file mode 100644 index 0000000..4dfc082 --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexClearException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.IndexExceptions +{ + public class IndexClearException : DomainException + { + public override string Code => "index_clear_error"; + + public IndexClearException(string message) : base(message) + { + } + + public IndexClearException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexCreateOrUpdateException.cs b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexCreateOrUpdateException.cs new file mode 100644 index 0000000..34206ef --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexCreateOrUpdateException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.IndexExceptions +{ + public class IndexCreateOrUpdateException :DomainException + { + public override string Code => "index_create_or_update_error"; + + public IndexCreateOrUpdateException(string message) : base(message) + { + } + + public IndexCreateOrUpdateException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexDeleteException.cs b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexDeleteException.cs new file mode 100644 index 0000000..12fd6f3 --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexDeleteException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.IndexExceptions +{ + public class IndexDeleteException : DomainException + { + public override string Code => "index_delete_error"; + + public IndexDeleteException(string message) : base(message) + { + } + + public IndexDeleteException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexExistsException.cs b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexExistsException.cs new file mode 100644 index 0000000..7a669d2 --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexExistsException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.IndexExceptions +{ + public class IndexExistsException : DomainException + { + public override string Code => "index_exists_exception"; + + public IndexExistsException(string message) : base(message) + { + } + + public IndexExistsException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexInitializerException.cs b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexInitializerException.cs new file mode 100644 index 0000000..2229de2 --- /dev/null +++ b/src/Cogworks.AzureSearch/Exceptions/IndexExceptions/IndexInitializerException.cs @@ -0,0 +1,17 @@ +using System; + +namespace Cogworks.AzureSearch.Exceptions.IndexExceptions +{ + public class IndexInitializerException : DomainException + { + public override string Code => "index_initializer_exception"; + + public IndexInitializerException(string message) : base(message) + { + } + + public IndexInitializerException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Indexes/AzureIndex.cs b/src/Cogworks.AzureSearch/Indexes/AzureIndex.cs deleted file mode 100644 index 1256ce4..0000000 --- a/src/Cogworks.AzureSearch/Indexes/AzureIndex.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Cogworks.AzureSearch.Interfaces.Indexes; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Indexes -{ - internal class AzureIndex : IAzureIndex where TAzureModel : class, IAzureModel, new() - { - private readonly IAzureDocumentOperation _azureSearchRepository; - - public AzureIndex(IAzureDocumentOperation azureSearchRepository) - => _azureSearchRepository = azureSearchRepository; - - public async Task AddOrUpdateDocumentAsync(TAzureModel model) - => await _azureSearchRepository.AddOrUpdateDocumentAsync(model); - - public async Task TryRemoveDocumentAsync(TAzureModel model) - => await _azureSearchRepository.TryRemoveDocumentAsync(model); - - public async Task AddOrUpdateDocumentsAsync(IEnumerable models) - => await _azureSearchRepository.AddOrUpdateDocumentsAsync(models); - - public async Task TryRemoveDocumentsAsync(IEnumerable models) - => await _azureSearchRepository.TryRemoveDocumentsAsync(models); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Indexes/Index.cs b/src/Cogworks.AzureSearch/Indexes/Index.cs new file mode 100644 index 0000000..7f7e1b7 --- /dev/null +++ b/src/Cogworks.AzureSearch/Indexes/Index.cs @@ -0,0 +1,29 @@ +using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Cogworks.AzureSearch.Indexes +{ + internal class Index : IIndex where TModel : class, IModel, new() + { + private readonly IDocumentOperation _documentOperation; + + public Index(IDocumentOperation documentOperation) + => _documentOperation = documentOperation; + + public async Task AddOrUpdateDocumentAsync(TModel model) + => await _documentOperation.AddOrUpdateDocumentAsync(model); + + public async Task TryRemoveDocumentAsync(TModel model) + => await _documentOperation.TryRemoveDocumentAsync(model); + + public async Task AddOrUpdateDocumentsAsync(IEnumerable models) + => await _documentOperation.AddOrUpdateDocumentsAsync(models); + + public async Task TryRemoveDocumentsAsync(IEnumerable models) + => await _documentOperation.TryRemoveDocumentsAsync(models); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Initializers/AzureInitializer.cs b/src/Cogworks.AzureSearch/Initializers/AzureInitializer.cs deleted file mode 100644 index a77c6aa..0000000 --- a/src/Cogworks.AzureSearch/Initializers/AzureInitializer.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Cogworks.AzureSearch.Interfaces.Initializers; -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using Cogworks.AzureSearch.Options; -using System; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Initializers -{ - internal class AzureInitializer : IAzureInitializer - where TAzureModel : class, IAzureModel, new() - { - private readonly AzureSearchIndexOption _azureSearchIndexOption; - private readonly IAzureIndexOperation _azureIndexOperation; - - public AzureInitializer(AzureSearchIndexOption azureSearchIndexOption, IAzureIndexOperation azureIndexOperation) - { - _azureSearchIndexOption = azureSearchIndexOption; - _azureIndexOperation = azureIndexOperation; - } - - public async Task InitializeAsync() - { - if (_azureSearchIndexOption.Recreate) - { - await _azureIndexOperation.IndexDeleteAsync(); - } - - try - { - return await _azureIndexOperation.IndexCreateOrUpdateAsync(); - } - catch (Exception) - { - if (_azureSearchIndexOption.RecreateOnUpdateFailure) - { - await _azureIndexOperation.IndexDeleteAsync(); - } - } - - return await _azureIndexOperation.IndexCreateOrUpdateAsync(); - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Initializers/Initializer.cs b/src/Cogworks.AzureSearch/Initializers/Initializer.cs new file mode 100644 index 0000000..9f0daa3 --- /dev/null +++ b/src/Cogworks.AzureSearch/Initializers/Initializer.cs @@ -0,0 +1,52 @@ +using System; +using System.Threading.Tasks; +using Cogworks.AzureSearch.Exceptions.IndexExceptions; +using Cogworks.AzureSearch.Interfaces.Initializers; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Options; + +namespace Cogworks.AzureSearch.Initializers +{ + internal class Initializer : IInitializer + where TModel : class, IModel, new() + { + private readonly IndexOption _indexOption; + private readonly IIndexOperation _indexOperation; + + public Initializer(IndexOption indexOption, IIndexOperation indexOperation) + { + _indexOption = indexOption; + _indexOperation = indexOperation; + } + + public async Task InitializeAsync() + { + if (_indexOption.Recreate) + { + await _indexOperation.IndexDeleteAsync(); + } + + try + { + await _indexOperation.IndexCreateOrUpdateAsync(); + } + catch (Exception) + { + if (_indexOption.RecreateOnUpdateFailure) + { + await _indexOperation.IndexDeleteAsync(); + } + } + + try + { + await _indexOperation.IndexCreateOrUpdateAsync(); + } + catch (Exception exception) + { + throw new IndexInitializerException(exception.Message, exception.InnerException); + } + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Builder/IContainerBuilder.cs b/src/Cogworks.AzureSearch/Interfaces/Builder/IContainerBuilder.cs new file mode 100644 index 0000000..4383b2a --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Builder/IContainerBuilder.cs @@ -0,0 +1,29 @@ +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Searchers; + +namespace Cogworks.AzureSearch.Interfaces.Builder +{ + public interface IContainerBuilder + { + IContainerBuilder RegisterIndexOptions(bool recreate, bool recreateOnUpdateFailure = false); + + IContainerBuilder RegisterClientOptions(string serviceName, string credentials, string serviceEndpointUrl); + + IContainerBuilder RegisterIndexDefinitions(string indexName) + where TDocument : class, IModel, new(); + + IContainerBuilder RegisterIndexDefinitions(SearchIndex customIndex) + where TDocument : class, IModel, new(); + + IContainerBuilder RegisterDomainSearcher() + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class; + + IContainerBuilder RegisterDomainSearcher(TSearcherType instance) + where TDocument : class, IModel, new() + where TSearcher : BaseDomainSearch, TSearcherType + where TSearcherType : class; + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Indexes/IAzureIndex.cs b/src/Cogworks.AzureSearch/Interfaces/Indexes/IAzureIndex.cs deleted file mode 100644 index 713fdd4..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Indexes/IAzureIndex.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Interfaces.Indexes -{ - public interface IAzureIndex where TAzureModel : class, IAzureModel, new() - { - Task AddOrUpdateDocumentAsync(TAzureModel model); - - Task AddOrUpdateDocumentsAsync(IEnumerable models); - - Task TryRemoveDocumentAsync(TAzureModel model); - - Task TryRemoveDocumentsAsync(IEnumerable models); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Indexes/IIndex.cs b/src/Cogworks.AzureSearch/Interfaces/Indexes/IIndex.cs new file mode 100644 index 0000000..44f3934 --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Indexes/IIndex.cs @@ -0,0 +1,19 @@ + +using System.Collections.Generic; +using System.Threading.Tasks; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Interfaces.Indexes +{ + public interface IIndex where TModel : class, IModel, new() + { + Task AddOrUpdateDocumentAsync(TModel model); + + Task AddOrUpdateDocumentsAsync(IEnumerable models); + + Task TryRemoveDocumentAsync(TModel model); + + Task TryRemoveDocumentsAsync(IEnumerable models); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Initializers/IAzureInitializer.cs b/src/Cogworks.AzureSearch/Interfaces/Initializers/IAzureInitializer.cs deleted file mode 100644 index bc728f0..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Initializers/IAzureInitializer.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Interfaces.Initializers -{ - public interface IAzureInitializer where TAzureModel : class, IAzureModel, new() - { - Task InitializeAsync(); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Initializers/IInitializer.cs b/src/Cogworks.AzureSearch/Interfaces/Initializers/IInitializer.cs new file mode 100644 index 0000000..e1d0f9e --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Initializers/IInitializer.cs @@ -0,0 +1,10 @@ +using Cogworks.AzureSearch.Models; +using System.Threading.Tasks; + +namespace Cogworks.AzureSearch.Interfaces.Initializers +{ + public interface IInitializer where TModel : class, IModel, new() + { + Task InitializeAsync(); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureDocumentOperation.cs b/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureDocumentOperation.cs deleted file mode 100644 index 3d8ab88..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureDocumentOperation.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Interfaces.Operations -{ - public interface IAzureDocumentOperation where TAzureModel : class, IAzureModel, new() - { - Task AddOrUpdateDocumentAsync(TAzureModel model); - - Task AddOrUpdateDocumentsAsync(IEnumerable models); - - Task TryRemoveDocumentAsync(TAzureModel model); - - Task TryRemoveDocumentsAsync(IEnumerable models); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureIndexOperation.cs b/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureIndexOperation.cs deleted file mode 100644 index 6e31944..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Operations/IAzureIndexOperation.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; - -namespace Cogworks.AzureSearch.Interfaces.Operations -{ - public interface IAzureIndexOperation where TAzureModel : class, IAzureModel, new() - { - Task IndexExistsAsync(); - - Task IndexDeleteAsync(); - - Task IndexCreateOrUpdateAsync(); - - Task IndexClearAsync(); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Operations/IDocumentOperation.cs b/src/Cogworks.AzureSearch/Interfaces/Operations/IDocumentOperation.cs new file mode 100644 index 0000000..a619035 --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Operations/IDocumentOperation.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Interfaces.Operations +{ + public interface IDocumentOperation where TModel : class, IModel, new() + { + Task AddOrUpdateDocumentAsync(TModel model); + + Task AddOrUpdateDocumentsAsync(IEnumerable models); + + Task TryRemoveDocumentAsync(TModel model); + + Task TryRemoveDocumentsAsync(IEnumerable models); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Operations/IIndexOperation.cs b/src/Cogworks.AzureSearch/Interfaces/Operations/IIndexOperation.cs new file mode 100644 index 0000000..0b7115d --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Operations/IIndexOperation.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Cogworks.AzureSearch.Models; + +namespace Cogworks.AzureSearch.Interfaces.Operations +{ + public interface IIndexOperation where TModel : class, IModel, new() + { + Task IndexExistsAsync(); + + Task IndexDeleteAsync(); + + Task IndexCreateOrUpdateAsync(); + + Task IndexClearAsync(); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Repositories/IAzureSearchRepository.cs b/src/Cogworks.AzureSearch/Interfaces/Repositories/IAzureSearchRepository.cs deleted file mode 100644 index 0d902e5..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Repositories/IAzureSearchRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Cogworks.AzureSearch.Interfaces.Operations; -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Models; - -namespace Cogworks.AzureSearch.Interfaces.Repositories -{ - public interface IAzureSearchRepository : - IAzureDocumentOperation, - IAzureIndexOperation, - IAzureDocumentSearch - where TAzureModel : class, IAzureModel, new() - { - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Repositories/IRepository.cs b/src/Cogworks.AzureSearch/Interfaces/Repositories/IRepository.cs new file mode 100644 index 0000000..5dcabfa --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Repositories/IRepository.cs @@ -0,0 +1,14 @@ +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Models; + +namespace Cogworks.AzureSearch.Interfaces.Repositories +{ + public interface IRepository : + IDocumentOperation, + IIndexOperation, + ISearcher + where TModel : class, IModel, new() + { + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureDocumentSearch.cs b/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureDocumentSearch.cs deleted file mode 100644 index b7d94a6..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureDocumentSearch.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Cogworks.AzureSearch.Models; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Interfaces.Searches -{ - public interface IAzureDocumentSearch where TAzureModel : class, IAzureModel, new() - { - Models.Dtos.SearchResult Search(string keyword, AzureSearchParameters azureSearchParameters); - - Task> SearchAsync(string keyword, AzureSearchParameters azureSearchParameters); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureSearch.cs b/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureSearch.cs deleted file mode 100644 index 35f6955..0000000 --- a/src/Cogworks.AzureSearch/Interfaces/Searches/IAzureSearch.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Interfaces.Searches -{ - public interface IAzureSearch where TAzureModel : class, IAzureModel, new() - { - SearchResult Search(string keyword, AzureSearchParameters azureSearchParameters); - - Task> SearchAsync(string keyword, AzureSearchParameters azureSearchParameters); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Searches/ISearcher.cs b/src/Cogworks.AzureSearch/Interfaces/Searches/ISearcher.cs new file mode 100644 index 0000000..9fa663e --- /dev/null +++ b/src/Cogworks.AzureSearch/Interfaces/Searches/ISearcher.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Interfaces.Searches +{ + public interface ISearcher where TModel : class, IModel, new() + { + SearchResult Search(string keyword, SearchParameters searchParameters); + + Task> SearchAsync(string keyword, SearchParameters searchParameters); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Wrappers/IDocumentOperationWrapper.cs b/src/Cogworks.AzureSearch/Interfaces/Wrappers/IDocumentOperationWrapper.cs index 773116b..bc09f32 100644 --- a/src/Cogworks.AzureSearch/Interfaces/Wrappers/IDocumentOperationWrapper.cs +++ b/src/Cogworks.AzureSearch/Interfaces/Wrappers/IDocumentOperationWrapper.cs @@ -1,15 +1,17 @@ -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search.Models; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Azure; +using Azure.Search.Documents; +using Azure.Search.Documents.Models; +using Cogworks.AzureSearch.Models; namespace Cogworks.AzureSearch.Interfaces.Wrappers { - public interface IDocumentOperationWrapper where TAzureModel : class, IAzureModel, new() + public interface IDocumentOperationWrapper where TModel : class, IModel, new() { - DocumentSearchResult Search(string searchText, SearchParameters parameters = null); + SearchResults Search(string searchText, SearchOptions parameters = null); - Task> SearchAsync(string searchText, SearchParameters parameters = null); + Task> SearchAsync(string searchText, SearchOptions parameters = null); - Task IndexAsync(IndexBatch indexBatch); + Task> IndexAsync(IndexDocumentsBatch indexBatch); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Interfaces/Wrappers/IIndexOperationWrapper.cs b/src/Cogworks.AzureSearch/Interfaces/Wrappers/IIndexOperationWrapper.cs index b477e66..6210d44 100644 --- a/src/Cogworks.AzureSearch/Interfaces/Wrappers/IIndexOperationWrapper.cs +++ b/src/Cogworks.AzureSearch/Interfaces/Wrappers/IIndexOperationWrapper.cs @@ -1,8 +1,6 @@ -using System.Collections; -using System.Collections.Generic; +using System.Threading.Tasks; +using Azure.Search.Documents.Indexes.Models; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search.Models; -using System.Threading.Tasks; namespace Cogworks.AzureSearch.Interfaces.Wrappers { @@ -12,8 +10,8 @@ public interface IIndexOperationWrapper Task DeleteAsync(string indexName); - Task CreateOrUpdateAsync(string indexName) where TAzureModel : class, IAzureModel, new(); + Task CreateOrUpdateAsync(string indexName) where TModel : class, IModel, new(); - Task CreateOrUpdateAsync(Index customIndexDefinition, bool overrideFields) where TAzureModel : class, IAzureModel, new(); + Task CreateOrUpdateAsync(SearchIndex customIndexDefinition, bool overrideFields) where TModel : class, IModel, new(); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Mappers/ParametersMapper.cs b/src/Cogworks.AzureSearch/Mappers/ParametersMapper.cs new file mode 100644 index 0000000..f860f83 --- /dev/null +++ b/src/Cogworks.AzureSearch/Mappers/ParametersMapper.cs @@ -0,0 +1,74 @@ +using Azure.Search.Documents; +using Azure.Search.Documents.Models; +using Cogworks.AzureSearch.Enums; +using Cogworks.AzureSearch.Extensions; +using Cogworks.AzureSearch.Models; + +namespace Cogworks.AzureSearch.Mappers +{ + public static class ParametersMapper + { + internal static SearchOptions Map(SearchParameters searchParameters) + { + var searchOptions = new SearchOptions + { + Filter = searchParameters.Filter, + HighlightPostTag = searchParameters.HighlightPostTag, + HighlightPreTag = searchParameters.HighlightPreTag, + IncludeTotalCount = searchParameters.IncludeTotalResultCount, + MinimumCoverage = searchParameters.MinimumCoverage, + QueryType = searchParameters.QueryType == AzureQueryType.Full + ? SearchQueryType.Full + : SearchQueryType.Simple, + ScoringProfile = searchParameters.ScoringProfile, + SearchMode = searchParameters.SearchMode == AzureSearchModeType.Any + ? SearchMode.Any + : SearchMode.All, + Skip = searchParameters.Skip, + Size = searchParameters.Take + }; + + if (searchParameters.Select.HasAny()) + { + foreach (var selectField in searchParameters.Select) + { + searchOptions.Select.Add(selectField); + } + } + + if (searchParameters.SearchFields.HasAny()) + { + foreach (var searchField in searchParameters.SearchFields) + { + searchOptions.SearchFields.Add(searchField); + } + } + + if (searchParameters.HighlightFields.HasAny()) + { + foreach (var highlightField in searchParameters.HighlightFields) + { + searchOptions.HighlightFields.Add(highlightField); + } + } + + if (searchParameters.Facets.HasAny()) + { + foreach (var facet in searchParameters.Facets) + { + searchOptions.Facets.Add(facet); + } + } + + if (searchParameters.OrderBy.HasAny()) + { + foreach (var order in searchParameters.OrderBy) + { + searchOptions.OrderBy.Add(order); + } + } + + return searchOptions; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Mappers/SearchResultMapper.cs b/src/Cogworks.AzureSearch/Mappers/SearchResultMapper.cs new file mode 100644 index 0000000..f0c26d9 --- /dev/null +++ b/src/Cogworks.AzureSearch/Mappers/SearchResultMapper.cs @@ -0,0 +1,32 @@ +using System.Linq; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Mappers +{ + public static class SearchResultMapper + { + public static SearchResult Map( + Azure.Search.Documents.Models.SearchResults results, + int skip, + int take) where TModel : class, IModel, new() + { + var resultsCount = results.TotalCount ?? 0; + + var searchedDocuments = results.GetResults() + .Select(resultDocument => new SearchResultItem( + resultDocument.Document, + resultDocument.Highlights, + resultDocument.Score ?? default + )) + .ToArray(); + + return new SearchResult() + { + HasMoreItems = skip + take < resultsCount, + TotalCount = resultsCount, + Results = searchedDocuments + }; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/AzureIndexDefinition.cs b/src/Cogworks.AzureSearch/Models/AzureIndexDefinition.cs deleted file mode 100644 index 72026d3..0000000 --- a/src/Cogworks.AzureSearch/Models/AzureIndexDefinition.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Runtime.CompilerServices; -using Microsoft.Azure.Search.Models; - -namespace Cogworks.AzureSearch.Models -{ - public class AzureIndexDefinition where TAzureModel : class, IAzureModel, new() - { - public string IndexName { get; } - - public Index CustomIndexDefinition { get; } - - public AzureIndexDefinition(string indexName) - => IndexName = indexName; - - public AzureIndexDefinition(Index customIndex) - => (CustomIndexDefinition, IndexName) = (customIndex, customIndex.Name); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/Dtos/AzureBatchDocumentsOperationResult.cs b/src/Cogworks.AzureSearch/Models/Dtos/AzureBatchDocumentsOperationResult.cs deleted file mode 100644 index 18bbc85..0000000 --- a/src/Cogworks.AzureSearch/Models/Dtos/AzureBatchDocumentsOperationResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Cogworks.AzureSearch.Models.Dtos -{ - public class AzureBatchDocumentsOperationResult - { - public bool Succeeded { get; set; } - - public string Message { get; set; } - - public IEnumerable SucceededDocuments { get; set; } = Enumerable.Empty(); - - public IEnumerable FailedDocuments { get; set; } = Enumerable.Empty(); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/Dtos/BatchDocumentsOperationResult.cs b/src/Cogworks.AzureSearch/Models/Dtos/BatchDocumentsOperationResult.cs new file mode 100644 index 0000000..1ce391f --- /dev/null +++ b/src/Cogworks.AzureSearch/Models/Dtos/BatchDocumentsOperationResult.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Cogworks.AzureSearch.Models.Dtos +{ + public class BatchDocumentsOperationResult + { + public bool Succeeded { get; set; } + + public string Message { get; set; } + + public IEnumerable SucceededDocuments { get; set; } = Enumerable.Empty(); + + public IEnumerable FailedDocuments { get; set; } = Enumerable.Empty(); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/Dtos/AzureDocumentOperationResult.cs b/src/Cogworks.AzureSearch/Models/Dtos/DocumentOperationResult.cs similarity index 72% rename from src/Cogworks.AzureSearch/Models/Dtos/AzureDocumentOperationResult.cs rename to src/Cogworks.AzureSearch/Models/Dtos/DocumentOperationResult.cs index 43d8c04..2db601c 100644 --- a/src/Cogworks.AzureSearch/Models/Dtos/AzureDocumentOperationResult.cs +++ b/src/Cogworks.AzureSearch/Models/Dtos/DocumentOperationResult.cs @@ -1,6 +1,6 @@ namespace Cogworks.AzureSearch.Models.Dtos { - public class AzureDocumentOperationResult + public class DocumentOperationResult { public bool Succeeded { get; set; } @@ -8,6 +8,8 @@ public class AzureDocumentOperationResult public string Message { get; set; } + public string InnerMessage { get; set; } + public int StatusCode { get; set; } } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/Dtos/AzureIndexOperationResult.cs b/src/Cogworks.AzureSearch/Models/Dtos/IndexOperationResult.cs similarity index 77% rename from src/Cogworks.AzureSearch/Models/Dtos/AzureIndexOperationResult.cs rename to src/Cogworks.AzureSearch/Models/Dtos/IndexOperationResult.cs index d7202d9..2200949 100644 --- a/src/Cogworks.AzureSearch/Models/Dtos/AzureIndexOperationResult.cs +++ b/src/Cogworks.AzureSearch/Models/Dtos/IndexOperationResult.cs @@ -1,6 +1,6 @@ namespace Cogworks.AzureSearch.Models.Dtos { - public class AzureIndexOperationResult + public class IndexOperationResult { public bool Succeeded { get; set; } diff --git a/src/Cogworks.AzureSearch/Models/Dtos/SearchResult.cs b/src/Cogworks.AzureSearch/Models/Dtos/SearchResult.cs index ae9906c..0a30132 100644 --- a/src/Cogworks.AzureSearch/Models/Dtos/SearchResult.cs +++ b/src/Cogworks.AzureSearch/Models/Dtos/SearchResult.cs @@ -2,7 +2,7 @@ namespace Cogworks.AzureSearch.Models.Dtos { - public class SearchResult where TModel : class, IAzureModel, new() + public class SearchResult where TModel : class, IModel, new() { public long TotalCount { get; set; } diff --git a/src/Cogworks.AzureSearch/Models/Dtos/SearchResultItem.cs b/src/Cogworks.AzureSearch/Models/Dtos/SearchResultItem.cs index 7baba89..ae977cd 100644 --- a/src/Cogworks.AzureSearch/Models/Dtos/SearchResultItem.cs +++ b/src/Cogworks.AzureSearch/Models/Dtos/SearchResultItem.cs @@ -2,7 +2,7 @@ namespace Cogworks.AzureSearch.Models.Dtos { - public class SearchResultItem where TModel : class, IAzureModel, new() + public class SearchResultItem where TModel : class, IModel, new() { public TModel Document { get; } diff --git a/src/Cogworks.AzureSearch/Models/IAzureModel.cs b/src/Cogworks.AzureSearch/Models/IModel.cs similarity index 62% rename from src/Cogworks.AzureSearch/Models/IAzureModel.cs rename to src/Cogworks.AzureSearch/Models/IModel.cs index e54c5bd..bfe8fc7 100644 --- a/src/Cogworks.AzureSearch/Models/IAzureModel.cs +++ b/src/Cogworks.AzureSearch/Models/IModel.cs @@ -1,6 +1,6 @@ namespace Cogworks.AzureSearch.Models { - public interface IAzureModel + public interface IModel { } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/IAzureModelIdentity.cs b/src/Cogworks.AzureSearch/Models/IModelIdentity.cs similarity index 61% rename from src/Cogworks.AzureSearch/Models/IAzureModelIdentity.cs rename to src/Cogworks.AzureSearch/Models/IModelIdentity.cs index aba8890..1d909cd 100644 --- a/src/Cogworks.AzureSearch/Models/IAzureModelIdentity.cs +++ b/src/Cogworks.AzureSearch/Models/IModelIdentity.cs @@ -1,6 +1,6 @@ namespace Cogworks.AzureSearch.Models { - public interface IAzureModelIdentity : IAzureModel + public interface IModelIdentity : IModel { string Id { get; set; } } diff --git a/src/Cogworks.AzureSearch/Models/IndexDefinition.cs b/src/Cogworks.AzureSearch/Models/IndexDefinition.cs new file mode 100644 index 0000000..7c0458b --- /dev/null +++ b/src/Cogworks.AzureSearch/Models/IndexDefinition.cs @@ -0,0 +1,17 @@ +using Azure.Search.Documents.Indexes.Models; + +namespace Cogworks.AzureSearch.Models +{ + public class IndexDefinition where TModel : class, IModel, new() + { + public string IndexName { get; } + + public SearchIndex CustomIndexDefinition { get; } + + public IndexDefinition(string indexName) + => IndexName = indexName; + + public IndexDefinition(SearchIndex customIndex) + => (CustomIndexDefinition, IndexName) = (customIndex, customIndex.Name); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Models/AzureSearchParameters.cs b/src/Cogworks.AzureSearch/Models/SearchParameters.cs similarity index 58% rename from src/Cogworks.AzureSearch/Models/AzureSearchParameters.cs rename to src/Cogworks.AzureSearch/Models/SearchParameters.cs index 8bef2ab..4dfdd42 100644 --- a/src/Cogworks.AzureSearch/Models/AzureSearchParameters.cs +++ b/src/Cogworks.AzureSearch/Models/SearchParameters.cs @@ -1,17 +1,17 @@ -using Cogworks.AzureSearch.Enums; -using System.Collections.Generic; +using System.Collections.Generic; +using Cogworks.AzureSearch.Enums; namespace Cogworks.AzureSearch.Models { - public class AzureSearchParameters + public class SearchParameters { public bool IncludeTotalResultCount { get; set; } - public IList Facets { get; set; } + public IEnumerable Facets { get; set; } public string Filter { get; set; } - public IList HighlightFields { get; set; } + public IEnumerable HighlightFields { get; set; } public string HighlightPostTag { get; set; } @@ -19,17 +19,17 @@ public class AzureSearchParameters public double? MinimumCoverage { get; set; } - public IList OrderBy { get; set; } + public IEnumerable OrderBy { get; set; } public AzureQueryType QueryType { get; set; } public string ScoringProfile { get; set; } - public IList SearchFields { get; set; } + public IEnumerable SearchFields { get; set; } public AzureSearchModeType SearchMode { get; set; } - public IList Select { get; set; } + public IEnumerable Select { get; set; } public int Skip { get; set; } diff --git a/src/Cogworks.AzureSearch/Operations/DocumentOperation.cs b/src/Cogworks.AzureSearch/Operations/DocumentOperation.cs new file mode 100644 index 0000000..72e69c4 --- /dev/null +++ b/src/Cogworks.AzureSearch/Operations/DocumentOperation.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Azure.Search.Documents.Models; +using Cogworks.AzureSearch.Exceptions.DocumentsExceptions; +using Cogworks.AzureSearch.Extensions; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Operations +{ + public class DocumentOperation : IDocumentOperation + where TModel : class, IModel, new() + { + private readonly IDocumentOperationWrapper _documentOperationWrapper; + + private const int BatchOperationSize = 500; + + public DocumentOperation(IDocumentOperationWrapper documentOperationWrapper) + => _documentOperationWrapper = documentOperationWrapper; + + public async Task AddOrUpdateDocumentAsync(TModel model) + { + var azureBatchDocumentsOperationResult = await AddOrUpdateDocumentsAsync(new[] { model }); + + return azureBatchDocumentsOperationResult.Succeeded + ? azureBatchDocumentsOperationResult.SucceededDocuments.FirstOrDefault() + : azureBatchDocumentsOperationResult.FailedDocuments.FirstOrDefault(); + } + + public async Task AddOrUpdateDocumentsAsync(IEnumerable models) + { + if (!models.HasAny()) + { + return new BatchDocumentsOperationResult() + { + Succeeded = true, + Message = "No documents found to index." + }; + } + + var chunkedBatchActions = models + .Select(IndexDocumentsAction.MergeOrUpload) + .ChunkBy(BatchOperationSize) + .ToList(); + + var indexResults = new List(); + + foreach (var batchActions in chunkedBatchActions) + { + var batch = IndexDocumentsBatch.Create(batchActions.ToArray()); + + try + { + var result = await _documentOperationWrapper.IndexAsync(batch); + indexResults.AddRange(result.Value.Results); + } + catch (Exception exception) + { + throw new AddOrUpdateDocumentException(exception.Message, exception.InnerException); + } + } + + return GetBatchOperationStatus(indexResults, "adding or updating"); + } + + public async Task TryRemoveDocumentAsync(TModel model) + { + var azureBatchDocumentsOperationResult = await TryRemoveDocumentsAsync(new[] { model }); + + return azureBatchDocumentsOperationResult.Succeeded + ? azureBatchDocumentsOperationResult.SucceededDocuments.FirstOrDefault() + : azureBatchDocumentsOperationResult.FailedDocuments.FirstOrDefault(); + } + + public async Task TryRemoveDocumentsAsync(IEnumerable models) + { + if (!models.HasAny()) + { + return new BatchDocumentsOperationResult() + { + Succeeded = true, + Message = "No documents found to delete." + }; + } + + var chunkedBatchActions = models + .Select(IndexDocumentsAction.Delete) + .ChunkBy(BatchOperationSize) + .ToList(); + + var indexResults = new List(); + + foreach (var batchActions in chunkedBatchActions) + { + var batch = IndexDocumentsBatch.Create(batchActions.ToArray()); + + try + { + var result = await _documentOperationWrapper.IndexAsync(batch); + indexResults.AddRange(result.Value.Results); + } + catch (Exception exception) + { + throw new RemoveDocumentException(exception.Message, exception.InnerException); + } + } + + return GetBatchOperationStatus(indexResults, "removing"); + } + + private static BatchDocumentsOperationResult GetBatchOperationStatus(IEnumerable indexingResults, string operationType) + { + var successfullyItems = indexingResults.Where(x => x.Succeeded).ToList(); + var failedItems = indexingResults.Where(x => !x.Succeeded).ToList(); + + return new BatchDocumentsOperationResult + { + Succeeded = !failedItems.Any(), + SucceededDocuments = successfullyItems.Select(successfullyItem => new DocumentOperationResult + { + Succeeded = true, + Message = $"Successfully {operationType} document.", + ModelId = successfullyItem.Key, + StatusCode = successfullyItem.Status + }).ToList(), + FailedDocuments = failedItems.Select(failedItem => new DocumentOperationResult + { + Message = $"Failed {operationType} document.", + InnerMessage = failedItem.ErrorMessage, + ModelId = failedItem.Key, + StatusCode = failedItem.Status + }).ToList() + }; + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Operations/IndexOperation.cs b/src/Cogworks.AzureSearch/Operations/IndexOperation.cs new file mode 100644 index 0000000..e4a7acb --- /dev/null +++ b/src/Cogworks.AzureSearch/Operations/IndexOperation.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading.Tasks; +using Cogworks.AzureSearch.Exceptions.IndexExceptions; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Models; + +namespace Cogworks.AzureSearch.Operations +{ + public class IndexOperation : IIndexOperation + where TModel : class, IModel, new() + { + private readonly IndexDefinition _indexDefinition; + private readonly IIndexOperationWrapper _indexOperationWrapper; + + public IndexOperation( + IndexDefinition indexDefinition, + IIndexOperationWrapper indexOperationWrapper) + { + _indexDefinition = indexDefinition; + _indexOperationWrapper = indexOperationWrapper; + } + + public async Task IndexExistsAsync() + { + try + { + return await _indexOperationWrapper.ExistsAsync(_indexDefinition.IndexName); + } + catch (Exception exception) + { + throw new IndexExistsException(exception.Message, exception.InnerException); + } + } + + public async Task IndexDeleteAsync() + { + try + { + await _indexOperationWrapper.DeleteAsync(_indexDefinition.IndexName); + } + catch (Exception exception) + { + throw new IndexDeleteException(exception.Message, exception.InnerException); + } + } + + public async Task IndexCreateOrUpdateAsync() + { + try + { + + _ = _indexDefinition.CustomIndexDefinition != null + ? await _indexOperationWrapper.CreateOrUpdateAsync(_indexDefinition.CustomIndexDefinition, true) + : await _indexOperationWrapper.CreateOrUpdateAsync(_indexDefinition.IndexName); + + } + catch (Exception exception) + { + throw new IndexCreateOrUpdateException(exception.Message, exception.InnerException); + + } + } + + public async Task IndexClearAsync() + { + try + { + if (await IndexExistsAsync()) + { + await IndexDeleteAsync(); + } + + await IndexCreateOrUpdateAsync(); + } + catch (Exception exception) + { + throw new IndexClearException(exception.Message, exception.InnerException); + } + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Options/AzureSearchClientOption.cs b/src/Cogworks.AzureSearch/Options/AzureSearchClientOption.cs deleted file mode 100644 index 044bc0d..0000000 --- a/src/Cogworks.AzureSearch/Options/AzureSearchClientOption.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.Azure.Search; - -namespace Cogworks.AzureSearch.Options -{ - public class AzureSearchClientOption - { - public string ServiceName { get; } - - public string Credentials { get; } - - public AzureSearchClientOption(string serviceName, string credentials) - { - ServiceName = serviceName; - Credentials = credentials; - } - - public SearchServiceClient GetSearchServiceClient() - => new SearchServiceClient( - ServiceName, - new SearchCredentials(Credentials)); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Options/ClientOption.cs b/src/Cogworks.AzureSearch/Options/ClientOption.cs new file mode 100644 index 0000000..76c76b2 --- /dev/null +++ b/src/Cogworks.AzureSearch/Options/ClientOption.cs @@ -0,0 +1,44 @@ +using Azure.Core; +using Azure.Core.Pipeline; +using Azure.Search.Documents; + +namespace Cogworks.AzureSearch.Options +{ + public class ClientOption + { + public string ServiceName { get; } + + public string Credentials { get; } + + public string ServiceUrlEndpoint { get; } + + public SearchClientOptions ClientOptions { get; } + + public ClientOption(string serviceName, string credentials, string serviceUrlEndpoint) + { + ServiceName = serviceName; + Credentials = credentials; + ServiceUrlEndpoint = serviceUrlEndpoint; + ClientOptions = GetOptions(); + } + + private static SearchClientOptions GetOptions() + { + var clientOptions = new SearchClientOptions(); + + clientOptions.AddPolicy( + new SearchIdPipelinePolicy(), + HttpPipelinePosition.PerCall); + + return clientOptions; + } + + private class SearchIdPipelinePolicy : HttpPipelineSynchronousPolicy + { + public override void OnSendingRequest(HttpMessage message) + => message.Request + .Headers + .SetValue("x-ms-azs-return-searchid", "true"); + } + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Options/AzureSearchIndexOption.cs b/src/Cogworks.AzureSearch/Options/IndexOption.cs similarity index 68% rename from src/Cogworks.AzureSearch/Options/AzureSearchIndexOption.cs rename to src/Cogworks.AzureSearch/Options/IndexOption.cs index 4c664d4..8b6d549 100644 --- a/src/Cogworks.AzureSearch/Options/AzureSearchIndexOption.cs +++ b/src/Cogworks.AzureSearch/Options/IndexOption.cs @@ -1,12 +1,12 @@ namespace Cogworks.AzureSearch.Options { - public class AzureSearchIndexOption + public class IndexOption { public bool Recreate { get; } public bool RecreateOnUpdateFailure { get; } - public AzureSearchIndexOption(bool recreate, bool recreateOnUpdateFailure) + public IndexOption(bool recreate, bool recreateOnUpdateFailure) { Recreate = recreate; RecreateOnUpdateFailure = recreateOnUpdateFailure; diff --git a/src/Cogworks.AzureSearch/Repositories/AzureSearchRepository.cs b/src/Cogworks.AzureSearch/Repositories/AzureSearchRepository.cs deleted file mode 100644 index b790963..0000000 --- a/src/Cogworks.AzureSearch/Repositories/AzureSearchRepository.cs +++ /dev/null @@ -1,303 +0,0 @@ -using Cogworks.AzureSearch.Extensions; -using Cogworks.AzureSearch.Interfaces.Repositories; -using Cogworks.AzureSearch.Interfaces.Wrappers; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using Microsoft.Azure.Search; -using Microsoft.Azure.Search.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Repositories -{ - internal class AzureSearchRepository : IAzureSearchRepository - where TAzureModel : class, IAzureModel, new() - { - private readonly AzureIndexDefinition _azureIndexDefinition; - private readonly IIndexOperationWrapper _indexOperationWrapper; - private readonly IDocumentOperationWrapper _documentOperationWrapper; - - private const int BatchOperationSize = 500; - - public AzureSearchRepository( - AzureIndexDefinition azureIndexDefinition, - IIndexOperationWrapper indexOperationWrapper, - IDocumentOperationWrapper documentOperationWrapper) - { - _azureIndexDefinition = azureIndexDefinition; - _indexOperationWrapper = indexOperationWrapper; - _documentOperationWrapper = documentOperationWrapper; - } - - public async Task IndexExistsAsync() - => await _indexOperationWrapper.ExistsAsync(_azureIndexDefinition.IndexName); - - public async Task IndexDeleteAsync() - { - var result = new AzureIndexOperationResult(); - - try - { - await _indexOperationWrapper.DeleteAsync(_azureIndexDefinition.IndexName); - - result.Succeeded = true; - result.Message = $"Index {_azureIndexDefinition.IndexName} successfully deleted."; - } - catch (Exception e) - { - result.Message = $"An issue occurred on deleting index: {_azureIndexDefinition.IndexName}. More information: {e.Message}"; - } - - return result; - } - - // TODO: add throwing domain exception on exception instead of returning dto - public async Task IndexCreateOrUpdateAsync() - { - var result = new AzureIndexOperationResult(); - - try - { - - var createdIndex = _azureIndexDefinition.CustomIndexDefinition != null - ? await _indexOperationWrapper.CreateOrUpdateAsync(_azureIndexDefinition.CustomIndexDefinition, true) - : await _indexOperationWrapper.CreateOrUpdateAsync(_azureIndexDefinition.IndexName) ; - - result.Message = $"Index {_azureIndexDefinition.IndexName} successfully created or updated."; - result.Succeeded = true; - } - catch (Exception exception) - { - result.Message = $"An issue occurred on creating or updating index: {_azureIndexDefinition.IndexName}. More information: {exception.Message}"; - } - - return result; - } - - public async Task IndexClearAsync() - { - try - { - if (await IndexExistsAsync()) - { - var deleteOperationResult = await IndexDeleteAsync(); - - if (!deleteOperationResult.Succeeded) - { - return new AzureIndexOperationResult - { - Succeeded = false, - Message = $"An issue occurred on clearing index: {_azureIndexDefinition.IndexName}. Could not delete existing index." - }; - } - } - } - catch (Exception) - { - // ignore - } - - var indexCreateOrUpdateResult = await IndexCreateOrUpdateAsync(); - - return new AzureIndexOperationResult - { - Succeeded = indexCreateOrUpdateResult.Succeeded, - Message = indexCreateOrUpdateResult.Succeeded - ? $"Index {_azureIndexDefinition.IndexName} successfully cleared." - : $"An issue occurred on clearing index: {_azureIndexDefinition.IndexName}. Could not create index." - }; - } - - public async Task AddOrUpdateDocumentAsync(TAzureModel model) - { - var azureBatchDocumentsOperationResult = await AddOrUpdateDocumentsAsync(new[] { model }); - - return azureBatchDocumentsOperationResult.Succeeded - ? azureBatchDocumentsOperationResult.SucceededDocuments.FirstOrDefault() - : azureBatchDocumentsOperationResult.FailedDocuments.FirstOrDefault(); - } - - public async Task AddOrUpdateDocumentsAsync(IEnumerable models) - { - if (!models.HasAny()) - { - return new AzureBatchDocumentsOperationResult() - { - Succeeded = true, - Message = "No documents found to index." - }; - } - - var chunkedBatchActions = models - .Select(model => new IndexAction(model, IndexActionType.Upload)) - .ChunkBy(BatchOperationSize) - .ToList(); - - var indexResults = new List(); - - foreach (var batchActions in chunkedBatchActions) - { - var batch = IndexBatch.New(batchActions); - - try - { - var result = await _documentOperationWrapper.IndexAsync(batch); - indexResults.AddRange(result.Results); - } - catch (IndexBatchException indexBatchException) - { - indexResults.AddRange(indexBatchException.IndexingResults); - } - catch (Exception exception) - { - // todo: handle it proper - } - } - - return GetBatchOperationStatus(indexResults, "adding or updating"); - } - - public async Task TryRemoveDocumentAsync(TAzureModel model) - { - var azureBatchDocumentsOperationResult = await TryRemoveDocumentsAsync(new[] { model }); - - return azureBatchDocumentsOperationResult.Succeeded - ? azureBatchDocumentsOperationResult.SucceededDocuments.FirstOrDefault() - : azureBatchDocumentsOperationResult.FailedDocuments.FirstOrDefault(); - } - - public async Task TryRemoveDocumentsAsync(IEnumerable models) - { - if (!models.HasAny()) - { - return new AzureBatchDocumentsOperationResult() - { - Succeeded = true, - Message = "No documents found to delete." - }; - } - - var chunkedBatchActions = models - .Select(model => new IndexAction(model, IndexActionType.Delete)) - .ChunkBy(BatchOperationSize) - .ToList(); - - var indexResults = new List(); - - foreach (var batchActions in chunkedBatchActions) - { - var batch = IndexBatch.New(batchActions); - - try - { - var result = await _documentOperationWrapper.IndexAsync(batch); - indexResults.AddRange(result.Results); - } - catch (IndexBatchException indexBatchException) - { - indexResults.AddRange(indexBatchException.IndexingResults); - } - catch (Exception exception) - { - // todo: handle it proper - } - } - - return GetBatchOperationStatus(indexResults, "removing"); - } - - public Models.Dtos.SearchResult Search(string keyword, AzureSearchParameters azureSearchParameters) - { - var searchText = GetSearchText(keyword); - var parameters = GetSearchParameters(azureSearchParameters); - var results = _documentOperationWrapper.Search($"{searchText}", parameters); - - return GetSearchResult(results, azureSearchParameters.Skip, azureSearchParameters.Take); - } - - public async Task> SearchAsync(string keyword, - AzureSearchParameters azureSearchParameters) - { - var searchText = GetSearchText(keyword); - var parameters = GetSearchParameters(azureSearchParameters); - var results = await _documentOperationWrapper.SearchAsync($"{searchText}", parameters); - - return GetSearchResult(results, azureSearchParameters.Skip, azureSearchParameters.Take); - } - - private static string GetSearchText(string keyword) - => keyword.EscapeHyphen().HasValue() - ? keyword.EscapeHyphen() - : "*"; - - private static SearchParameters GetSearchParameters(AzureSearchParameters azureSearchParameters) - => new SearchParameters - { - Facets = azureSearchParameters.Facets, - Filter = azureSearchParameters.Filter, - HighlightFields = azureSearchParameters.HighlightFields, - HighlightPostTag = azureSearchParameters.HighlightPostTag, - HighlightPreTag = azureSearchParameters.HighlightPreTag, - IncludeTotalResultCount = azureSearchParameters.IncludeTotalResultCount, - MinimumCoverage = azureSearchParameters.MinimumCoverage, - OrderBy = azureSearchParameters.OrderBy, - QueryType = azureSearchParameters.QueryType == Enums.AzureQueryType.Full - ? QueryType.Full - : QueryType.Simple, - ScoringProfile = azureSearchParameters.ScoringProfile, - SearchFields = azureSearchParameters.SearchFields, - SearchMode = azureSearchParameters.SearchMode == Enums.AzureSearchModeType.Any - ? SearchMode.Any - : SearchMode.All, - Select = azureSearchParameters.Select, - Skip = azureSearchParameters.Skip, - Top = azureSearchParameters.Take - }; - - private Models.Dtos.SearchResult GetSearchResult(DocumentSearchResult results, int skip, int take) - { - var resultsCount = results.Count ?? 0; - - var searchedDocuments = results.Results - .Select(resultDocument => new SearchResultItem( - resultDocument.Document, - resultDocument.Highlights, - resultDocument.Score - )) - .ToArray(); - - return new Models.Dtos.SearchResult() - { - HasMoreItems = skip + take < resultsCount, - TotalCount = resultsCount, - Results = searchedDocuments - }; - } - - private AzureBatchDocumentsOperationResult GetBatchOperationStatus(IEnumerable indexingResults, string operationType) - { - var successfullyItems = indexingResults.Where(x => x.Succeeded).ToList(); - var failedItems = indexingResults.Where(x => !x.Succeeded).ToList(); - - return new AzureBatchDocumentsOperationResult - { - Succeeded = !failedItems.Any(), - SucceededDocuments = successfullyItems.Select(successfullyItem => new AzureDocumentOperationResult - { - Succeeded = true, - Message = $"Successfully {operationType} document.", - ModelId = successfullyItem.Key, - StatusCode = successfullyItem.StatusCode - }).ToList(), - FailedDocuments = failedItems.Select(failedItem => new AzureDocumentOperationResult - { - Message = $"Failed {operationType} document.", - ModelId = failedItem.Key, - StatusCode = failedItem.StatusCode - }).ToList(), - }; - } - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Repositories/Repository.cs b/src/Cogworks.AzureSearch/Repositories/Repository.cs new file mode 100644 index 0000000..587b1b5 --- /dev/null +++ b/src/Cogworks.AzureSearch/Repositories/Repository.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Repositories; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Repositories +{ + internal class Repository : IRepository + where TModel : class, IModel, new() + { + private readonly IIndexOperation _indexOperation; + private readonly IDocumentOperation _documentOperation; + private readonly ISearcher _search; + + public Repository( + IIndexOperation indexOperation, + IDocumentOperation documentOperation, + ISearcher search) + { + _indexOperation = indexOperation; + _documentOperation = documentOperation; + _search = search; + } + + public async Task AddOrUpdateDocumentAsync(TModel model) + => await _documentOperation.AddOrUpdateDocumentAsync(model); + + public async Task AddOrUpdateDocumentsAsync(IEnumerable models) + => await _documentOperation.AddOrUpdateDocumentsAsync(models); + + public async Task TryRemoveDocumentAsync(TModel model) + => await _documentOperation.TryRemoveDocumentAsync(model); + + public async Task TryRemoveDocumentsAsync(IEnumerable models) + => await _documentOperation.TryRemoveDocumentsAsync(models); + + public async Task IndexExistsAsync() + => await _indexOperation.IndexExistsAsync(); + + public async Task IndexDeleteAsync() + => await _indexOperation.IndexDeleteAsync(); + + public async Task IndexCreateOrUpdateAsync() + => await _indexOperation.IndexCreateOrUpdateAsync(); + + public async Task IndexClearAsync() + => await _indexOperation.IndexClearAsync(); + + public SearchResult Search(string keyword, SearchParameters searchParameters) + => _search.Search(keyword, searchParameters); + + public async Task> SearchAsync(string keyword, + SearchParameters searchParameters) + => await _search.SearchAsync(keyword, searchParameters); + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Searchers/AzureSearch.cs b/src/Cogworks.AzureSearch/Searchers/AzureSearch.cs deleted file mode 100644 index fb16f7c..0000000 --- a/src/Cogworks.AzureSearch/Searchers/AzureSearch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Cogworks.AzureSearch.Interfaces.Searches; -using Cogworks.AzureSearch.Models; -using Cogworks.AzureSearch.Models.Dtos; -using System.Threading.Tasks; - -namespace Cogworks.AzureSearch.Searchers -{ - public class AzureSearch : IAzureSearch - where TAzureModel : class, IAzureModel, new() - { - private readonly IAzureDocumentSearch _azureSearchRepository; - - public AzureSearch(IAzureDocumentSearch azureSearchRepository) - => _azureSearchRepository = azureSearchRepository; - - public SearchResult Search(string keyword, AzureSearchParameters azureSearchParameters) - => _azureSearchRepository.Search(keyword, azureSearchParameters); - - public async Task> SearchAsync(string keyword, AzureSearchParameters azureSearchParameters) - => await _azureSearchRepository.SearchAsync(keyword, azureSearchParameters); - } -} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Searchers/BaseDomainSearch.cs b/src/Cogworks.AzureSearch/Searchers/BaseDomainSearch.cs new file mode 100644 index 0000000..3767fd4 --- /dev/null +++ b/src/Cogworks.AzureSearch/Searchers/BaseDomainSearch.cs @@ -0,0 +1,22 @@ +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; +using System.Threading.Tasks; + +namespace Cogworks.AzureSearch.Searchers +{ + public abstract class BaseDomainSearch + where TModel : class, IModel, new() + { + protected ISearcher Searcher { get; } + + protected BaseDomainSearch(ISearcher search) + => Searcher = search; + + public virtual SearchResult Search(string keyword, SearchParameters searchParameters) + => Searcher.Search(keyword, searchParameters); + + public async Task> SearchAsync(string keyword, SearchParameters searchParameters) + => await Searcher.SearchAsync(keyword, searchParameters); + } +} diff --git a/src/Cogworks.AzureSearch/Searchers/Searcher.cs b/src/Cogworks.AzureSearch/Searchers/Searcher.cs new file mode 100644 index 0000000..5774cc6 --- /dev/null +++ b/src/Cogworks.AzureSearch/Searchers/Searcher.cs @@ -0,0 +1,48 @@ +using System.Threading.Tasks; +using Cogworks.AzureSearch.Extensions; +using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Interfaces.Wrappers; +using Cogworks.AzureSearch.Mappers; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Models.Dtos; + +namespace Cogworks.AzureSearch.Searchers +{ + internal class Searcher : ISearcher + where TModel : class, IModel, new() + { + private readonly IDocumentOperationWrapper _documentOperationWrapper; + + public Searcher(IDocumentOperationWrapper documentOperationWrapper) + => _documentOperationWrapper = documentOperationWrapper; + + public SearchResult Search(string keyword, SearchParameters searchParameters) + { + var searchText = GetSearchText(keyword); + var parameters = ParametersMapper.Map(searchParameters); + var results = _documentOperationWrapper.Search($"{searchText}", parameters); + + return SearchResultMapper.Map( + results, + searchParameters.Skip, + searchParameters.Take); + } + + public async Task> SearchAsync(string keyword, SearchParameters searchParameters) + { + var searchText = GetSearchText(keyword); + var parameters = ParametersMapper.Map(searchParameters); + var results = await _documentOperationWrapper.SearchAsync(searchText, parameters); + + return SearchResultMapper.Map( + results, + searchParameters.Skip, + searchParameters.Take); + } + + private static string GetSearchText(string keyword) + => keyword.EscapeHyphen().HasValue() + ? keyword.EscapeHyphen() + : "*"; + } +} \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Wrappers/DocumentOperationWrapper.cs b/src/Cogworks.AzureSearch/Wrappers/DocumentOperationWrapper.cs index fba1cda..7b4a3c1 100644 --- a/src/Cogworks.AzureSearch/Wrappers/DocumentOperationWrapper.cs +++ b/src/Cogworks.AzureSearch/Wrappers/DocumentOperationWrapper.cs @@ -1,30 +1,42 @@ -using Cogworks.AzureSearch.Interfaces.Wrappers; + +using System; +using System.Threading.Tasks; +using Azure; +using Azure.Search.Documents; +using Azure.Search.Documents.Models; +using Cogworks.AzureSearch.Interfaces.Wrappers; using Cogworks.AzureSearch.Models; using Cogworks.AzureSearch.Options; -using Microsoft.Azure.Search; -using Microsoft.Azure.Search.Models; -using System.Threading.Tasks; namespace Cogworks.AzureSearch.Wrappers { - internal class DocumentOperationWrapper : IDocumentOperationWrapper - where TAzureModel : class, IAzureModel, new() + internal class DocumentOperationWrapper : IDocumentOperationWrapper + where TModel : class, IModel, new() { - private readonly IDocumentsOperations _documentOperation; + private readonly SearchClient _searchClient; + + public DocumentOperationWrapper( + IndexDefinition indexDefinition, + ClientOption clientOption) + { + var azureKeyCredential = new AzureKeyCredential(clientOption.Credentials); + + _searchClient = new SearchClient( + endpoint: new Uri(clientOption.ServiceUrlEndpoint), + indexName: indexDefinition.IndexName, + credential: azureKeyCredential, + options: clientOption.ClientOptions - public DocumentOperationWrapper(AzureIndexDefinition azureIndexDefinition, AzureSearchClientOption azureSearchClientOption) - => _documentOperation = azureSearchClientOption.GetSearchServiceClient() - .Indexes - .GetClient(azureIndexDefinition.IndexName) - .Documents; + ); + } - public DocumentSearchResult Search(string searchText, SearchParameters parameters = null) - => _documentOperation.Search(searchText, parameters); + public SearchResults Search(string searchText, SearchOptions parameters = null) + => _searchClient.Search(searchText, parameters); - public async Task> SearchAsync(string searchText, SearchParameters parameters = null) - => await _documentOperation.SearchAsync(searchText, parameters); + public async Task> SearchAsync(string searchText, SearchOptions parameters = null) + => await _searchClient.SearchAsync(searchText, parameters); - public async Task IndexAsync(IndexBatch indexBatch) - => await _documentOperation.IndexAsync(indexBatch); + public async Task> IndexAsync(IndexDocumentsBatch indexBatch) + => await _searchClient.IndexDocumentsAsync(indexBatch); } } \ No newline at end of file diff --git a/src/Cogworks.AzureSearch/Wrappers/IndexOperationWrapper.cs b/src/Cogworks.AzureSearch/Wrappers/IndexOperationWrapper.cs index a30e497..d974320 100644 --- a/src/Cogworks.AzureSearch/Wrappers/IndexOperationWrapper.cs +++ b/src/Cogworks.AzureSearch/Wrappers/IndexOperationWrapper.cs @@ -1,48 +1,56 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; +using System; +using System.Threading.Tasks; +using Azure; +using Azure.Search.Documents.Indexes; +using Azure.Search.Documents.Indexes.Models; using Cogworks.AzureSearch.Interfaces.Wrappers; using Cogworks.AzureSearch.Models; using Cogworks.AzureSearch.Options; -using Microsoft.Azure.Search; -using Microsoft.Azure.Search.Models; -using System.Threading.Tasks; namespace Cogworks.AzureSearch.Wrappers { internal class IndexOperationWrapper : IIndexOperationWrapper { - private readonly IIndexesOperations _indexOperation; + private readonly SearchIndexClient _searchIndexClient; - public IndexOperationWrapper(AzureSearchClientOption azureSearchClientOption) - => _indexOperation = azureSearchClientOption.GetSearchServiceClient().Indexes; + public IndexOperationWrapper(ClientOption clientOption) + { + var azureKeyCredential = new AzureKeyCredential(clientOption.Credentials); + + _searchIndexClient = new SearchIndexClient( + endpoint: new Uri(clientOption.ServiceUrlEndpoint), + credential: azureKeyCredential); + } public async Task ExistsAsync(string indexName) - => await _indexOperation.ExistsAsync(indexName); + => (await _searchIndexClient.GetIndexAsync(indexName)).Value != null; public async Task DeleteAsync(string indexName) - => await _indexOperation.DeleteAsync(indexName); + => await _searchIndexClient.DeleteIndexAsync(indexName); - public async Task CreateOrUpdateAsync(string indexName) where TAzureModel : class, IAzureModel, new() + public async Task CreateOrUpdateAsync(string indexName) where TModel : class, IModel, new() { - var indexDefinition = new Index - { - Name = indexName, - Fields = FieldBuilder.BuildForType(), + var fieldBuilder = new FieldBuilder(); + var searchFields = fieldBuilder.Build(typeof(TModel)); - }; + var definition = new SearchIndex( + indexName, + searchFields); - return await _indexOperation.CreateOrUpdateAsync(indexDefinition); + return await _searchIndexClient.CreateOrUpdateIndexAsync(definition); } - public async Task CreateOrUpdateAsync(Index customIndexDefinition, bool overrideFields = true) where TAzureModel : class, IAzureModel, new() + public async Task CreateOrUpdateAsync(SearchIndex customIndexDefinition, bool overrideFields) where TModel : class, IModel, new() { if (overrideFields) { - customIndexDefinition.Fields = FieldBuilder.BuildForType(); + var fieldBuilder = new FieldBuilder(); + var searchFields = fieldBuilder.Build(typeof(TModel)); + + customIndexDefinition.Fields = searchFields; } - return await _indexOperation.CreateOrUpdateAsync(customIndexDefinition); + return await _searchIndexClient.CreateOrUpdateIndexAsync(customIndexDefinition); } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/AutofacIocExtensionTests.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/AutofacIocExtensionTests.cs index ec981c2..e0e52fd 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/AutofacIocExtensionTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/AutofacIocExtensionTests.cs @@ -1,6 +1,5 @@ -using Autofac; +using AutofacContainerBuilder = Autofac.ContainerBuilder; using Cogworks.AzureSearch.Autofac.Extensions; -using Cogworks.AzureSearch.Builder; using Cogworks.AzureSearch.Interfaces.Indexes; using Cogworks.AzureSearch.Interfaces.Initializers; using Cogworks.AzureSearch.Interfaces.Operations; @@ -9,18 +8,19 @@ using Cogworks.AzureSearch.Models; using NSubstitute; using System; +using Autofac; using Cogworks.AzureSearch.AutofacIoc.UnitTests.Models; using Cogworks.AzureSearch.AutofacIoc.UnitTests.Searchers; -using Microsoft.Azure.Search.Models; using Xunit; -using Index = Microsoft.Azure.Search.Models.Index; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Interfaces.Builder; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests { public class AutofacIocExtensionTests { - private readonly IAzureSearchBuilder _azureSearchBuilder; - private readonly ContainerBuilder _containerBuilder; + private readonly IContainerBuilder _containerBuilder; + private readonly AutofacContainerBuilder _autofacContainerBuilder; private const string FirstDocumentIndexName = "first-test-document"; private const string SecondDocumentIndexName = "second-test-document"; @@ -28,44 +28,41 @@ public class AutofacIocExtensionTests public AutofacIocExtensionTests() { - _containerBuilder = new ContainerBuilder(); + _autofacContainerBuilder = new AutofacContainerBuilder(); - _azureSearchBuilder = _containerBuilder.RegisterAzureSearch() - .RegisterClientOptions("test", "test") + _containerBuilder = _autofacContainerBuilder.RegisterAzureSearch() + .RegisterClientOptions("test", "test", "https://localhost") .RegisterIndexOptions(false, false) .RegisterIndexDefinitions(FirstDocumentIndexName) .RegisterIndexDefinitions(SecondDocumentIndexName) - .RegisterIndexDefinitions(customIndex: new Index { Name = ThirdDocumentIndexName }); + .RegisterIndexDefinitions(customIndex: new SearchIndex(ThirdDocumentIndexName)); } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) { // Arrange // ReSharper disable once PossibleNullReferenceException - using (var scope = _containerBuilder.Build().BeginLifetimeScope().BeginLifetimeScope()) + using (var scope = _autofacContainerBuilder.Build().BeginLifetimeScope().BeginLifetimeScope()) { // Act var instance = scope.Resolve(desiredObjectType); @@ -79,27 +76,24 @@ public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectType) { // Arrange @@ -111,13 +105,12 @@ public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectTyp } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ThrowException_When_IndexNotRegistered(Type desiredObjectType) { // NotRegisteredTestDocumentModel @@ -127,7 +120,7 @@ public void Should_ThrowException_When_IndexNotRegistered(Type desiredObjectType var exceptionRecord = Record.Exception(() => { // ReSharper disable once PossibleNullReferenceException - using (var scope = _containerBuilder.Build().BeginLifetimeScope()) + using (var scope = _autofacContainerBuilder.Build().BeginLifetimeScope()) { // Act _ = scope.Resolve(desiredObjectType); @@ -153,15 +146,18 @@ public void Should_Not_ThrowException_When_GettingCustomSearchService() public void Should_ReturnCustomSearchService() { // Arrange - _azureSearchBuilder.RegisterDomainSearcher(); + _containerBuilder.RegisterDomainSearcher(); // ReSharper disable once PossibleNullReferenceException - using (var scope = _containerBuilder.Build().BeginLifetimeScope()) + using (var scope = _autofacContainerBuilder.Build().BeginLifetimeScope()) { + var customTestSearch = scope.Resolve(); // Assert Assert.NotNull(customTestSearch); + + } } @@ -171,10 +167,10 @@ public void Should_InvokeCustomSearchServiceDomainMethod() // Arrange var mockedCustomTestSearch = Substitute.For(); - _azureSearchBuilder.RegisterDomainSearcher(mockedCustomTestSearch); + _containerBuilder.RegisterDomainSearcher(mockedCustomTestSearch); // ReSharper disable once PossibleNullReferenceException - using (var scope = _containerBuilder.Build().BeginLifetimeScope()) + using (var scope = _autofacContainerBuilder.Build().BeginLifetimeScope()) { var customTestSearch = scope.Resolve(); @@ -209,11 +205,11 @@ public void Should_GetDedicatedIndexWithProperName() // Act // ReSharper disable once PossibleNullReferenceException - using (var scope = _containerBuilder.Build().BeginLifetimeScope()) + using (var scope = _autofacContainerBuilder.Build().BeginLifetimeScope()) { - var firstTestDocumentIndexDefinition = scope.Resolve>(); - var secondTestDocumentIndexDefinition = scope.Resolve>(); - var thirdTestDocumentIndexDefinition = scope.Resolve>(); + var firstTestDocumentIndexDefinition = scope.Resolve>(); + var secondTestDocumentIndexDefinition = scope.Resolve>(); + var thirdTestDocumentIndexDefinition = scope.Resolve>(); // Assert Assert.NotNull(firstTestDocumentIndexDefinition); diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests.csproj b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests.csproj index 6474551..cfc453a 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests.csproj +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests.csproj @@ -37,6 +37,5 @@ - \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/FirstTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/FirstTestDocumentModel.cs index a7cbf3a..885507a 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/FirstTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/FirstTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests.Models { - public class FirstTestDocumentModel : IAzureModel + public class FirstTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs index 0d7c116..ceb0260 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests.Models { - public class NotRegisteredTestDocumentModel : IAzureModel + public class NotRegisteredTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/SecondTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/SecondTestDocumentModel.cs index d3d8715..df0eaf3 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/SecondTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/SecondTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests.Models { - public class SecondTestDocumentModel : IAzureModel + public class SecondTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/ThirdTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/ThirdTestDocumentModel.cs index 32f03e9..e5d407c 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/ThirdTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Models/ThirdTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests.Models { - public class ThirdTestDocumentModel : IAzureModel + public class ThirdTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Searchers/CustomTestSearch.cs b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Searchers/CustomTestSearch.cs index a85711d..6fb7151 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Searchers/CustomTestSearch.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.AutofacIoc.UnitTests/Searchers/CustomTestSearch.cs @@ -1,5 +1,6 @@ using Cogworks.AzureSearch.AutofacIoc.UnitTests.Models; using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Searchers; namespace Cogworks.AzureSearch.AutofacIoc.UnitTests.Searchers { @@ -8,9 +9,9 @@ public interface ICustomTestSearch void SomeCustomSearchExample(); } - public class CustomTestSearch : AzureSearch.Searchers.AzureSearch, ICustomTestSearch + public class CustomTestSearch : BaseDomainSearch, ICustomTestSearch { - public CustomTestSearch(IAzureDocumentSearch azureSearchRepository) : base(azureSearchRepository) + public CustomTestSearch(ISearcher search) : base(search) { } @@ -20,7 +21,7 @@ public void SomeCustomSearchExample() // ... // End of custom filters - // _ = base.Search("test", new AzureSearchParameters()); + // _ = base.Search("test", new SearchParameters()); } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Cogworks.AzureSearch.LightInject.UnitTests.csproj b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Cogworks.AzureSearch.LightInject.UnitTests.csproj index 41f91f0..5eb1c65 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Cogworks.AzureSearch.LightInject.UnitTests.csproj +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Cogworks.AzureSearch.LightInject.UnitTests.csproj @@ -36,6 +36,5 @@ - \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/LightInjectIocExtensionTests.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/LightInjectIocExtensionTests.cs index a21403a..99bfc92 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/LightInjectIocExtensionTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/LightInjectIocExtensionTests.cs @@ -1,5 +1,4 @@ -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Indexes; using Cogworks.AzureSearch.Interfaces.Initializers; using Cogworks.AzureSearch.Interfaces.Operations; using Cogworks.AzureSearch.Interfaces.Repositories; @@ -11,14 +10,15 @@ using LightInject; using NSubstitute; using System; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Interfaces.Builder; using Xunit; -using Index = Microsoft.Azure.Search.Models.Index; namespace Cogworks.AzureSearch.LightInject.UnitTests { public class LightInjectIocExtensionTests { - private readonly IAzureSearchBuilder _azureSearchBuilder; + private readonly IContainerBuilder _containerBuilder; private readonly IServiceContainer _container; private const string FirstDocumentIndexName = "first-test-document"; @@ -29,36 +29,33 @@ public LightInjectIocExtensionTests() { _container = new ServiceContainer(); - _azureSearchBuilder = _container.RegisterAzureSearch() - .RegisterClientOptions("test", "test") + _containerBuilder = _container.RegisterAzureSearch() + .RegisterClientOptions("test", "test", "https://localhost") .RegisterIndexOptions(false, false) .RegisterIndexDefinitions(FirstDocumentIndexName) .RegisterIndexDefinitions(SecondDocumentIndexName) - .RegisterIndexDefinitions(customIndex: new Index { Name = ThirdDocumentIndexName }); ; + .RegisterIndexDefinitions(customIndex: new SearchIndex(ThirdDocumentIndexName)); ; } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) { // Arrange @@ -78,27 +75,24 @@ public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectType) { // Arrange @@ -110,13 +104,12 @@ public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectTyp } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ThrowException_When_IndexNotRegistered(Type desiredObjectType) { // Arrange @@ -150,7 +143,7 @@ public void Should_Not_ThrowException_When_GettingCustomSearchService() public void Should_ReturnCustomSearchService() { // Arrange - _azureSearchBuilder.RegisterDomainSearcher(); + _containerBuilder.RegisterDomainSearcher(); // ReSharper disable once PossibleNullReferenceException using (var scope = _container.BeginScope()) @@ -168,7 +161,7 @@ public void Should_InvokeCustomSearchServiceDomainMethod() // Arrange var mockedCustomTestSearch = Substitute.For(); - _azureSearchBuilder.RegisterDomainSearcher(mockedCustomTestSearch); + _containerBuilder.RegisterDomainSearcher(mockedCustomTestSearch); // ReSharper disable once PossibleNullReferenceException using (var scope = _container.BeginScope()) @@ -208,9 +201,9 @@ public void Should_GetDedicatedIndexWithProperName() // ReSharper disable once PossibleNullReferenceException using (var scope = _container.BeginScope()) { - var firstTestDocumentIndexDefinition = scope.GetInstance>(); - var secondTestDocumentIndexDefinition = scope.GetInstance>(); - var thirdTestDocumentIndexDefinition = scope.GetInstance>(); + var firstTestDocumentIndexDefinition = scope.GetInstance>(); + var secondTestDocumentIndexDefinition = scope.GetInstance>(); + var thirdTestDocumentIndexDefinition = scope.GetInstance>(); // Assert Assert.NotNull(firstTestDocumentIndexDefinition); diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/FirstTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/FirstTestDocumentModel.cs index b0e2e35..f695fb0 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/FirstTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/FirstTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.LightInject.UnitTests.Models { - public class FirstTestDocumentModel : IAzureModel + public class FirstTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/NotRegistredTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/NotRegistredTestDocumentModel.cs index 2442364..211e1e2 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/NotRegistredTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/NotRegistredTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.LightInject.UnitTests.Models { - public class NotRegisteredTestDocumentModel : IAzureModel + public class NotRegisteredTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/SecondTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/SecondTestDocumentModel.cs index dfe1aef..8cfe990 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/SecondTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/SecondTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.LightInject.UnitTests.Models { - public class SecondTestDocumentModel : IAzureModel + public class SecondTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/ThirdTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/ThirdTestDocumentModel.cs index 0c3f998..86ac7b6 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/ThirdTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Models/ThirdTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.LightInject.UnitTests.Models { - public class ThirdTestDocumentModel : IAzureModel + public class ThirdTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Searchers/CustomTestSearch.cs b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Searchers/CustomTestSearch.cs index 408aa3e..a1ba737 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Searchers/CustomTestSearch.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.LightInject.UnitTests/Searchers/CustomTestSearch.cs @@ -1,5 +1,6 @@ using Cogworks.AzureSearch.Interfaces.Searches; using Cogworks.AzureSearch.LightInject.UnitTests.Models; +using Cogworks.AzureSearch.Searchers; namespace Cogworks.AzureSearch.LightInject.UnitTests.Searchers { @@ -8,9 +9,9 @@ public interface ICustomTestSearch void SomeCustomSearchExample(); } - public class CustomTestSearch : AzureSearch.Searchers.AzureSearch, ICustomTestSearch + public class CustomTestSearch : BaseDomainSearch, ICustomTestSearch { - public CustomTestSearch(IAzureDocumentSearch azureSearchRepository) : base(azureSearchRepository) + public CustomTestSearch(ISearcher search) : base(search) { } @@ -20,7 +21,7 @@ public void SomeCustomSearchExample() // ... // End of custom filters - // _ = base.Search("test", new AzureSearchParameters()); + // _ = base.Search("test", new SearchParameters()); } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests.csproj b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests.csproj index 9708802..494fc15 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests.csproj +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests.csproj @@ -37,6 +37,5 @@ - \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/MicrosoftIocExtensionTests.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/MicrosoftIocExtensionTests.cs index cd0aefb..52289aa 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/MicrosoftIocExtensionTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/MicrosoftIocExtensionTests.cs @@ -1,5 +1,4 @@ -using Cogworks.AzureSearch.Builder; -using Cogworks.AzureSearch.Interfaces.Indexes; +using Cogworks.AzureSearch.Interfaces.Indexes; using Cogworks.AzureSearch.Interfaces.Initializers; using Cogworks.AzureSearch.Interfaces.Operations; using Cogworks.AzureSearch.Interfaces.Repositories; @@ -9,16 +8,17 @@ using Microsoft.Extensions.DependencyInjection; using NSubstitute; using System; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Interfaces.Builder; using Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models; using Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Searchers; using Xunit; -using Index = Microsoft.Azure.Search.Models.Index; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests { public class MicrosoftIocExtensionTests { - private readonly IAzureSearchBuilder _azureSearchBuilder; + private readonly IContainerBuilder _containerBuilder; private readonly IServiceCollection _serviceContainer; private const string FirstDocumentIndexName = "first-test-document"; @@ -29,36 +29,33 @@ public MicrosoftIocExtensionTests() { _serviceContainer = new ServiceCollection(); - _azureSearchBuilder = _serviceContainer.RegisterAzureSearch() - .RegisterClientOptions("test", "test") + _containerBuilder = _serviceContainer.RegisterAzureSearch() + .RegisterClientOptions("test", "test", "https://localhost") .RegisterIndexOptions(false, false) .RegisterIndexDefinitions(FirstDocumentIndexName) .RegisterIndexDefinitions(SecondDocumentIndexName) - .RegisterIndexDefinitions(customIndex: new Index { Name = ThirdDocumentIndexName }); + .RegisterIndexDefinitions(customIndex: new SearchIndex(ThirdDocumentIndexName)); } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) { // Arrange @@ -78,27 +75,24 @@ public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectType) { // Arrange @@ -110,13 +104,12 @@ public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectTyp } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ThrowException_When_IndexNotRegistered(Type desiredObjectType) { // NotRegisteredTestDocumentModel @@ -152,7 +145,7 @@ public void Should_Not_ThrowException_When_GettingCustomSearchService() public void Should_ReturnCustomSearchService() { // Arrange - _azureSearchBuilder.RegisterDomainSearcher(); + _containerBuilder.RegisterDomainSearcher(); // ReSharper disable once PossibleNullReferenceException using (var serviceProvider = _serviceContainer.BuildServiceProvider()) @@ -170,7 +163,7 @@ public void Should_InvokeCustomSearchServiceDomainMethod() // Arrange var mockedCustomTestSearch = Substitute.For(); - _azureSearchBuilder.RegisterDomainSearcher(mockedCustomTestSearch); + _containerBuilder.RegisterDomainSearcher(mockedCustomTestSearch); // ReSharper disable once PossibleNullReferenceException using (var serviceProvider = _serviceContainer.BuildServiceProvider()) @@ -210,9 +203,9 @@ public void Should_GetDedicatedIndexWithProperName() // ReSharper disable once PossibleNullReferenceException using (var serviceProvider = _serviceContainer.BuildServiceProvider()) { - var firstTestDocumentIndexDefinition = serviceProvider.GetService>(); - var secondTestDocumentIndexDefinition = serviceProvider.GetService>(); - var thirdTestDocumentIndexDefinition = serviceProvider.GetService>(); + var firstTestDocumentIndexDefinition = serviceProvider.GetService>(); + var secondTestDocumentIndexDefinition = serviceProvider.GetService>(); + var thirdTestDocumentIndexDefinition = serviceProvider.GetService>(); // Assert Assert.NotNull(firstTestDocumentIndexDefinition); diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/FirstTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/FirstTestDocumentModel.cs index 6d1dae5..d7e0167 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/FirstTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/FirstTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models { - public class FirstTestDocumentModel : IAzureModel + public class FirstTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs index 8aeb17b..1fed359 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models { - public class NotRegisteredTestDocumentModel : IAzureModel + public class NotRegisteredTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/SecondTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/SecondTestDocumentModel.cs index c13b11d..cdc0813 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/SecondTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/SecondTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models { - public class SecondTestDocumentModel : IAzureModel + public class SecondTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/ThirdTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/ThirdTestDocumentModel.cs index 623bd62..52be652 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/ThirdTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Models/ThirdTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models { - public class ThirdTestDocumentModel : IAzureModel + public class ThirdTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Searchers/CustomTestSearch.cs b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Searchers/CustomTestSearch.cs index 5f1475c..f648c39 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Searchers/CustomTestSearch.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.MicrosoftIoc.UnitTests/Searchers/CustomTestSearch.cs @@ -1,5 +1,6 @@ using Cogworks.AzureSearch.Interfaces.Searches; using Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Models; +using Cogworks.AzureSearch.Searchers; namespace Cogworks.AzureSearch.MicrosoftIoc.UnitTests.Searchers { @@ -8,9 +9,9 @@ public interface ICustomTestSearch void SomeCustomSearchExample(); } - public class CustomTestSearch : AzureSearch.Searchers.AzureSearch, ICustomTestSearch + public class CustomTestSearch : BaseDomainSearch, ICustomTestSearch { - public CustomTestSearch(IAzureDocumentSearch azureSearchRepository) : base(azureSearchRepository) + public CustomTestSearch(ISearcher search) : base(search) { } @@ -20,7 +21,7 @@ public void SomeCustomSearchExample() // ... // End of custom filters - // _ = base.Search("test", new AzureSearchParameters()); + // _ = base.Search("test", new SearchParameters()); } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests.csproj b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests.csproj index 5411aca..bafac6e 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests.csproj +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests.csproj @@ -15,7 +15,7 @@ Properties Cogworks.AzureSearch.UmbracoIoc.UnitTests Cogworks.AzureSearch.UmbracoIoc.UnitTests - v4.8 + v4.7.2 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15.0 @@ -50,6 +50,12 @@ ..\..\..\packages\AutoFixture.AutoNSubstitute.4.13.0\lib\net452\AutoFixture.AutoNSubstitute.dll + + ..\..\..\packages\Azure.Core.1.9.0\lib\net461\Azure.Core.dll + + + ..\..\..\packages\Azure.Search.Documents.11.2.0\lib\netstandard2.0\Azure.Search.Documents.dll + ..\..\..\packages\DotLiquid.2.0.333\lib\net45\DotLiquid.dll @@ -74,17 +80,8 @@ ..\..\..\packages\Microsoft.AspNet.Identity.Core.2.2.2\lib\net45\Microsoft.AspNet.Identity.Core.dll - - ..\..\..\packages\Microsoft.Azure.Search.10.1.0\lib\net461\Microsoft.Azure.Search.dll - - - ..\..\..\packages\Microsoft.Azure.Search.Common.10.1.0\lib\net461\Microsoft.Azure.Search.Common.dll - - - ..\..\..\packages\Microsoft.Azure.Search.Data.10.1.0\lib\net461\Microsoft.Azure.Search.Data.dll - - - ..\..\..\packages\Microsoft.Azure.Search.Service.10.1.0\lib\net461\Microsoft.Azure.Search.Service.dll + + ..\..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -96,9 +93,6 @@ ..\..\..\packages\Microsoft.Rest.ClientRuntime.2.3.20\lib\net461\Microsoft.Rest.ClientRuntime.dll - - ..\..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.18\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll - ..\..\..\packages\Microsoft.Spatial.7.5.3\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll @@ -169,6 +163,9 @@ ..\..\..\packages\Superpower.2.0.0\lib\net45\Superpower.dll + + ..\..\..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll @@ -183,29 +180,54 @@ ..\..\..\packages\Umbraco.SqlServerCE.4.0.0.1\lib\net472\System.Data.SqlServerCe.Entity.dll - - ..\..\..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll + + ..\..\..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + ..\..\..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + ..\..\..\packages\System.Memory.Data.1.0.1\lib\net461\System.Memory.Data.dll + ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + ..\..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + ..\..\..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll + + ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True True + + ..\..\..\packages\System.Text.Encodings.Web.4.6.0\lib\netstandard2.0\System.Text.Encodings.Web.dll + + + ..\..\..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll + + + ..\..\..\packages\System.Threading.Channels.4.6.0\lib\netstandard2.0\System.Threading.Channels.dll + + + ..\..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + ..\..\..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll @@ -230,13 +252,7 @@ - - - - - - - + @@ -252,7 +268,7 @@ Cogworks.AzureSearch.Umbraco.IocExtension - {64b55c63-5070-430f-a92d-747ff2cd57a6} + {94f77e26-4e02-4ed5-bd54-45e3aaa70090} Cogworks.AzureSearch diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/FirstTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/FirstTestDocumentModel.cs index 392acc6..f8490c4 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/FirstTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/FirstTestDocumentModel.cs @@ -1,15 +1,17 @@ -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; +using Cogworks.AzureSearch.Models; namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests.Models { - public class FirstTestDocumentModel : IAzureModel + public class FirstTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs index 281b7dc..a3c14e7 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/NotRegistredTestDocumentModel.cs @@ -1,15 +1,17 @@ -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; +using Cogworks.AzureSearch.Models; namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests.Models { - public class NotRegisteredTestDocumentModel : IAzureModel + public class NotRegisteredTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/SecondTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/SecondTestDocumentModel.cs index 76a2040..0b526e9 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/SecondTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/SecondTestDocumentModel.cs @@ -1,15 +1,17 @@ -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; +using Cogworks.AzureSearch.Models; namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests.Models { - public class SecondTestDocumentModel : IAzureModel + public class SecondTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/ThirdTestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/ThirdTestDocumentModel.cs index 59fdf9f..a22238a 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/ThirdTestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Models/ThirdTestDocumentModel.cs @@ -1,15 +1,17 @@ -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests.Models { - public class ThirdTestDocumentModel : IAzureModel + public class ThirdTestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Properties/AssemblyInfo.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Properties/AssemblyInfo.cs index ace1062..546bb9b 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Properties/AssemblyInfo.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("Cogworks.AzureSearch.UmbracoIoc.UnitTests")] diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Searchers/CustomTestSearch.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Searchers/CustomTestSearch.cs index 0c5fb4d..5b54c5b 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Searchers/CustomTestSearch.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/Searchers/CustomTestSearch.cs @@ -1,4 +1,5 @@ using Cogworks.AzureSearch.Interfaces.Searches; +using Cogworks.AzureSearch.Searchers; using Cogworks.AzureSearch.UmbracoIoc.UnitTests.Models; namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests.Searchers @@ -8,9 +9,9 @@ public interface ICustomTestSearch void SomeCustomSearchExample(); } - public class CustomTestSearch : AzureSearch.Searchers.AzureSearch, ICustomTestSearch + public class CustomTestSearch : BaseDomainSearch, ICustomTestSearch { - public CustomTestSearch(IAzureDocumentSearch azureSearchRepository) : base(azureSearchRepository) + public CustomTestSearch(ISearcher search) : base(search) { } @@ -20,7 +21,7 @@ public void SomeCustomSearchExample() // ... // End of custom filters - // _ = base.Search("test", new AzureSearchParameters()); + // _ = base.Search("test", new SearchParameters()); } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/UmbracoIocExtensionTests.cs b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/UmbracoIocExtensionTests.cs index d0c86c9..6f87448 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/UmbracoIocExtensionTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/UmbracoIocExtensionTests.cs @@ -1,5 +1,5 @@ // ReSharper disable PossibleNullReferenceException -using Cogworks.AzureSearch.Builder; + using Cogworks.AzureSearch.Interfaces.Indexes; using Cogworks.AzureSearch.Interfaces.Initializers; using Cogworks.AzureSearch.Interfaces.Operations; @@ -12,7 +12,8 @@ using LightInject; using NSubstitute; using System; -using Microsoft.Azure.Search.Models; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Interfaces.Builder; using Umbraco.Core.Composing; using Umbraco.Core.Composing.LightInject; using Xunit; @@ -21,7 +22,7 @@ namespace Cogworks.AzureSearch.UmbracoIoc.UnitTests { public class UmbracoIocExtensionTests { - private readonly IAzureSearchBuilder _azureSearchBuilder; + private readonly IContainerBuilder _containerBuilder; private readonly Composition _composing; private const string FirstDocumentIndexName = "first-test-document"; @@ -34,38 +35,35 @@ public UmbracoIocExtensionTests() _composing = new Composition(lightInjectContainer, null, null, null, null); - _azureSearchBuilder = _composing.RegisterAzureSearch() - .RegisterClientOptions("test", "test") + _containerBuilder = _composing.RegisterAzureSearch() + .RegisterClientOptions("test", "test", "https://localhost") .RegisterIndexOptions(false, false) .RegisterIndexDefinitions(FirstDocumentIndexName) .RegisterIndexDefinitions(SecondDocumentIndexName) - .RegisterIndexDefinitions(customIndex: new Index { Name = ThirdDocumentIndexName }); + .RegisterIndexDefinitions(customIndex: new SearchIndex(ThirdDocumentIndexName)); } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) { // Arrange @@ -85,27 +83,24 @@ public void Should_ReturnDedicatedRepositoryInstance(Type desiredObjectType) } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectType) { // Arrange @@ -117,13 +112,12 @@ public void Should_Not_ThrowException_When_IndexRegistered(Type desiredObjectTyp } [Theory] - [InlineData(typeof(IAzureSearchRepository))] - [InlineData(typeof(IAzureIndexOperation))] - [InlineData(typeof(IAzureDocumentOperation))] - [InlineData(typeof(IAzureDocumentSearch))] - [InlineData(typeof(IAzureIndex))] - [InlineData(typeof(IAzureInitializer))] - [InlineData(typeof(IAzureSearch))] + [InlineData(typeof(IRepository))] + [InlineData(typeof(IIndexOperation))] + [InlineData(typeof(IDocumentOperation))] + [InlineData(typeof(IIndex))] + [InlineData(typeof(IInitializer))] + [InlineData(typeof(ISearcher))] public void Should_ThrowException_When_IndexNotRegistered(Type desiredObjectType) { // Arrange @@ -158,7 +152,7 @@ public void Should_Not_ThrowException_When_GettingCustomSearchService() public void Should_ReturnCustomSearchService() { // Arrange - _azureSearchBuilder.RegisterDomainSearcher(); + _containerBuilder.RegisterDomainSearcher(); var container = _composing.Concrete as ServiceContainer as IServiceContainer; @@ -177,7 +171,7 @@ public void Should_InvokeCustomSearchServiceDomainMethod() // Arrange var mockedCustomTestSearch = Substitute.For(); - _azureSearchBuilder.RegisterDomainSearcher(mockedCustomTestSearch); + _containerBuilder.RegisterDomainSearcher(mockedCustomTestSearch); var container = _composing.Concrete as ServiceContainer as IServiceContainer; @@ -219,9 +213,9 @@ public void Should_GetDedicatedIndexWithProperName() using (var scope = container.BeginScope()) { - var firstTestDocumentIndexDefinition = scope.GetInstance>(); - var secondTestDocumentIndexDefinition = scope.GetInstance>(); - var thirdTestDocumentIndexDefinition = scope.GetInstance>(); + var firstTestDocumentIndexDefinition = scope.GetInstance>(); + var secondTestDocumentIndexDefinition = scope.GetInstance>(); + var thirdTestDocumentIndexDefinition = scope.GetInstance>(); // Assert Assert.NotNull(firstTestDocumentIndexDefinition); diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/app.config b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/app.config index fcc6ad7..0a5f76e 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/app.config +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/app.config @@ -10,6 +10,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/packages.config b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/packages.config index 56aa20e..b911f8d 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/packages.config +++ b/tests/UnitTests/Cogworks.AzureSearch.UmbracoIoc.UnitTests/packages.config @@ -1,60 +1,67 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Cogworks.AzureSearch.UnitTests.csproj b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Cogworks.AzureSearch.UnitTests.csproj index feddd21..b1ab222 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Cogworks.AzureSearch.UnitTests.csproj +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Cogworks.AzureSearch.UnitTests.csproj @@ -6,6 +6,18 @@ false + + + + + + + + + + + + @@ -36,10 +48,4 @@ - - - - - - \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestDocumentModel.cs b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestDocumentModel.cs index 61a95e2..d79bc8a 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestDocumentModel.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestDocumentModel.cs @@ -1,15 +1,17 @@ -using Cogworks.AzureSearch.Models; -using Microsoft.Azure.Search; -using System.ComponentModel.DataAnnotations; +using Azure.Search.Documents.Indexes; +using Cogworks.AzureSearch.Models; namespace Cogworks.AzureSearch.UnitTests.Models { - public class TestDocumentModel : IAzureModel + public class TestDocumentModel : IModel { - [Key, IsFilterable, IsRetrievable(true), IsSearchable] + [SimpleField(IsKey = true, IsFilterable = true)] + [SearchableField()] public string Id { get; set; } - [IsFilterable, IsSearchable] + [SimpleField(IsFilterable = true)] + [SearchableField()] + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestResponse.cs b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestResponse.cs new file mode 100644 index 0000000..878ad44 --- /dev/null +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Models/TestResponse.cs @@ -0,0 +1,18 @@ +using Azure; + +namespace Cogworks.AzureSearch.UnitTests.Models +{ + + public class TestResponse : Response + { + + public TestResponse(T value) + { + Value = value; + } + + public override T Value { get; } + + public override Response GetRawResponse() => null; + } +} \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/DocumentOperationTests.cs b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/DocumentOperationTests.cs index 703f075..b096563 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/DocumentOperationTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/DocumentOperationTests.cs @@ -1,24 +1,27 @@ -using AutoFixture; +using System; +using System.Linq; +using System.Threading.Tasks; +using AutoFixture; +using Azure.Search.Documents.Models; +using Cogworks.AzureSearch.Exceptions.DocumentsExceptions; using Cogworks.AzureSearch.Interfaces.Operations; using Cogworks.AzureSearch.Repositories; using Cogworks.AzureSearch.UnitTests.Models; -using Microsoft.Azure.Search.Models; using NSubstitute; -using System.Linq; -using System.Threading.Tasks; +using NSubstitute.ExceptionExtensions; using Xunit; namespace Cogworks.AzureSearch.UnitTests.Operations { public class DocumentOperationTests : TestBase { - private readonly IAzureDocumentOperation _azureDocumentOperation; + private readonly IDocumentOperation _documentOperation; public DocumentOperationTests() - => _azureDocumentOperation = new AzureSearchRepository( - TestDocumentModelDefinition, - IndexOperationWrapper, - DocumentOperationWrapper); + => _documentOperation = new Repository( + IndexOperation, + DocumentOperation, + Search); [Theory] [InlineData(1)] @@ -32,17 +35,23 @@ public async Task Should_AddOrUpdateDocuments(int documentsCount) .Select(_ => Fixture.Create()) .ToArray(); + var indexResults = testDocuments - .Select(testDocument => new IndexingResult(testDocument.Id, succeeded: true, statusCode: 200)) + .Select(testDocument => SearchModelFactory.IndexingResult( + key: testDocument.Id, + errorMessage: string.Empty, + succeeded: true, + status: 200)) .ToList(); - var documentIndexResult = new DocumentIndexResult(indexResults); + var documentIndexResult = SearchModelFactory.IndexDocumentsResult(indexResults); - _ = DocumentOperationWrapper.IndexAsync(Arg.Any>()) - .Returns(documentIndexResult); + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Returns(new TestResponse(documentIndexResult)); // Act - var result = await _azureDocumentOperation.AddOrUpdateDocumentsAsync(testDocuments); + var result = await _documentOperation.AddOrUpdateDocumentsAsync(testDocuments); // Assert Assert.NotNull(result); @@ -60,19 +69,87 @@ public async Task Should_AddOrUpdateDocuments(int documentsCount) }); } + [Theory] + [InlineData(100)] + [InlineData(500)] + [InlineData(1000)] + public async Task Should_Fail_When_AddOrUpdateDocumentsPartiallyFail(int documentsCount) + { + // Arrange + var testDocuments = Enumerable.Range(0, documentsCount) + .Select(_ => Fixture.Create()) + .ToArray(); + + + var indexResults = testDocuments + .Select((document, index) => new + { + Document = document, + Succeded = index % (documentsCount / 2) == 0 + }) + .Select(item => SearchModelFactory.IndexingResult( + key: item.Document.Id, + errorMessage: !item.Succeded + ? "Internal Unit Error." + : string.Empty, + succeeded: item.Succeded, + status: item.Succeded + ? 200 + : 404)) + .ToList(); + + var documentIndexResult = SearchModelFactory.IndexDocumentsResult(indexResults); + + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Returns(new TestResponse(documentIndexResult)); + + // Act + var result = await _documentOperation.AddOrUpdateDocumentsAsync(testDocuments); + + // Assert + Assert.NotNull(result); + Assert.False(result.Succeeded); + Assert.NotEmpty(result.SucceededDocuments); + Assert.NotEmpty(result.FailedDocuments); + Assert.All( + result.SucceededDocuments, + succeedItem => + { + Assert.True(succeedItem.Succeeded); + Assert.Equal(200, succeedItem.StatusCode); + Assert.Equal("Successfully adding or updating document.", succeedItem.Message); + Assert.Contains(testDocuments, item => item.Id == succeedItem.ModelId); + }); + + Assert.All( + result.FailedDocuments, + succeedItem => + { + Assert.False(succeedItem.Succeeded); + Assert.Equal(404, succeedItem.StatusCode); + Assert.Equal("Failed adding or updating document.", succeedItem.Message); + Assert.Equal("Internal Unit Error.", succeedItem.InnerMessage); + Assert.Contains(testDocuments, item => item.Id == succeedItem.ModelId); + }); + } + [Fact] public async Task Should_Succeeded_When_TryToAddEmptyDocuments() { // Arrange var testDocuments = Enumerable.Empty(); - var documentIndexResult = new DocumentIndexResult(); + var documentIndexResult = new TestResponse( + SearchModelFactory.IndexDocumentsResult( + Enumerable.Empty())); - _ = DocumentOperationWrapper.IndexAsync(Arg.Any>()) + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) .Returns(documentIndexResult); // Act - var result = await _azureDocumentOperation.AddOrUpdateDocumentsAsync(testDocuments); + var result = await _documentOperation.AddOrUpdateDocumentsAsync(testDocuments); // Assert Assert.NotNull(result); @@ -88,13 +165,16 @@ public async Task Should_Succeeded_When_TryToRemoveEmptyDocuments() // Arrange var testDocuments = Enumerable.Empty(); - var documentIndexResult = new DocumentIndexResult(); + var documentIndexResult = new TestResponse( + SearchModelFactory.IndexDocumentsResult( + Enumerable.Empty())); - _ = DocumentOperationWrapper.IndexAsync(Arg.Any>()) + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) .Returns(documentIndexResult); // Act - var result = await _azureDocumentOperation.TryRemoveDocumentsAsync(testDocuments); + var result = await _documentOperation.TryRemoveDocumentsAsync(testDocuments); // Assert Assert.NotNull(result); @@ -117,16 +197,21 @@ public async Task Should_Succeeded_When_TryRemoveDocuments(int documentsCount) .ToArray(); var indexResults = testDocuments - .Select(testDocument => new IndexingResult(testDocument.Id, succeeded: true, statusCode: 200)) + .Select(testDocument => SearchModelFactory.IndexingResult( + key: testDocument.Id, + errorMessage: string.Empty, + succeeded: true, + status: 200)) .ToList(); - var documentIndexResult = new DocumentIndexResult(indexResults); + var documentIndexResult = SearchModelFactory.IndexDocumentsResult(indexResults); - _ = DocumentOperationWrapper.IndexAsync(Arg.Any>()) - .Returns(documentIndexResult); + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Returns(new TestResponse(documentIndexResult)); // Act - var result = await _azureDocumentOperation.TryRemoveDocumentsAsync(testDocuments); + var result = await _documentOperation.TryRemoveDocumentsAsync(testDocuments); // Assert Assert.NotNull(result); @@ -157,16 +242,21 @@ public async Task Should_Fail_When_TryRemoveNotExistingDocuments(int documentsCo .ToArray(); var indexResults = testDocuments - .Select(testDocument => new IndexingResult(testDocument.Id, succeeded: false, statusCode: 404)) + .Select(testDocument => SearchModelFactory.IndexingResult( + key: testDocument.Id, + errorMessage: string.Empty, + succeeded: false, + status: 404)) .ToList(); - var documentIndexResult = new DocumentIndexResult(indexResults); + var documentIndexResult = SearchModelFactory.IndexDocumentsResult(indexResults); - _ = DocumentOperationWrapper.IndexAsync(Arg.Any>()) - .Returns(documentIndexResult); + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Returns(new TestResponse(documentIndexResult)); // Act - var result = await _azureDocumentOperation.TryRemoveDocumentsAsync(testDocuments); + var result = await _documentOperation.TryRemoveDocumentsAsync(testDocuments); // Assert Assert.NotNull(result); @@ -183,5 +273,93 @@ public async Task Should_Fail_When_TryRemoveNotExistingDocuments(int documentsCo Assert.Contains(testDocuments, item => item.Id == failedItem.ModelId); }); } + + [Theory] + [InlineData(1)] + [InlineData(100)] + [InlineData(500)] + [InlineData(1000)] + public async Task Should_ThrowDomainException_When_IssueWith_TryAddOrUpdateDocuments(int documentsCount) + { + // Arrange + + var testDocuments = Enumerable.Range(0, documentsCount) + .Select(_ => Fixture.Create()) + .ToArray(); + + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Throws(_ => new AddOrUpdateDocumentException("Test Error", Fixture.Create())); + + // Assert + var domainException = await Assert.ThrowsAsync(async () => + await _documentOperation.AddOrUpdateDocumentsAsync(testDocuments)); + + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); + } + + [Theory] + [InlineData(1)] + [InlineData(100)] + [InlineData(500)] + [InlineData(1000)] + public async Task Should_Not_ThrowDomainException_When_No_IssueWith_TryAddOrUpdateDocuments(int documentsCount) + { + // Arrange + _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) + .Returns(true); + + // Act + var domainExceptionResult = await Record.ExceptionAsync(() => Should_AddOrUpdateDocuments(documentsCount)); + + // Assert + Assert.Null(domainExceptionResult); + } + + [Theory] + [InlineData(1)] + [InlineData(100)] + [InlineData(500)] + [InlineData(1000)] + public async Task Should_ThrowDomainException_When_IssueWith_TryRemoveDocuments(int documentsCount) + { + // Arrange + + var testDocuments = Enumerable.Range(0, documentsCount) + .Select(_ => Fixture.Create()) + .ToArray(); + + _ = DocumentOperationWrapper + .IndexAsync(Arg.Any>()) + .Throws(_ => new AddOrUpdateDocumentException("Test Error", Fixture.Create())); + + // Assert + var domainException = await Assert.ThrowsAsync(async () => + await _documentOperation.TryRemoveDocumentsAsync(testDocuments)); + + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); + } + + [Theory] + [InlineData(1)] + [InlineData(100)] + [InlineData(500)] + [InlineData(1000)] + public async Task Should_Not_ThrowDomainException_When_No_IssueWith_TryRemoveDocuments(int documentsCount) + { + // Arrange + _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) + .Returns(true); + + // Act + var domainExceptionResult = await Record.ExceptionAsync(() => Should_Succeeded_When_TryRemoveDocuments(documentsCount)); + + // Assert + Assert.Null(domainExceptionResult); + } } } \ No newline at end of file diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/IndexOperationTests.cs b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/IndexOperationTests.cs index 9aa7baf..902e23b 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/IndexOperationTests.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/Operations/IndexOperationTests.cs @@ -1,26 +1,28 @@ -using Cogworks.AzureSearch.Interfaces.Operations; +using System; +using System.Threading.Tasks; +using AutoFixture; +using Azure.Search.Documents.Indexes.Models; +using Cogworks.AzureSearch.Exceptions.IndexExceptions; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; using Cogworks.AzureSearch.Repositories; using Cogworks.AzureSearch.UnitTests.Models; -using Microsoft.Azure.Search.Models; -using Microsoft.Rest.Azure; using NSubstitute; using NSubstitute.ExceptionExtensions; -using System.Threading.Tasks; -using AutoFixture; -using Cogworks.AzureSearch.Models; using Xunit; namespace Cogworks.AzureSearch.UnitTests.Operations { public class IndexOperationTests : TestBase { - private readonly IAzureIndexOperation _azureIndexOperation; + private readonly IIndexOperation _indexOperation; public IndexOperationTests() - => _azureIndexOperation = new AzureSearchRepository( - TestDocumentModelDefinition, - IndexOperationWrapper, - DocumentOperationWrapper); + => _indexOperation = new Repository( + IndexOperation, + DocumentOperation, + Search); #region Exists Tests @@ -32,7 +34,7 @@ public async Task Should_ReturnTrue_When_IndexExists() .Returns(true); // Act - var result = await _azureIndexOperation.IndexExistsAsync(); + var result = await _indexOperation.IndexExistsAsync(); // Assert Assert.True(result); @@ -46,7 +48,7 @@ public async Task Should_ReturnFalse_When_IndexNotExists() .Returns(false); // Act - var result = await _azureIndexOperation.IndexExistsAsync(); + var result = await _indexOperation.IndexExistsAsync(); // Assert Assert.False(result); @@ -57,10 +59,16 @@ public async Task Should_ThrowException_When_IssuesWithConnection() { // Arrange _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + .Throws(_ => new IndexExistsException( + "Test Error", + Fixture.Create())); // Assert - _ = await Assert.ThrowsAsync(async () => await _azureIndexOperation.IndexExistsAsync()); + var domainException = await Assert.ThrowsAsync(async () => await _indexOperation.IndexExistsAsync()); + + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); } [Fact] @@ -87,28 +95,11 @@ public async Task Should_Not_ThrowException_When_NoIssueWithConnection() public async Task Should_DeleteIndex_When_IndexExists() { // Act - var deleteResult = await _azureIndexOperation.IndexDeleteAsync(); - - // Assert - Assert.NotNull(deleteResult); - Assert.True(deleteResult.Succeeded); - Assert.Equal($"Index {TestDocumentModelDefinition.IndexName} successfully deleted.", deleteResult.Message); - } - - [Fact] - public async Task Should_Not_DeleteIndex_When_IndexNotExists() - { - // Arrange - _ = IndexOperationWrapper.DeleteAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); - // Act - var deleteResult = await _azureIndexOperation.IndexDeleteAsync(); + var deleteResult = await Record.ExceptionAsync(async () => await _indexOperation.IndexDeleteAsync()); // Assert - Assert.NotNull(deleteResult); - Assert.False(deleteResult.Succeeded); - Assert.Equal($"An issue occurred on deleting index: {TestDocumentModelDefinition.IndexName}. More information: {AzureWrapperException}", deleteResult.Message); + Assert.Null(deleteResult); } [Fact] @@ -122,13 +113,21 @@ public async Task Should_Not_ThrowException_When_DeletingExistingIndex() } [Fact] - public async Task Should_Not_ThrowException_When_DeletingNotExistingIndex() + public async Task Should_ThrowException_When_IssuesWithConnection_On_DeletingIndex() { + // Arrange + _ = IndexOperationWrapper.DeleteAsync(Arg.Any()) + .Throws(_ => new IndexDeleteException( + "Test Error", + Fixture.Create())); + // Act - var indexDeletingResult = await Record.ExceptionAsync(Should_Not_DeleteIndex_When_IndexNotExists); + var domainException = await Assert.ThrowsAsync(async () => await _indexOperation.IndexDeleteAsync()); // Assert - Assert.Null(indexDeletingResult); + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); } #endregion Delete Tests @@ -139,86 +138,90 @@ public async Task Should_Not_ThrowException_When_DeletingNotExistingIndex() public async Task Should_CreateOrUpdateIndex() { // Arrange - var createdOrUpdatedIndex = new Index - { - Name = TestDocumentModelDefinition.IndexName - }; + var createdOrUpdatedIndex = new SearchIndex(TestDocumentModelDefinition.IndexName); _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any()) .Returns(createdOrUpdatedIndex); // Act - var operationResult = await _azureIndexOperation.IndexCreateOrUpdateAsync(); + var indexResult = await Record.ExceptionAsync(async () => await _indexOperation.IndexCreateOrUpdateAsync()); // Assert - Assert.NotNull(operationResult); - Assert.True(operationResult.Succeeded); - Assert.Equal($"Index {TestDocumentModelDefinition.IndexName} successfully created or updated.", operationResult.Message); + Assert.Null(indexResult); + } [Fact] public async Task Should_CreateOrUpdateCustomIndex() { // Arrange - var createdOrUpdatedIndex = new Index - { - Name = TestDocumentModelDefinition.IndexName - }; + var index = new SearchIndex(Fixture.Create()); - _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any(), Arg.Any()) - .Returns(createdOrUpdatedIndex); + var customModelDefinition = new IndexDefinition(index); + + var customIndexOperationService = new IndexOperation( + customModelDefinition, + IndexOperationWrapper); + + var azureIndexOperation = new Repository( + customIndexOperationService, + DocumentOperation, + Search); // Act - var operationResult = await _azureIndexOperation.IndexCreateOrUpdateAsync(); + var indexResult = await Record.ExceptionAsync(async () => await azureIndexOperation.IndexCreateOrUpdateAsync()); // Assert - Assert.NotNull(operationResult); - Assert.True(operationResult.Succeeded); - Assert.Equal($"Index {TestDocumentModelDefinition.IndexName} successfully created or updated.", operationResult.Message); + Assert.Null(indexResult); } [Fact] - public async Task Should_Not_ThrowException_When_IssueOnCreatingOrUpdatingIndex() + public async Task Should_ThrowException_When_IssueOnCreatingOrUpdatingIndex() { // Arrange _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + .Throws(_ => new IndexCreateOrUpdateException( + "Test Error", + Fixture.Create())); // Act - var operationResult = await _azureIndexOperation.IndexCreateOrUpdateAsync(); + var domainException = await Assert.ThrowsAsync(async () => await _indexOperation.IndexCreateOrUpdateAsync()); // Assert - Assert.NotNull(operationResult); - Assert.False(operationResult.Succeeded); - Assert.Equal($"An issue occurred on creating or updating index: {TestDocumentModelDefinition.IndexName}. More information: {AzureWrapperException}", operationResult.Message); + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); } [Fact] - public async Task Should_Not_ThrowException_When_IssueOnCreatingOrUpdatingCustomIndex() + public async Task Should_ThrowException_When_IssueOnCreatingOrUpdatingCustomIndex() { // Arrange - var index = new Index - { - Name = Fixture.Create() - }; + var index = new SearchIndex(Fixture.Create()); - var customModelDefinition = new AzureIndexDefinition(index); + var customModelDefinition = new IndexDefinition(index); - var azureIndexOperation = new AzureSearchRepository( + var customIndexOperationService = new IndexOperation( customModelDefinition, - IndexOperationWrapper, - DocumentOperationWrapper); + IndexOperationWrapper); - _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any(), Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + var azureIndexOperation = new Repository( + customIndexOperationService, + DocumentOperation, + Search); + + _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any(), Arg.Any()) + .Throws(_ => new IndexCreateOrUpdateException( + "Test Error", + Fixture.Create())); // Act - var operationResult = await azureIndexOperation.IndexCreateOrUpdateAsync(); + var domainException = await Assert.ThrowsAsync(async () => await azureIndexOperation.IndexCreateOrUpdateAsync()); // Assert - Assert.NotNull(operationResult); - Assert.False(operationResult.Succeeded); - Assert.Equal($"An issue occurred on creating or updating index: {customModelDefinition.IndexName}. More information: {AzureWrapperException}", operationResult.Message); + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); } #endregion Index Create or Update Tests @@ -232,13 +235,11 @@ public async Task Should_ClearIndex_When_IndexExists() _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) .Returns(true); - // Act - var indexOperationResult = await _azureIndexOperation.IndexClearAsync(); + // Act + var indexResult = await Record.ExceptionAsync(async () => await _indexOperation.IndexClearAsync()); // Assert - Assert.NotNull(indexOperationResult); - Assert.True(indexOperationResult.Succeeded); - Assert.Equal($"Index {TestDocumentModelDefinition.IndexName} successfully cleared.", indexOperationResult.Message); + Assert.Null(indexResult); } [Fact] @@ -249,46 +250,51 @@ public async Task Should_ClearIndex_When_IndexNotExists() .Returns(false); // Act - var indexOperationResult = await _azureIndexOperation.IndexClearAsync(); + var indexResult = await Record.ExceptionAsync(async () => await _indexOperation.IndexClearAsync()); // Assert - Assert.NotNull(indexOperationResult); - Assert.True(indexOperationResult.Succeeded); - Assert.Equal($"Index {TestDocumentModelDefinition.IndexName} successfully cleared.", indexOperationResult.Message); + Assert.Null(indexResult); } [Fact] - public async Task Should_Not_ThrowException_When_IssueWithConnectionOnClearingIndex() + public async Task Should_ThrowException_When_IssueWithConnectionOnClearingIndex() { // Arrange _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) .Returns(true); _ = IndexOperationWrapper.DeleteAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + .Throws(_ => new IndexClearException( + "Test Error", + Fixture.Create())); // Act - var indexOperationResult = await _azureIndexOperation.IndexClearAsync(); + var domainException = await Record.ExceptionAsync(async () => await _indexOperation.IndexClearAsync()); // Assert - Assert.NotNull(indexOperationResult); - Assert.False(indexOperationResult.Succeeded); - Assert.Equal($"An issue occurred on clearing index: {TestDocumentModelDefinition.IndexName}. Could not delete existing index.", indexOperationResult.Message); + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); + // Arrange _ = IndexOperationWrapper.ExistsAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + .Throws(_ => new IndexExistsException( + "Test Error", + Fixture.Create())); _ = IndexOperationWrapper.CreateOrUpdateAsync(Arg.Any()) - .Throws(_ => new CloudException(AzureWrapperException)); + .Throws(_ => new IndexCreateOrUpdateException( + "Test Error", + Fixture.Create())); // Act - indexOperationResult = await _azureIndexOperation.IndexClearAsync(); + domainException = await Record.ExceptionAsync(async () => await _indexOperation.IndexClearAsync()); // Assert - Assert.NotNull(indexOperationResult); - Assert.False(indexOperationResult.Succeeded); - Assert.Equal($"An issue occurred on clearing index: {TestDocumentModelDefinition.IndexName}. Could not create index.", indexOperationResult.Message); + Assert.NotNull(domainException); + Assert.Equal("Test Error", domainException.Message); + Assert.NotNull(domainException.InnerException); } #endregion Index Clear Tests diff --git a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/TestBase.cs b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/TestBase.cs index 27d8482..68ff4fd 100644 --- a/tests/UnitTests/Cogworks.AzureSearch.UnitTests/TestBase.cs +++ b/tests/UnitTests/Cogworks.AzureSearch.UnitTests/TestBase.cs @@ -1,7 +1,10 @@ using AutoFixture; using AutoFixture.AutoNSubstitute; +using Cogworks.AzureSearch.Interfaces.Operations; +using Cogworks.AzureSearch.Interfaces.Searches; using Cogworks.AzureSearch.Interfaces.Wrappers; using Cogworks.AzureSearch.Models; +using Cogworks.AzureSearch.Operations; using Cogworks.AzureSearch.UnitTests.Models; using NSubstitute; @@ -16,14 +19,27 @@ public abstract class TestBase protected readonly IIndexOperationWrapper IndexOperationWrapper; protected readonly IDocumentOperationWrapper DocumentOperationWrapper; - protected readonly AzureIndexDefinition TestDocumentModelDefinition; + protected readonly IndexDefinition TestDocumentModelDefinition; + protected readonly ISearcher Search; + + protected readonly IDocumentOperation DocumentOperation; + protected readonly IIndexOperation IndexOperation; protected TestBase() { - TestDocumentModelDefinition = Fixture.Create>(); + TestDocumentModelDefinition = Fixture.Create>(); IndexOperationWrapper = Substitute.For(); DocumentOperationWrapper = Substitute.For>(); + + Search = Substitute.For>(); + + DocumentOperation = new DocumentOperation( + DocumentOperationWrapper); + + IndexOperation = new IndexOperation( + TestDocumentModelDefinition, + IndexOperationWrapper); } } } \ No newline at end of file