From b132986f54924b253043d55e7b79f06c54bdf2e8 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Fri, 17 Feb 2023 12:51:04 +0100 Subject: [PATCH 01/57] Prepare next major version 8 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f4965a313..ae9a76b92 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.0 \ No newline at end of file +8.0.0 From 8bf27fac060217ec5027c7eb8823925ce00e5597 Mon Sep 17 00:00:00 2001 From: Christian Siewert Date: Wed, 3 May 2023 14:37:13 +0200 Subject: [PATCH 02/57] Update `Newtonsoft.Json` to `13.0.3` --- Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 1e4f23370..b0784c6c3 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -26,7 +26,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From 63f198010ca2855fe2e08856dc97c86d4deef8fd Mon Sep 17 00:00:00 2001 From: MarisaGoergen <69142022+MarisaGoergen@users.noreply.github.com> Date: Wed, 31 May 2023 15:24:08 +0200 Subject: [PATCH 03/57] Fix spelling mistakes in the documentation --- docs/tutorials/HowToCreateAProduct.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/HowToCreateAProduct.md b/docs/tutorials/HowToCreateAProduct.md index c62cb9f8e..2a00fdc6f 100644 --- a/docs/tutorials/HowToCreateAProduct.md +++ b/docs/tutorials/HowToCreateAProduct.md @@ -1,11 +1,11 @@ --- uid: HowToCreateAProduct --- -# How to create a resource +# How to create a product This tutorial shows how [Products](../../src/Moryx.AbstractionLayer/Products/ProductType.cs) should be implemented. Look [here](../articles/Products/Concept.md) if you are not firm with the concept of a `Product`. -For products we differentiate between [ProductType](../../src/Moryx.AbstractionLayer/Products/ProductType.cs) and [ProductInstance](../../src/Moryx.AbstractionLayer/Products/ProductInstance.cs). The `ProductType` is what you can order in a catalog, while the `ProductInstance` is what you received after ordering: an instance of the product with its unique serialnumber. So that a `ProductType` can be producted it needs a corresponding `ProductInstance`. If your application isn't used for production, you can skip the `ProductInstances`. +For products we differentiate between [ProductType](../../src/Moryx.AbstractionLayer/Products/ProductType.cs) and [ProductInstance](../../src/Moryx.AbstractionLayer/Products/ProductInstance.cs). The `ProductType` is what you can order in a catalog, while the `ProductInstance` is what you received after ordering: an instance of the product with its unique serialnumber. So that a `ProductType` can be produced it needs a corresponding `ProductInstance`. If your application isn't used for production, you can skip the `ProductInstances`. ## Create a basic ProductType and ProductInstance All ProductTypes are derived from `ProductType`. The methode `Instantiate()` returns an object of the correspoding `ProductInstance`. From 00c3d2d951dfee7ee3c53eb9f8765527f90488a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Sch=C3=B6ne?= Date: Wed, 24 May 2023 14:29:17 +0200 Subject: [PATCH 04/57] Switching to ubuntu for github actions Deleting PowerShell Scripts !!Need to add LangVersion latest!! --- .build/BuildToolkit.ps1 | 680 ------------------ .build/Output.ps1 | 36 - .github/workflows/build-and-test.yml | 119 ++- Build.ps1 | 63 -- ...ctory.build.props => Directory.Build.props | 2 +- Directory.Build.targets | 1 + src/Tests/Directory.Build.props | 5 + .../CommunicationSocketsTests.cs | 4 + .../CommunicationSocketsTestsBase.cs | 4 + .../DelimiterCommunicationSocketTests.cs | 4 + .../HeaderedCommunicationSocketTests.cs | 4 + ...munication.Sockets.IntegrationTests.csproj | 4 + src/Tests/Moryx.Model.Tests/SqliteTests.cs | 13 +- 13 files changed, 85 insertions(+), 854 deletions(-) delete mode 100644 .build/BuildToolkit.ps1 delete mode 100644 .build/Output.ps1 delete mode 100644 Build.ps1 rename Directory.build.props => Directory.Build.props (91%) create mode 100644 src/Tests/Directory.Build.props diff --git a/.build/BuildToolkit.ps1 b/.build/BuildToolkit.ps1 deleted file mode 100644 index 26d22dbf7..000000000 --- a/.build/BuildToolkit.ps1 +++ /dev/null @@ -1,680 +0,0 @@ -# Tool Versions -$NunitVersion = "3.12.0"; -$OpenCoverVersion = "4.7.1221"; -$DocFxVersion = "2.58.4"; -$ReportGeneratorVersion = "4.8.13"; -$OpenCoverToCoberturaVersion = "0.3.4"; - -# Folder Pathes -$RootPath = $MyInvocation.PSScriptRoot; -$BuildTools = "$RootPath\packages"; - -# Artifacts -$ArtifactsDir = "$RootPath\artifacts"; - -# Documentation -$DocumentationDir = "$RootPath\docs"; -$DocumentationArtifcacts = "$ArtifactsDir\Documentation"; - -# Tests -$NunitReportsDir = "$ArtifactsDir\Tests"; -$OpenCoverReportsDir = "$ArtifactsDir\Tests" -$CoberturaReportsDir = "$ArtifactsDir\Tests" - -# Nuget -$NugetConfig = "$RootPath\NuGet.Config"; -$NugetPackageArtifacts = "$ArtifactsDir\Packages"; - -# Load partial scripts -. "$PSScriptRoot\Output.ps1"; - -# Define Tools -$global:DotNetCli = "dotnet.exe"; -$global:NugetCli = "nuget.exe"; -$global:GitCli = ""; -$global:OpenCoverCli = "$BuildTools\OpenCover.$OpenCoverVersion\tools\OpenCover.Console.exe"; -$global:NunitCli = "$BuildTools\NUnit.ConsoleRunner.$NunitVersion\tools\nunit3-console.exe"; -$global:ReportGeneratorCli = "$BuildTools\ReportGenerator.$ReportGeneratorVersion\tools\net47\ReportGenerator.exe"; -$global:DocFxCli = "$BuildTools\docfx.console.$DocFxVersion\tools\docfx.exe"; -$global:OpenCoverToCoberturaCli = "$BuildTools\OpenCoverToCoberturaConverter.$OpenCoverToCoberturaVersion\tools\OpenCoverToCoberturaConverter.exe"; - -# Git -$global:GitCommitHash = ""; - -# Functions -function Invoke-Initialize([string]$Version = "1.0.0", [bool]$Cleanup = $False) { - Write-Step "Initializing BuildToolkit" - - # First check the powershell version - if ($PSVersionTable.PSVersion.Major -lt 5) { - Write-Host ("The needed major powershell version for this script is 5. Your version: " + ($PSVersionTable.PSVersion.ToString())) - exit 1; - } - - # Assign git.exe - $gitCommand = (Get-Command "git.exe" -ErrorAction SilentlyContinue); - if ($null -eq $gitCommand) { - Write-Host "Unable to find git.exe in your PATH. Download from https://git-scm.com"; - exit 1; - } - - $global:GitCli = $gitCommand.Path; - - # Load Hash - $global:GitCommitHash = (& $global:GitCli rev-parse HEAD); - Invoke-ExitCodeCheck $LastExitCode; - - # Initialize Folders - CreateFolderIfNotExists $BuildTools; - CreateFolderIfNotExists $ArtifactsDir; - - # Environment Variable Defaults - if (-not $env:MORYX_BUILDNUMBER) { - $env:MORYX_BUILDNUMBER = 0; - } - - if (-not $env:MORYX_BUILD_CONFIG) { - $env:MORYX_BUILD_CONFIG = "Debug"; - } - - if (-not $env:MORYX_BUILD_VERBOSITY) { - $env:MORYX_BUILD_VERBOSITY = "minimal" - } - - if (-not $env:MORYX_TEST_VERBOSITY) { - $env:MORYX_TEST_VERBOSITY = "normal" - } - - if (-not $env:MORYX_NUGET_VERBOSITY) { - $env:MORYX_NUGET_VERBOSITY = "normal" - } - - if (-not $env:MORYX_OPTIMIZE_CODE) { - $env:MORYX_OPTIMIZE_CODE = $True; - } - else { - if (-not [bool]::TryParse($env:MORYX_OPTIMIZE_CODE, [ref]$env:MORYX_OPTIMIZE_CODE)) { - $env:MORYX_OPTIMIZE_CODE = $True; - } - } - - if (-not $env:MORYX_PACKAGE_TARGET) { - $env:MORYX_PACKAGE_TARGET = ""; - } - - if (-not $env:MORYX_PACKAGE_TARGET_V3) { - $env:MORYX_PACKAGE_TARGET_V3 = ""; - } - - if (-not $env:MORYX_ASSEMBLY_VERSION) { - $env:MORYX_ASSEMBLY_VERSION = $Version; - } - - if (-not $env:MORYX_FILE_VERSION) { - $env:MORYX_FILE_VERSION = $Version; - } - - if (-not $env:MORYX_INFORMATIONAL_VERSION) { - $env:MORYX_INFORMATIONAL_VERSION = $Version; - } - - if (-not $env:MORYX_PACKAGE_VERSION) { - $env:MORYX_PACKAGE_VERSION = $Version; - } - - Set-Version $Version; - - # Printing Variables - Write-Step "Printing global variables" - Write-Variable "RootPath" $RootPath; - Write-Variable "DocumentationDir" $DocumentationDir; - Write-Variable "NunitReportsDir" $NunitReportsDir; - - Write-Step "Printing global scope" - Write-Variable "OpenCoverCli" $global:OpenCoverCli; - Write-Variable "NUnitCli" $global:NUnitCli; - Write-Variable "ReportGeneratorCli" $global:ReportGeneratorCli; - Write-Variable "DocFxCli" $global:DocFxCli; - Write-Variable "OpenCoverToCoberturaCli" $global:OpenCoverToCoberturaCli; - Write-Variable "GitCli" $global:GitCli; - Write-Variable "GitCommitHash" $global:GitCommitHash; - - Write-Step "Printing environment variables" - Write-Variable "MORYX_OPTIMIZE_CODE" $env:MORYX_OPTIMIZE_CODE; - Write-Variable "MORYX_BUILDNUMBER" $env:MORYX_BUILDNUMBER; - Write-Variable "MORYX_BUILD_CONFIG" $env:MORYX_BUILD_CONFIG; - Write-Variable "MORYX_BUILD_VERBOSITY" $env:MORYX_BUILD_VERBOSITY; - Write-Variable "MORYX_TEST_VERBOSITY" $env:MORYX_TEST_VERBOSITY; - Write-Variable "MORYX_NUGET_VERBOSITY" $env:MORYX_NUGET_VERBOSITY; - Write-Variable "MORYX_PACKAGE_TARGET" $env:MORYX_PACKAGE_TARGET; - Write-Variable "MORYX_PACKAGE_TARGET_V3" $env:MORYX_PACKAGE_TARGET_V3; - - Write-Variable "MORYX_ASSEMBLY_VERSION" $env:MORYX_ASSEMBLY_VERSION; - Write-Variable "MORYX_FILE_VERSION" $env:MORYX_FILE_VERSION; - Write-Variable "MORYX_INFORMATIONAL_VERSION" $env:MORYX_INFORMATIONAL_VERSION; - Write-Variable "MORYX_PACKAGE_VERSION" $env:MORYX_PACKAGE_VERSION; - - - # Cleanp - if ($Cleanup) { - Write-Step "Cleanup" - - Write-Host "Cleaning up repository ..." -ForegroundColor Red; - & $global:GitCli clean -f -d -x - Invoke-ExitCodeCheck $LastExitCode; - - & $global:GitCli checkout . - Invoke-ExitCodeCheck $LastExitCode; - } -} - -function Invoke-Cleanup { - # Clean up - Write-Step "Cleaning up repository ..."; - & $global:GitCli clean -f -d -x - Invoke-ExitCodeCheck $LastExitCode; -} - -function Install-Tool([string]$PackageName, [string]$Version, [string]$TargetExecutable, [string]$OutputDirectory = $BuildTools) { - if (-not (Test-Path $TargetExecutable)) { - & $global:NugetCli install $PackageName -version $Version -outputdirectory $OutputDirectory -configfile $NugetConfig - Invoke-ExitCodeCheck $LastExitCode; - } - else { - Write-Host "$PackageName ($Version) already exists. Do not need to install." - } -} - -function Invoke-Build([string]$ProjectFile, [string]$Options = "") { - Write-Step "Building $ProjectFile" - - # TODO: maybe we find a better way: currently all packages of all solutions are restored. - ForEach ($solution in (Get-ChildItem $RootPath -Filter "*.sln")) { - Write-Host "Restoring Nuget packages of $solution"; - - & $global:DotNetCli restore $solution --verbosity $env:MORYX_NUGET_VERBOSITY --configfile $NugetConfig; - Invoke-ExitCodeCheck $LastExitCode; - } - - $additonalOptions = ""; - if (-not [string]::IsNullOrEmpty($Options)) { - $additonalOptions = ",$Options"; - } - - $msbuildParams = "Optimize=" + (&{If($env:MORYX_OPTIMIZE_CODE -eq $True) {"true"} Else {"false"}}) + ",DebugSymbols=true$additonalOptions"; - $buildArgs = "--configuration", "$env:MORYX_BUILD_CONFIG"; - $buildArgs += "--verbosity", $env:MORYX_BUILD_VERBOSITY; - $buildArgs += "-p:$msbuildParams" - - & $global:DotNetCli build $ProjectFile @buildArgs - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-Nunit([string]$SearchPath = $RootPath, [string]$SearchFilter = "*.csproj") { - $randomIncrement = Get-Random -Minimum 2000 -Maximum 2100 - Write-Step "Running $Name Tests: $SearchPath" - - $testProjects = Get-ChildItem $SearchPath -Recurse -Include $SearchFilter - if ($testProjects.Length -eq 0) { - Write-Host-Warning "No test projects found!" - return; - } - - $env:PORT_INCREMENT = $randomIncrement; - - if (-not (Test-Path $global:NUnitCli)) { - Install-Tool "NUnit.Console" $NunitVersion $global:NunitCli; - } - - CreateFolderIfNotExists $NunitReportsDir; - - ForEach($testProject in $testProjects ) { - $projectName = ([System.IO.Path]::GetFileNameWithoutExtension($testProject.Name)); - $testAssembly = [System.IO.Path]::Combine($testProject.DirectoryName, "bin", $env:MORYX_BUILD_CONFIG, "$projectName.dll"); - - # If assembly does not exists, the project will be build - if (-not (Test-Path $testAssembly)) { - Invoke-Build $testProject - } - - & $global:NUnitCli $testProject /config:"$env:MORYX_BUILD_CONFIG" - } - - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-SmokeTest([string]$RuntimePath, [int]$ModulesCount, [int]$InterruptTime) { - $randomIncrement = Get-Random -Minimum 2000 -Maximum 2100 - Write-Step "Invoking Runtime SmokeTest Modules: $ModulesCount, Interrupt Time: $InterruptTime, Port Increment: $randomIncrement." - - & "$RuntimePath" @("smokeTest", "-e $ModulesCount", "-i $InterruptTime", "-p $randomIncrement") - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-CoverTests($SearchPath = $RootPath, $SearchFilter = "*.csproj", $FilterFile = "$RootPath\OpenCoverFilter.txt") { - Write-Step "Starting cover tests from $SearchPath with filter $FilterFile." - - if (-not (Test-Path $SearchPath)) { - Write-Host-Warning "$SearchPath does not exists, ignoring!"; - return; - } - - $testProjects = Get-ChildItem $SearchPath -Recurse -Include $SearchFilter - if ($testProjects.Length -eq 0) { - Write-Host-Warning "No test projects found!" - return; - } - - if (-not (Test-Path $global:NUnitCli)) { - Install-Tool "NUnit.Console" $NunitVersion $global:NunitCli; - } - - if (-not (Test-Path $global:OpenCoverCli)) { - Install-Tool "OpenCover" $OpenCoverVersion $global:OpenCoverCli; - } - - if (-not (Test-Path $global:OpenCoverToCoberturaCli)) { - Install-Tool "OpenCoverToCoberturaConverter" $OpenCoverToCoberturaVersion $global:OpenCoverToCoberturaCli; - } - - CreateFolderIfNotExists $OpenCoverReportsDir; - CreateFolderIfNotExists $NunitReportsDir; - - $includeFilter = "+[Moryx*]*"; - $excludeFilter = "-[*nunit*]* -[*Tests]* -[*Model*]*"; - - if (Test-Path $FilterFile) { - $ignoreContent = Get-Content $FilterFile; - - foreach ($line in $ignoreContent) { - $parts = $line.Split(":"); - if ($parts.Count -lt 2) { - continue - } - - $filterType = $parts[0]; - $filterValue = $parts[1]; - - if ($filterType.StartsWith("INCLUDE")) { - $includeFilter += " $filterValue"; - } - - if ($filterType.StartsWith("EXCLUDE")) { - $excludeFilter += " $filterValue"; - } - } - - Write-Host "Active Filter: `r`n Include: $includeFilter `r`n Exclude: $excludeFilter"; - } - - ForEach($testProject in $testProjects ) { - $projectName = ([System.IO.Path]::GetFileNameWithoutExtension($testProject.Name)); - $testAssembly = [System.IO.Path]::Combine($testProject.DirectoryName, "bin", $env:MORYX_BUILD_CONFIG, "$projectName.dll"); - $isNetCore = Get-CsprojIsNetCore($testProject); - - Write-Host "OpenCover Test: ${projectName}:"; - - $nunitXml = ($NunitReportsDir + "\$projectName.TestResult.xml"); - $openCoverXml = ($OpenCoverReportsDir + "\$projectName.OpenCover.xml"); - $coberturaXml = ($CoberturaReportsDir + "\$projectName.Cobertura.xml"); - - if ($isNetCore) { - $targetArgs = '"test -v ' + $env:MORYX_TEST_VERBOSITY + ' -c ' + $env:MORYX_BUILD_CONFIG + ' ' + $testProject + '"'; - $openCoverAgs = "-target:$global:DotNetCli", "-targetargs:$targetArgs" - } - else { - # If assembly does not exists, the project will be build - if (-not (Test-Path $testAssembly)) { - Invoke-Build $testProject - } - - $openCoverAgs = "-target:$global:NunitCli", "-targetargs:/config:$env:MORYX_BUILD_CONFIG /result:$nunitXml $testAssembly" - } - - $openCoverAgs += "-log:Debug", "-register:administrator", "-output:$openCoverXml", "-hideskipped:all", "-skipautoprops"; - $openCoverAgs += "-returntargetcode" # We need the nunit return code - $openCoverAgs += "-filter:$includeFilter $excludeFilter" - - & $global:OpenCoverCli $openCoverAgs - - $exitCode = [int]::Parse($LastExitCode); - if ($exitCode -ne 0) { - $errorText = ""; - switch ($exitCode) { - -1 { $errorText = "INVALID_ARG"; } - -2 { $errorText = "INVALID_ASSEMBLY"; } - -4 { $errorText = "INVALID_TEST_FIXTURE"; } - -5 { $errorText = "UNLOAD_ERROR"; } - Default { $errorText = "UNEXPECTED_ERROR"; } - } - - if ($exitCode -gt 0) { - $errorText = "FAILED_TESTS ($exitCode)"; - } - - Write-Host-Error "Nunit exited with $errorText for $projectName"; - Invoke-ExitCodeCheck $exitCode; - } - - & $global:OpenCoverToCoberturaCli -input:$openCoverXml -output:$coberturaXml -sources:$rootPath - Invoke-ExitCodeCheck $LastExitCode; - } -} - -function Get-CsprojIsNetCore($CsprojItem) { - [xml]$csprojContent = Get-Content $CsprojItem.FullName - $sdkProject = $csprojContent.Project.Sdk; - if ($null -ne $sdkProject) { - # Read Target Framework - $targetFramework = $csprojContent.Project.PropertyGroup.TargetFramework; - if ($targetFramework -Match "netcoreapp" -or $targetFramework -Match "net5.") { - # NETCore - return $true; - } - } - return $false; -} - -function Get-CsprojIsSdkProject($CsprojItem) { - [xml]$csprojContent = Get-Content $CsprojItem.FullName - $sdkProject = $csprojContent.Project.Sdk; - if ($null -ne $sdkProject) { - return $true; - } - return $false; -} - -function Invoke-CoverReport { - Write-Step "Creating cover report. Searching for OpenCover.xml files in $OpenCoverReportsDir." - - if (-not (Test-Path $OpenCoverReportsDir)) { - Write-Host-Error "$OpenCoverReportsDir was not found!"; - Invoke-ExitCodeCheck 1; - } - - if (-not (Test-Path $global:ReportGeneratorCli)) { - Install-Tool "ReportGenerator" $ReportGeneratorVersion $global:ReportGeneratorCli; - } - - $reports = (Get-ChildItem $OpenCoverReportsDir -Recurse -Include '*.OpenCover.xml'); - $asArgument = [string]::Join(";",$reports); - - CreateFolderIfNotExists $DocumentationArtifcacts; - - & $global:ReportGeneratorCli -reports:"$asArgument" -targetDir:"$DocumentationArtifcacts/OpenCover" - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-DocFx($Metadata = [System.IO.Path]::Combine($DocumentationDir, "docfx.json")) { - Write-Step "Generating documentation using DocFx" - - if (-not (Test-Path $Metadata)) { - Write-Host-Error "Metadata was not found at: $Metadata!" - Invoke-ExitCodeCheck 1; - } - - if (-not (Test-Path $global:DocFxCli)) { - Install-Tool "docfx.console" $DocFxVersion $global:DocFxCli; - } - - $docFxObj = (Get-Content $Metadata) | ConvertFrom-Json; - $metadataFolder = [System.IO.Path]::GetDirectoryName($Metadata); - $docFxDest = [System.IO.Path]::Combine($metadataFolder, $docFxObj.build.dest); - - & $global:DocFxCli $Metadata; - Invoke-ExitCodeCheck $LastExitCode; - - CreateFolderIfNotExists $DocumentationArtifcacts; - CopyAndReplaceFolder $docFxDest "$DocumentationArtifcacts\DocFx"; -} - -function Invoke-PackSdkProject($CsprojItem, [bool]$IncludeSymbols = $False) { - Write-Host "Try to pack .NET SDK project: $($CsprojItem.Name) ..."; - - # Check if the project should be packed - $csprojFullName = $CsprojItem.FullName; - [xml]$csprojContent = Get-Content $csprojFullName - $createPackage = $csprojContent.Project.PropertyGroup.CreatePackage; -; - if ($null -eq $createPackage -or "false" -eq $createPackage) { - Write-Host-Warning "... csproj not flagged with true: $($CsprojItem.Name)"; - return; - } - - $packargs = "--output", "$NugetPackageArtifacts"; - $packargs += "--configuration", "$env:MORYX_BUILD_CONFIG"; - $packargs += "--verbosity", "$env:MORYX_NUGET_VERBOSITY"; - $packargs += "--no-build"; - - if ($IncludeSymbols) { - $packargs += "--include-symbols"; - $packargs += "--include-source"; - } - - & $global:DotNetCli pack "$csprojFullName" @packargs - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-PackFrameworkProject($CsprojItem, [bool]$IsTool = $False, [bool]$IncludeSymbols = $False) { - Write-Host "Try to pack .NET Framework project: $CsprojItem.Name ..."; - - # Check if there is a matching nuspec for the proj - $csprojFullName = $CsprojItem.FullName; - $nuspecPath = [IO.Path]::ChangeExtension($csprojFullName, "nuspec") - if(-not (Test-Path $nuspecPath)) { - Write-Host-Warning "Nuspec for project not found: $CsprojItem.Name"; - return; - } - - $packargs = "-outputdirectory", "$NugetPackageArtifacts"; - $packargs += "-includereferencedprojects"; - $packargs += "-Version", "$env:MORYX_PACKAGE_VERSION"; - $packargs += "-Prop", "Configuration=$env:MORYX_BUILD_CONFIG"; - $packargs += "-Verbosity", "$env:MORYX_NUGET_VERBOSITY"; - - if ($IncludeSymbols) { - $packargs += "-Symbols"; - } - - if ($IsTool) { - $packargs += "-Tool"; - } - - # Call nuget with default arguments plus optional - & $global:NugetCli pack "$csprojFullName" @packargs - Invoke-ExitCodeCheck $LastExitCode; -} - -function Invoke-Pack($ProjectItem, [bool]$IsTool = $False, [bool]$IncludeSymbols = $False) { - CreateFolderIfNotExists $NugetPackageArtifacts; - - if (Get-CsprojIsSdkProject($ProjectItem)) { - Invoke-PackSdkProject $ProjectItem $IncludeSymbols; - } - else { - Invoke-PackFrameworkProject $ProjectItem $IsTool $IncludeSymbols; - } -} - -function Invoke-PackAll([switch]$Symbols = $False) { - Write-Host "Looking for .csproj files..." - # Look for csproj in this directory - foreach ($csprojItem in Get-ChildItem $RootPath -Recurse -Filter *.csproj) { - Invoke-Pack -ProjectItem $csprojItem -IncludeSymbols $Symbols - } -} - -function Invoke-Publish { - Write-Host "Pushing packages from $NugetPackageArtifacts to $env:MORYX_PACKAGE_TARGET" - - $packages = Get-ChildItem $NugetPackageArtifacts -Recurse -Include *.nupkg - if ($packages.Length -gt 0 -and [string]::IsNullOrEmpty($env:MORYX_PACKAGE_TARGET)) { - Write-Host-Error "There is no package target given. Set the environment varialble MORYX_PACKAGE_TARGET to publish packages."; - Invoke-ExitCodeCheck 1; - } - - foreach ($package in $packages) { - Write-Host "Pushing package $package" - & $global:DotNetCli nuget push $package --api-key $env:MORYX_NUGET_APIKEY --no-symbols --skip-duplicate --source $env:MORYX_PACKAGE_TARGET - Invoke-ExitCodeCheck $LastExitCode; - } - - $symbolPackages = Get-ChildItem $NugetPackageArtifacts -Recurse -Include *.snupkg - if ($symbolPackages.Length -gt 0 -and [string]::IsNullOrEmpty($env:MORYX_PACKAGE_TARGET_V3)) { - Write-Host-Error "There is no package (v3) target given. Set the environment varialble MORYX_PACKAGE_TARGET_V3 to publish snupkg symbol packages."; - Invoke-ExitCodeCheck 1; - } - - foreach ($symbolPackage in $symbolPackages) { - Write-Host "Pushing symbol (snupkg) $symbolPackage" - & $global:DotNetCli nuget push $symbolPackage --api-key $env:MORYX_NUGET_APIKEY --skip-duplicate --source $env:MORYX_PACKAGE_TARGET_V3 - Invoke-ExitCodeCheck $LastExitCode; - } -} - -function Set-Version ([string]$MajorMinorPatch) { - $semVer2Regex = "^(?0|[1-9]\d*)\.(?0|[1-9]\d*)\.(?0|[1-9]\d*)(?:-(?(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"; - - $version = Read-VersionFromRef($MajorMinorPatch); - Write-Host "Setting environment version to $version"; - - # Match semVer2 regex - $regexMatch = [regex]::Match($version, $semVer2Regex); - - if (-not $regexMatch.Success) { - Write-Host "Could not parse version: $version"; - Invoke-ExitCodeCheck 1; - } - - # Extract groups - $matchgroups = $regexMatch.captures.groups; - $majorGroup = $matchgroups[1]; - $minorGroup = $matchgroups[2]; - $patchGroup = $matchgroups[3]; - $preReleaseGroup = $matchgroups[4]; - - # Compose Major.Minor.Patch - $mmp = $majorGroup.Value + "." + $minorGroup.Value + "." + $patchGroup.Value; - - # Check if it is a pre release - $env:MORYX_ASSEMBLY_VERSION = $majorGroup.Value + ".0.0.0" # 3.0.0.0 - $env:MORYX_FILE_VERSION = $mmp + "." + $env:MORYX_BUILDNUMBER; # 3.1.2.42 - - if ($preReleaseGroup.Success) { - $env:MORYX_INFORMATIONAL_VERSION = $mmp + "-" + $preReleaseGroup.Value + "+" + $global:GitCommitHash; # 3.1.2-beta.1+d95a996ed5ba14a1421dafeb844a56ab08211ead - $env:MORYX_PACKAGE_VERSION = $mmp + "-" + $preReleaseGroup.Value; - } else { - $env:MORYX_INFORMATIONAL_VERSION = $mmp + "+" + $global:GitCommitHash; # 3.1.2+d95a996ed5ba14a1421dafeb844a56ab08211ead - $env:MORYX_PACKAGE_VERSION = $mmp; - } -} - -function Read-VersionFromRef([string]$MajorMinorPatch) { - function preReleaseVersion ([string] $name) - { - $name = $name.Replace("/","").ToLower(); - return "$MajorMinorPatch-$name.$env:MORYX_BUILDNUMBER";; - } - - $ref = ""; - if ($env:GITHUB_WORKFLOW) { # GitHub Workflow - Write-Host "Reading version from 'GitHub Workflow'"; - $ref = $env:GITHUB_REF; - - if ($ref.StartsWith("refs/tags/")) { - if ($ref.StartsWith("refs/tags/v")) { - # Its a version tag - $version = $ref.Replace("refs/tags/v","") - } - else { - # Just a tag - $name = $ref.Replace("refs/tags/",""); - $version = = preReleaseVersion($name); - } - } - elseif ($ref.StartsWith("refs/heads/")) { - # Its a branch - $name = $ref.Replace("refs/heads/",""); - $version = preReleaseVersion($name); - } - else { - $version = preReleaseVersion($ref); - } - } - else { # Local build - Write-Host "Reading version from 'local'"; - $ref = (& $global:GitCli rev-parse --abbrev-ref HEAD); - $version = preReleaseVersion($ref); - } - - return $version; -} - -function Set-AssemblyVersion([string]$InputFile) { - $file = Get-Childitem -Path $inputFile; - - if (-Not $file) { - Write-Host "AssemblyInfo: $inputFile was not found!"; - exit 1; - } - - Write-Host "Applying assembly info of $($file.FullName) -> $env:MORYX_ASSEMBLY_VERSION "; - - $assemblyVersionPattern = 'AssemblyVersion\("[0-9]+(\.([0-9]+)){3}"\)'; - $assemblyVersion = 'AssemblyVersion("' + $env:MORYX_ASSEMBLY_VERSION + '")'; - - $assemblyFileVersionPattern = 'AssemblyFileVersion\("[0-9]+(\.([0-9]+)){3}"\)'; - $assemblyFileVersion = 'AssemblyFileVersion("' + $env:MORYX_FILE_VERSION + '")'; - - $assemblyInformationalVersionPattern = 'AssemblyInformationalVersion\("[0-9]+(\.([0-9]+)){3}"\)'; - $assemblyInformationalVersion = 'AssemblyInformationalVersion("' + $env:MORYX_INFORMATIONAL_VERSION + '")'; - - $assemblyConfigurationPattern = 'AssemblyConfiguration\("\w+"\)'; - $assemblyConfiguration = 'AssemblyConfiguration("' + $env:MORYX_BUILD_CONFIG + '")'; - - $content = (Get-Content $file.FullName) | ForEach-Object { - ForEach-Object {$_ -replace $assemblyVersionPattern, $assemblyVersion } | - ForEach-Object {$_ -replace $assemblyFileVersionPattern, $assemblyFileVersion } | - ForEach-Object {$_ -replace $assemblyInformationalVersionPattern, $assemblyInformationalVersion } | - ForEach-Object {$_ -replace $assemblyConfigurationPattern, $assemblyConfiguration } - } - - Out-File -InputObject $content -FilePath $file.FullName -Encoding utf8; -} - -function Set-AssemblyVersions([string[]]$Ignored = $(), [string]$SearchPath = $RootPath) { - $Ignored = $Ignored + "\\.build\\" + "\\Tests\\" + "\\IntegrationTests\\" + "\\SystemTests\\"; - - $assemblyInfos = Get-ChildItem -Path $RootPath -include "*AssemblyInfo.cs" -Recurse | Where-Object { - $fullName = $_.FullName; - return -not ($Ignored.Where({ $fullName -match $_ }).Count -gt 0); - } - - if ($assemblyInfos) - { - Write-Host "Will apply version to $($assemblyInfos.Count) AssemblyInfos."; - foreach ($file in $assemblyInfos) { - Set-AssemblyVersion -InputFile $file; - } - } -} - -function CreateFolderIfNotExists([string]$Folder) { - if (-not (Test-Path $Folder)) { - Write-Host "Creating missing directory '$Folder'" - New-Item $Folder -Type Directory | Out-Null - } -} - -function CopyAndReplaceFolder($SourceDir, $TargetDir) { - Write-Host-Info "Copy $SourceDir to $TargetDir!" - # Remove old folder if exists - if (Test-Path $TargetDir) { - Write-Host "Target path already exists, removing ..." -ForegroundColor Yellow - Remove-Item -Recurse -Force $TargetDir - } - - # Copy to target path - Write-Host "Copy from $SourceDir to $TargetDir ..." -ForegroundColor Green - Copy-Item -Path $SourceDir -Recurse -Destination $TargetDir -Container -} diff --git a/.build/Output.ps1 b/.build/Output.ps1 deleted file mode 100644 index 913f5577b..000000000 --- a/.build/Output.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -################################ -# Functions for Console Output # -################################ - -function Write-Step([string]$step) { - Write-Host "########################################################################################################" -foreground Magenta; - Write-Host "#### $step" -foreground Magenta; - Write-Host "########################################################################################################" -foreground Magenta -} - -function Write-Variable ([string]$variableName, [string]$variableValue) { - Write-Host ($variableName + " = " + $variableValue) -} - -function Invoke-ExitCodeCheck([string]$exitCode) { - if ([int]::Parse($exitCode) -gt 0) { - Write-Host "This is the end, you know (ExitCode: $exitCode) - Lady, the plans we had went all wrong - We ain't nothing but fight and shout and tears." -ForegroundColor Red - exit $exitCode; - } -} - -function Write-Host-Info([string]$message) { - Write-Host $message -} - -function Write-Host-Success([string]$message) { - Write-Host $message -ForegroundColor Green -} - -function Write-Host-Warning([string]$message) { - Write-Host $message -ForegroundColor Yellow -} - -function Write-Host-Error([string]$message) { - Write-Host $message -ForegroundColor Red -} \ No newline at end of file diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index f276f12f5..9bde9ca83 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -12,94 +12,87 @@ on: branches: - dev - future - + env: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true REPOSITORY_NAME: ${{ github.event.repository.name }} + MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package' + MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json' + MORYX_PACKAGE_TARGET_FUTURE: 'https://www.myget.org/F/moryx-future/api/v2/package' + MORYX_PACKAGE_TARGET_V3_FUTURE: 'https://www.myget.org/F/moryx-future/api/v3/index.json' + MORYX_PACKAGE_TARGET_RELEASE: 'https://api.nuget.org/v3/index.json' + MORYX_PACKAGE_TARGET_V3_RELEASE: 'https://api.nuget.org/v3/index.json' jobs: + EnvVar: + runs-on: ubuntu-latest + steps: + - run: echo "" + outputs: + dotnet_sdk_version: ${{ env.dotnet_sdk_version }} + REPOSITORY_NAME: ${{ env.REPOSITORY_NAME }} + MORYX_PACKAGE_TARGET_DEV: ${{ env.MORYX_PACKAGE_TARGET_DEV }} + MORYX_PACKAGE_TARGET_V3_DEV: ${{ env.MORYX_PACKAGE_TARGET_V3_DEV }} + MORYX_PACKAGE_TARGET_FUTURE: ${{ env.MORYX_PACKAGE_TARGET_FUTURE }} + MORYX_PACKAGE_TARGET_V3_FUTURE: ${{ env.MORYX_PACKAGE_TARGET_V3_FUTURE }} + MORYX_PACKAGE_TARGET_RELEASE: ${{ env.MORYX_PACKAGE_TARGET_RELEASE }} + MORYX_PACKAGE_TARGET_V3_RELEASE: ${{ env.MORYX_PACKAGE_TARGET_V3_RELEASE }} + Build: - uses: PHOENIXCONTACT/tools/.github/workflows/build-tool.yml@main + needs: [EnvVar] + uses: phoenixcontact/tools/.github/workflows/build-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} UnitTests: - needs: [Build] - uses: PHOENIXCONTACT/tools/.github/workflows/unittest-tool.yml@main + needs: [EnvVar, Build] + uses: phoenixcontact/tools/.github/workflows/unittest-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} IntegrationTests: - needs: [Build] - uses: PHOENIXCONTACT/tools/.github/workflows/integrationtest-tool.yml@main + needs: [EnvVar, Build] + uses: phoenixcontact/tools/.github/workflows/integrationtest-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} ReportGenerator: - needs: [UnitTests, IntegrationTests] - uses: PHOENIXCONTACT/tools/.github/workflows/reportgenerator-tool.yml@main + needs: [EnvVar, UnitTests, IntegrationTests] + uses: phoenixcontact/tools/.github/workflows/reportgenerator-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} Publish-Test-Coverage: - needs: [ReportGenerator] - uses: PHOENIXCONTACT/tools/.github/workflows/publish-test-coverage-tool.yml@main + needs: [EnvVar, ReportGenerator] + uses: phoenixcontact/tools/.github/workflows/publish-test-coverage-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - Documentation: - needs: [UnitTests] - uses: PHOENIXCONTACT/tools/.github/workflows/documentation-tool.yml@main - with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + # currently not working + # Documentation: + # needs: [EnvVar, UnitTests] + # uses: phoenixcontact/tools/.github/workflows/documentation-tool.yml@future + # with: + # REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} Publish: - needs: [UnitTests] - uses: PHOENIXCONTACT/tools/.github/workflows/publish-tool.yml@main + needs: [EnvVar, UnitTests] + uses: phoenixcontact/tools/.github/workflows/publish-tool.yml@future with: - MORYX_OPTIMIZE_CODE: "false" - MORYX_BUILD_CONFIG: "Release" - MORYX_BUILDNUMBER: ${{github.run_number}} - dotnet_sdk_version: '7.x' - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - REPOSITORY_NAME: ${{ github.event.repository.name }} + dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} + REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} + MORYX_PACKAGE_TARGET_DEV: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_DEV }} + MORYX_PACKAGE_TARGET_V3_DEV: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_V3_DEV }} + MORYX_PACKAGE_TARGET_FUTURE: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_FUTURE }} + MORYX_PACKAGE_TARGET_V3_FUTURE: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_V3_FUTURE }} + MORYX_PACKAGE_TARGET_RELEASE: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_RELEASE }} + MORYX_PACKAGE_TARGET_V3_RELEASE: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_V3_RELEASE }} secrets: MYGET_TOKEN: ${{secrets.MYGET_TOKEN}} - NUGET_TOKEN: ${{secrets.NUGET_TOKEN}} + NUGET_TOKEN: ${{secrets.NUGET_TOKEN}} \ No newline at end of file diff --git a/Build.ps1 b/Build.ps1 deleted file mode 100644 index 4b65211d1..000000000 --- a/Build.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -param ( - [switch]$SetAssemblyVersion, - [switch]$Build, - - [switch]$SmokeTests, - [switch]$UnitTests, - [switch]$IntegrationTests, - [switch]$SystemTests, - - [switch]$CoverReport, - [switch]$GenerateDocs, - - [switch]$Pack, - [switch]$Publish -) - -# Load Toolkit -. ".build\BuildToolkit.ps1" - -# Set MSBuild to latest version -$MsBuildVersion = "latest"; - -# Initialize Toolkit -Invoke-Initialize -Version (Get-Content "VERSION"); - -if ($Build) { - Invoke-Build ".\MORYX-Framework.sln" -} - -if ($SmokeTests) { - $runtimePath = "$RootPath\src\StartProject\bin\$env:MORYX_BUILD_CONFIG\StartProject.exe"; - Invoke-SmokeTest $runtimePath 3 6000 -} - -if ($UnitTests) { - Invoke-CoverTests -SearchFilter "*.Tests.csproj" -} - -if ($IntegrationTests) { - Invoke-CoverTests -SearchFilter "*.IntegrationTests.csproj" -} - -if ($SystemTests) { - Invoke-CoverTests -SearchFilter "*.SystemTests.csproj" -} - -if ($CoverReport) { - Invoke-CoverReport -} - -if ($GenerateDocs) { - Invoke-DocFx -} - -if ($Pack) { - Invoke-PackAll -Symbols -} - -if ($Publish) { - Invoke-Publish -} - -Write-Host "Success!" \ No newline at end of file diff --git a/Directory.build.props b/Directory.Build.props similarity index 91% rename from Directory.build.props rename to Directory.Build.props index 52d408eb4..a5baa5c61 100644 --- a/Directory.build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 9.0 + latest diff --git a/Directory.Build.targets b/Directory.Build.targets index 1e4f23370..521421535 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -7,6 +7,7 @@ 6.0.0 6.0.0 + latest diff --git a/src/Tests/Directory.Build.props b/src/Tests/Directory.Build.props new file mode 100644 index 000000000..a2119370e --- /dev/null +++ b/src/Tests/Directory.Build.props @@ -0,0 +1,5 @@ + + + false + + \ No newline at end of file diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs index 1eb19a2f3..2e28b0f30 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs @@ -9,6 +9,9 @@ namespace Moryx.Communication.Sockets.IntegrationTests { + // preprocessor statement for differentiating between different os + // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) + #if _WINDOWS [TestFixture] public class CommunicationSocketsTests : CommunicationSocketsTestsBase> { @@ -129,4 +132,5 @@ public void SendEmptyMessages() WaitForConnectionState(0, new TimeSpan(0, 0, 0, 1), BinaryConnectionState.AttemptingConnection); } } + #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs index fc3b866b5..1196f240e 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs @@ -11,6 +11,9 @@ namespace Moryx.Communication.Sockets.IntegrationTests { + // preprocessor statement for differentiating between different os + // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) + #if _WINDOWS public abstract class CommunicationSocketsTestsBase where TMessage : BinaryMessage { private List> _serverConnections; @@ -340,4 +343,5 @@ protected static TcpListenerConfig CreateServerConfig(IPAddress adress, int port }; } } + #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs index 8cf86bb2f..4e0955067 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs @@ -8,6 +8,9 @@ namespace Moryx.Communication.Sockets.IntegrationTests.DelimiterProtocol { + // preprocessor statement for differentiating between different os + // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) + #if _WINDOWS [TestFixture] public class DelimiterCommunicationSocketTests : CommunicationSocketsTestsBase { @@ -66,4 +69,5 @@ public void SendDelimitedMessage() EndDelimiterOnlyInterpreter.TestEndDelimiter.Length, published.Payload.Length); } } + #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs index 44d6018a9..72e6d7b2a 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs @@ -10,6 +10,9 @@ namespace Moryx.Communication.Sockets.IntegrationTests { + // preprocessor statement for differentiating between different os + // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) + #if _WINDOWS [TestFixture] public class HeaderedCommunicationSocketTests : CommunicationSocketsTestsBase> { @@ -299,4 +302,5 @@ protected override BinaryMessage CreateMessage(int senderId, byte[] payload) return new BinaryMessage(header, payload); } } + #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj index 6f1956905..9df967ee6 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj @@ -6,6 +6,10 @@ full + + _WINDOWS + + diff --git a/src/Tests/Moryx.Model.Tests/SqliteTests.cs b/src/Tests/Moryx.Model.Tests/SqliteTests.cs index c413731a2..335237e51 100644 --- a/src/Tests/Moryx.Model.Tests/SqliteTests.cs +++ b/src/Tests/Moryx.Model.Tests/SqliteTests.cs @@ -1,16 +1,8 @@ -using Microsoft.Extensions.Logging; -using Moryx.Model.InMemory; -using Moryx.Model.Sqlite; +using Moryx.Model.Sqlite; using Moryx.Products.Model; -using Moryx.Runtime.Endpoints.Databases.Endpoint.Services; using Moryx.Runtime.Kernel; -using Moryx.TestTools.Test.Model; using NUnit.Framework; -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Moryx.Model.Tests @@ -26,7 +18,7 @@ public class SqliteTests public void Setup() { string databaseName = "TestDatabase"; - datasource = $".\\db\\{databaseName}.db"; + datasource = Path.Combine(".", "db", databaseName+".db"); string connectionString = $@"Data Source={datasource};"; dbConfig = new SqliteDatabaseConfig(); dbConfig.ConnectionSettings = new DatabaseConnectionSettings { ConnectionString = connectionString, Database = databaseName }; @@ -80,6 +72,5 @@ public void Destroy() configurator.DeleteDatabase(dbConfig).Wait(); } - } } From 5b5bd47cd007a7c55e4d495885158eba25bd1504 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Fri, 16 Jun 2023 06:47:56 +0200 Subject: [PATCH 05/57] Update references to 8.0.0-preview.5 --- .github/workflows/build-and-test.yml | 2 +- Directory.Build.targets | 12 ++++++------ .../Moryx.AbstractionLayer.Products.Endpoints.csproj | 2 +- ...Moryx.AbstractionLayer.Resources.Endpoints.csproj | 4 ++-- .../Moryx.AbstractionLayer.TestTools.csproj | 2 +- .../Moryx.AbstractionLayer.csproj | 2 +- src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj | 2 +- .../Moryx.CommandCenter.Web.csproj | 2 +- .../Moryx.Communication.Serial.csproj | 2 +- src/Moryx.Container/Moryx.Container.csproj | 2 +- .../Moryx.DependentTestModule.csproj | 2 +- src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj | 2 +- .../Moryx.Model.PostgreSQL.csproj | 2 +- src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj | 2 +- src/Moryx.Model/Moryx.Model.csproj | 2 +- src/Moryx.Notifications/Moryx.Notifications.csproj | 2 +- .../Moryx.Products.Management.csproj | 2 +- src/Moryx.Products.Model/Moryx.Products.Model.csproj | 2 +- .../Moryx.Products.Samples.csproj | 2 +- .../Moryx.Resources.Management.csproj | 2 +- .../Moryx.Resources.Samples.csproj | 2 +- .../Moryx.Runtime.Endpoints.csproj | 2 +- src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj | 2 +- src/Moryx.Runtime/Moryx.Runtime.csproj | 2 +- src/Moryx.TestModule/Moryx.TestModule.csproj | 2 +- .../Moryx.TestTools.Test.Model.csproj | 2 +- .../Moryx.TestTools.UnitTest.csproj | 2 +- src/Moryx/Moryx.csproj | 2 +- src/StartProject.Asp/StartProject.Asp.csproj | 2 +- .../Moryx.AbstractionLayer.Tests.csproj | 2 +- ...ryx.Communication.Sockets.IntegrationTests.csproj | 2 +- .../Moryx.Container.TestPlugin.csproj | 2 +- .../Moryx.Container.TestRootPlugin.csproj | 2 +- .../Moryx.Container.TestTools.csproj | 2 +- .../Moryx.Container.Tests.csproj | 2 +- src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj | 2 +- .../Moryx.Notifications.Tests.csproj | 2 +- .../Moryx.Products.IntegrationTests.csproj | 2 +- ....AbstractionLayer.Products.Endpoints.Tests.csproj | 2 +- .../Moryx.Resources.Management.Tests.csproj | 2 +- .../Moryx.Runtime.Endpoints.Tests.csproj | 2 +- .../Moryx.Runtime.Kernel.Tests.csproj | 2 +- .../Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj | 2 +- src/Tests/Moryx.Tests/Moryx.Tests.csproj | 2 +- 44 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 9bde9ca83..67d3e1b88 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,7 +14,7 @@ on: - future env: - dotnet_sdk_version: '7.x' + dotnet_sdk_version: '8.0.100-preview.5.23303.2' REPOSITORY_NAME: ${{ github.event.repository.name }} MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package' MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json' diff --git a/Directory.Build.targets b/Directory.Build.targets index 521421535..d7fb096cb 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -4,15 +4,15 @@ - 6.0.0 - 6.0.0 + 8.0.0-preview.* + 8.0.0-preview.* latest - + @@ -21,8 +21,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -44,7 +44,7 @@ - + diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj b/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj index 4e5cd128d..a912a5507 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Endpoints for the Product Facade true true diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj b/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj index 8c981b0b2..cf4f3350d 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 true REST Api in order to interact with the resource management true diff --git a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj index bde0a3899..04b58a92f 100644 --- a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj +++ b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true Additional AbstractionLayer implementations for Tests true diff --git a/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj b/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj index 6ce2a84f3..2bd6f6433 100644 --- a/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj +++ b/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true Domain model types and definitions of Cyber-physical systems in IIoT projects. true diff --git a/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj b/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj index ea47f4474..3bc5f8156 100644 --- a/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj +++ b/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 Extensions for the Integration of MORYX in ASP.NET Core true MORYX;ASP diff --git a/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj b/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj index 2ebb93bb3..bde6f97b1 100644 --- a/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj +++ b/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj @@ -8,7 +8,7 @@ - net6.0 + net8.0 true true diff --git a/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj b/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj index 41dda1c2d..d26930255 100644 --- a/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj +++ b/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true MORYX binary connection for serial communication true diff --git a/src/Moryx.Container/Moryx.Container.csproj b/src/Moryx.Container/Moryx.Container.csproj index d4aaf59c8..ed472f116 100644 --- a/src/Moryx.Container/Moryx.Container.csproj +++ b/src/Moryx.Container/Moryx.Container.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true MORYX container functionality based on Castle.Windsor. true diff --git a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj index ccd3319d9..989e70890 100644 --- a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj +++ b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 Moryx Runtime Module: DependentTestModule diff --git a/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj b/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj index 7331a134a..68ede0d8c 100644 --- a/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj +++ b/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true InMemory extension for unit tests referencing Moryx.Model true diff --git a/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj b/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj index 19320c878..016742711 100644 --- a/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj +++ b/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true Adapter for Moryx.Model on PostgreSQL true diff --git a/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj b/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj index a3f48238e..a7c96cb27 100644 --- a/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj +++ b/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true Adapter for Moryx.Model on Sqlite true diff --git a/src/Moryx.Model/Moryx.Model.csproj b/src/Moryx.Model/Moryx.Model.csproj index 9b3e63695..059f3ba71 100644 --- a/src/Moryx.Model/Moryx.Model.csproj +++ b/src/Moryx.Model/Moryx.Model.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true Datamodel integration for MORYX applications based on Entity Framework true diff --git a/src/Moryx.Notifications/Moryx.Notifications.csproj b/src/Moryx.Notifications/Moryx.Notifications.csproj index 8a7719414..4cf00f863 100644 --- a/src/Moryx.Notifications/Moryx.Notifications.csproj +++ b/src/Moryx.Notifications/Moryx.Notifications.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true Types and interfaces for notifications within MORYX applications true diff --git a/src/Moryx.Products.Management/Moryx.Products.Management.csproj b/src/Moryx.Products.Management/Moryx.Products.Management.csproj index 9507af634..94f9ce7de 100644 --- a/src/Moryx.Products.Management/Moryx.Products.Management.csproj +++ b/src/Moryx.Products.Management/Moryx.Products.Management.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true ProductManagement module hosting product types and instances, as well as recipes and workplans. true diff --git a/src/Moryx.Products.Model/Moryx.Products.Model.csproj b/src/Moryx.Products.Model/Moryx.Products.Model.csproj index 25b61d2de..7a5f1f765 100644 --- a/src/Moryx.Products.Model/Moryx.Products.Model.csproj +++ b/src/Moryx.Products.Model/Moryx.Products.Model.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true Database model for the ProductManagement module true diff --git a/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj b/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj index 5208563fb..82216f239 100644 --- a/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj +++ b/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false diff --git a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj index 5e84cc851..5081c4556 100644 --- a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj +++ b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 true ResourceManagement module composing and maintaining the resource graph as the habitat for digital twins of manufacturing assets. true diff --git a/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj b/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj index 18561d82d..e76d4c89e 100644 --- a/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj +++ b/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true diff --git a/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj b/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj index bb98cf126..cf3c51ceb 100644 --- a/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj +++ b/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 true diff --git a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj index fdc0e91d4..5bfe48ccb 100644 --- a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj +++ b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true Kernel components that comprise the MORYX server side runtime environment true diff --git a/src/Moryx.Runtime/Moryx.Runtime.csproj b/src/Moryx.Runtime/Moryx.Runtime.csproj index 80aec6d44..1da28113c 100644 --- a/src/Moryx.Runtime/Moryx.Runtime.csproj +++ b/src/Moryx.Runtime/Moryx.Runtime.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true Server side component types and implementations for MORYX applications true diff --git a/src/Moryx.TestModule/Moryx.TestModule.csproj b/src/Moryx.TestModule/Moryx.TestModule.csproj index 5c0ca9a73..3520b8818 100644 --- a/src/Moryx.TestModule/Moryx.TestModule.csproj +++ b/src/Moryx.TestModule/Moryx.TestModule.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Moryx Runtime Module: TestModuleKestrel. Library diff --git a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj index 504e58611..943e7aeb1 100644 --- a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj +++ b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj b/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj index 7428d8136..81265093b 100644 --- a/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj +++ b/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true Library with helper classes for UnitTests. true diff --git a/src/Moryx/Moryx.csproj b/src/Moryx/Moryx.csproj index 67387d757..d4aff4303 100644 --- a/src/Moryx/Moryx.csproj +++ b/src/Moryx/Moryx.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net6.0 + netstandard2.0;net8.0 true true Core package of the MORYX ecosystem. It defines the necessary types for MORYX compatibility as well as commonly required tools. diff --git a/src/StartProject.Asp/StartProject.Asp.csproj b/src/StartProject.Asp/StartProject.Asp.csproj index 92678d733..1fabe3f24 100644 --- a/src/StartProject.Asp/StartProject.Asp.csproj +++ b/src/StartProject.Asp/StartProject.Asp.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 StartProject of the MORYX-Framework. This is for debugging only. diff --git a/src/Tests/Moryx.AbstractionLayer.Tests/Moryx.AbstractionLayer.Tests.csproj b/src/Tests/Moryx.AbstractionLayer.Tests/Moryx.AbstractionLayer.Tests.csproj index df430c0a8..dfd8f9912 100644 --- a/src/Tests/Moryx.AbstractionLayer.Tests/Moryx.AbstractionLayer.Tests.csproj +++ b/src/Tests/Moryx.AbstractionLayer.Tests/Moryx.AbstractionLayer.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false full diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj index 9df967ee6..ad0e426c8 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net8.0 full diff --git a/src/Tests/Moryx.Container.TestPlugin/Moryx.Container.TestPlugin.csproj b/src/Tests/Moryx.Container.TestPlugin/Moryx.Container.TestPlugin.csproj index 3e4347729..7c6fa2a02 100644 --- a/src/Tests/Moryx.Container.TestPlugin/Moryx.Container.TestPlugin.csproj +++ b/src/Tests/Moryx.Container.TestPlugin/Moryx.Container.TestPlugin.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/src/Tests/Moryx.Container.TestRootPlugin/Moryx.Container.TestRootPlugin.csproj b/src/Tests/Moryx.Container.TestRootPlugin/Moryx.Container.TestRootPlugin.csproj index 3e4347729..7c6fa2a02 100644 --- a/src/Tests/Moryx.Container.TestRootPlugin/Moryx.Container.TestRootPlugin.csproj +++ b/src/Tests/Moryx.Container.TestRootPlugin/Moryx.Container.TestRootPlugin.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/src/Tests/Moryx.Container.TestTools/Moryx.Container.TestTools.csproj b/src/Tests/Moryx.Container.TestTools/Moryx.Container.TestTools.csproj index dc57d1125..4c4707fa3 100644 --- a/src/Tests/Moryx.Container.TestTools/Moryx.Container.TestTools.csproj +++ b/src/Tests/Moryx.Container.TestTools/Moryx.Container.TestTools.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj b/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj index ca366b30c..4dfd568fc 100644 --- a/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj +++ b/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Library full diff --git a/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj b/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj index f692d2370..26e8e1f1e 100644 --- a/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj +++ b/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Library full diff --git a/src/Tests/Moryx.Notifications.Tests/Moryx.Notifications.Tests.csproj b/src/Tests/Moryx.Notifications.Tests/Moryx.Notifications.Tests.csproj index 094742684..1940dd422 100644 --- a/src/Tests/Moryx.Notifications.Tests/Moryx.Notifications.Tests.csproj +++ b/src/Tests/Moryx.Notifications.Tests/Moryx.Notifications.Tests.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net8.0 full diff --git a/src/Tests/Moryx.Products.IntegrationTests/Moryx.Products.IntegrationTests.csproj b/src/Tests/Moryx.Products.IntegrationTests/Moryx.Products.IntegrationTests.csproj index beb45acc9..d28118d39 100644 --- a/src/Tests/Moryx.Products.IntegrationTests/Moryx.Products.IntegrationTests.csproj +++ b/src/Tests/Moryx.Products.IntegrationTests/Moryx.Products.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false full diff --git a/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj b/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj index 7cb39db8f..de0cad0be 100644 --- a/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj +++ b/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false full diff --git a/src/Tests/Moryx.Resources.Management.Tests/Moryx.Resources.Management.Tests.csproj b/src/Tests/Moryx.Resources.Management.Tests/Moryx.Resources.Management.Tests.csproj index 67acc5147..ed77ed38d 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Moryx.Resources.Management.Tests.csproj +++ b/src/Tests/Moryx.Resources.Management.Tests/Moryx.Resources.Management.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false full diff --git a/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj b/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj index 14b1d6e96..d8c44f249 100644 --- a/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj b/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj index 12e208480..ce8d4a08d 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Library full diff --git a/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj b/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj index 12e208480..ce8d4a08d 100644 --- a/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Library full diff --git a/src/Tests/Moryx.Tests/Moryx.Tests.csproj b/src/Tests/Moryx.Tests/Moryx.Tests.csproj index 1ff29d6a4..29b8cd319 100644 --- a/src/Tests/Moryx.Tests/Moryx.Tests.csproj +++ b/src/Tests/Moryx.Tests/Moryx.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Library full From c3d219339d9881325c9ddbfadf71ad1576deeae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Sch=C3=B6ne?= Date: Wed, 28 Jun 2023 10:49:14 +0200 Subject: [PATCH 06/57] Delete CreatePackage flag and add IsPackable false, if necessary --- .../Moryx.AbstractionLayer.Products.Endpoints.csproj | 1 - .../Moryx.AbstractionLayer.Resources.Endpoints.csproj | 1 - .../Moryx.AbstractionLayer.TestTools.csproj | 1 - src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj | 1 - src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj | 1 - src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj | 1 - src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj | 1 - src/Moryx.Container/Moryx.Container.csproj | 1 - src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj | 1 + src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj | 1 - src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj | 1 - src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj | 1 - src/Moryx.Model/Moryx.Model.csproj | 1 - src/Moryx.Notifications/Moryx.Notifications.csproj | 1 - src/Moryx.Products.Management/Moryx.Products.Management.csproj | 1 - src/Moryx.Products.Model/Moryx.Products.Model.csproj | 1 - src/Moryx.Products.Samples/Moryx.Products.Samples.csproj | 1 + src/Moryx.Resources.Management/Moryx.Resources.Management.csproj | 1 - src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj | 1 + src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj | 1 - src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj | 1 - src/Moryx.Runtime/Moryx.Runtime.csproj | 1 - src/Moryx.TestModule/Moryx.TestModule.csproj | 1 + src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj | 1 + src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj | 1 - src/Moryx/Moryx.csproj | 1 - 26 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj b/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj index a912a5507..b5eeaf342 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/Moryx.AbstractionLayer.Products.Endpoints.csproj @@ -4,7 +4,6 @@ net8.0 Endpoints for the Product Facade true - true MORYX;IIoT;IoT; diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj b/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj index cf4f3350d..21907fa30 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/Moryx.AbstractionLayer.Resources.Endpoints.csproj @@ -4,7 +4,6 @@ net8.0 true REST Api in order to interact with the resource management - true MORYX;IIoT;IoT;Resource diff --git a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj index 04b58a92f..f572eb116 100644 --- a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj +++ b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj @@ -4,7 +4,6 @@ net8.0 true Additional AbstractionLayer implementations for Tests - true MORYX;IIoT;IoT;Abstraction;Tests diff --git a/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj b/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj index 2bd6f6433..f3779fc05 100644 --- a/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj +++ b/src/Moryx.AbstractionLayer/Moryx.AbstractionLayer.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true Domain model types and definitions of Cyber-physical systems in IIoT projects. - true MORYX;IIoT;IoT;Hardware;Communication;Manufacturing;Industrial;Abstraction;Realtime diff --git a/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj b/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj index 3bc5f8156..27255d156 100644 --- a/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj +++ b/src/Moryx.Asp.Extensions/Moryx.Asp.Extensions.csproj @@ -3,7 +3,6 @@ net8.0 Extensions for the Integration of MORYX in ASP.NET Core - true MORYX;ASP diff --git a/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj b/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj index bde6f97b1..3b23fff5b 100644 --- a/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj +++ b/src/Moryx.CommandCenter.Web/Moryx.CommandCenter.Web.csproj @@ -10,7 +10,6 @@ net8.0 true - true diff --git a/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj b/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj index d26930255..353b1adb0 100644 --- a/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj +++ b/src/Moryx.Communication.Serial/Moryx.Communication.Serial.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true MORYX binary connection for serial communication - true MORYX;Communication;Serial;Ports diff --git a/src/Moryx.Container/Moryx.Container.csproj b/src/Moryx.Container/Moryx.Container.csproj index ed472f116..dec10b0f8 100644 --- a/src/Moryx.Container/Moryx.Container.csproj +++ b/src/Moryx.Container/Moryx.Container.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true MORYX container functionality based on Castle.Windsor. - true MORYX;Container;IoC diff --git a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj index 989e70890..b3691c8a7 100644 --- a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj +++ b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj @@ -4,6 +4,7 @@ net8.0 Moryx Runtime Module: DependentTestModule + false diff --git a/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj b/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj index 68ede0d8c..f6de585e6 100644 --- a/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj +++ b/src/Moryx.Model.InMemory/Moryx.Model.InMemory.csproj @@ -4,7 +4,6 @@ net8.0 true InMemory extension for unit tests referencing Moryx.Model - true MORYX;Entity;Framework;EntityFramework;DataModel;Model;Database;InMemory;Effort diff --git a/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj b/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj index 016742711..e45126e44 100644 --- a/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj +++ b/src/Moryx.Model.PostgreSQL/Moryx.Model.PostgreSQL.csproj @@ -4,7 +4,6 @@ net8.0 true Adapter for Moryx.Model on PostgreSQL - true MORYX;Entity;Framework;EntityFramework;DataModel;Model;Database;Npgsql;PostgreSQL;Postgres diff --git a/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj b/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj index a7c96cb27..7ab5ba4bc 100644 --- a/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj +++ b/src/Moryx.Model.Sqlite/Moryx.Model.Sqlite.csproj @@ -4,7 +4,6 @@ net8.0 true Adapter for Moryx.Model on Sqlite - true MORYX;Entity;Framework;EntityFramework;DataModel;Model;Database;Sqlite diff --git a/src/Moryx.Model/Moryx.Model.csproj b/src/Moryx.Model/Moryx.Model.csproj index 059f3ba71..31addd467 100644 --- a/src/Moryx.Model/Moryx.Model.csproj +++ b/src/Moryx.Model/Moryx.Model.csproj @@ -4,7 +4,6 @@ net8.0 true Datamodel integration for MORYX applications based on Entity Framework - true MORYX;Entity;Framework;EntityFramework;DataModel;Model;Database diff --git a/src/Moryx.Notifications/Moryx.Notifications.csproj b/src/Moryx.Notifications/Moryx.Notifications.csproj index 4cf00f863..c4842c763 100644 --- a/src/Moryx.Notifications/Moryx.Notifications.csproj +++ b/src/Moryx.Notifications/Moryx.Notifications.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true Types and interfaces for notifications within MORYX applications - true MORYX;IIoT;IoT;Notifications diff --git a/src/Moryx.Products.Management/Moryx.Products.Management.csproj b/src/Moryx.Products.Management/Moryx.Products.Management.csproj index 94f9ce7de..30ae80781 100644 --- a/src/Moryx.Products.Management/Moryx.Products.Management.csproj +++ b/src/Moryx.Products.Management/Moryx.Products.Management.csproj @@ -4,7 +4,6 @@ net8.0 true ProductManagement module hosting product types and instances, as well as recipes and workplans. - true MORYX;IIoT;IoT;Product;Manufacturing;Management;API diff --git a/src/Moryx.Products.Model/Moryx.Products.Model.csproj b/src/Moryx.Products.Model/Moryx.Products.Model.csproj index 7a5f1f765..5291b228b 100644 --- a/src/Moryx.Products.Model/Moryx.Products.Model.csproj +++ b/src/Moryx.Products.Model/Moryx.Products.Model.csproj @@ -4,7 +4,6 @@ net8.0 true Database model for the ProductManagement module - true MORYX;IIoT;IoT;Product;Manufacturing;Management diff --git a/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj b/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj index 82216f239..ccd43227d 100644 --- a/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj +++ b/src/Moryx.Products.Samples/Moryx.Products.Samples.csproj @@ -3,6 +3,7 @@ net8.0 false + false diff --git a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj index 5081c4556..ecff4994c 100644 --- a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj +++ b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj @@ -4,7 +4,6 @@ net8.0 true ResourceManagement module composing and maintaining the resource graph as the habitat for digital twins of manufacturing assets. - true MORYX;IIoT;IoT;Manufacturing;API;Resource diff --git a/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj b/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj index e76d4c89e..8c94687ef 100644 --- a/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj +++ b/src/Moryx.Resources.Samples/Moryx.Resources.Samples.csproj @@ -3,6 +3,7 @@ netstandard2.0;net8.0 true + false diff --git a/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj b/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj index cf3c51ceb..ceda8ed4d 100644 --- a/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj +++ b/src/Moryx.Runtime.Endpoints/Moryx.Runtime.Endpoints.csproj @@ -2,7 +2,6 @@ net8.0 - true diff --git a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj index 5bfe48ccb..6b50d5ad1 100644 --- a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj +++ b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true Kernel components that comprise the MORYX server side runtime environment - true MORYX;Kernel;Runtime;Server diff --git a/src/Moryx.Runtime/Moryx.Runtime.csproj b/src/Moryx.Runtime/Moryx.Runtime.csproj index 1da28113c..8c4839e1c 100644 --- a/src/Moryx.Runtime/Moryx.Runtime.csproj +++ b/src/Moryx.Runtime/Moryx.Runtime.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true Server side component types and implementations for MORYX applications - true MORYX;Runtime;Server diff --git a/src/Moryx.TestModule/Moryx.TestModule.csproj b/src/Moryx.TestModule/Moryx.TestModule.csproj index 3520b8818..4a68a1cf7 100644 --- a/src/Moryx.TestModule/Moryx.TestModule.csproj +++ b/src/Moryx.TestModule/Moryx.TestModule.csproj @@ -4,6 +4,7 @@ net8.0 Moryx Runtime Module: TestModuleKestrel. Library + false diff --git a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj index 943e7aeb1..3fa69dc19 100644 --- a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj +++ b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj @@ -2,6 +2,7 @@ net8.0 + false diff --git a/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj b/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj index 81265093b..872b1a81d 100644 --- a/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj +++ b/src/Moryx.TestTools.UnitTest/Moryx.TestTools.UnitTest.csproj @@ -4,7 +4,6 @@ netstandard2.0;net8.0 true Library with helper classes for UnitTests. - true MORYX;Tests;UnitTests diff --git a/src/Moryx/Moryx.csproj b/src/Moryx/Moryx.csproj index d4aff4303..39398326e 100644 --- a/src/Moryx/Moryx.csproj +++ b/src/Moryx/Moryx.csproj @@ -5,7 +5,6 @@ true true Core package of the MORYX ecosystem. It defines the necessary types for MORYX compatibility as well as commonly required tools. - true MORYX;Serialization;Configuration;Logging;Core;Modules;Workplans From 6e2a19133ceed66f5e8e606ba90939c0846bc0e8 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Fri, 21 Jul 2023 22:17:59 +0200 Subject: [PATCH 07/57] Update and simplify container --- Directory.Build.targets | 4 +- .../ResourceManagementController.cs | 4 +- src/Moryx.Container/CastleContainer.cs | 52 +++++++++-- .../Installer/ComponentRegistrator.cs | 29 +++++-- .../Installer/DoubleRegistrationCheck.cs | 20 ----- .../Installer/IConfiguredInstaller.cs | 13 --- .../LocalContainer/LocalContainer.cs | 87 ------------------- .../LocalContainer/LocalRegistrator.cs | 44 ---------- src/Moryx.Model/DbContextManager.cs | 1 - .../Storage/AutoConfigurator.cs | 4 +- .../Modules/Endpoint/ModulesController.cs | 13 +-- .../Configuration/ConfigManager.cs | 1 - .../Container/ModuleContainerFactory.cs | 3 +- .../Modules/ModuleManager.cs | 1 - src/Moryx.Runtime/Container/IContainerHost.cs | 25 ------ src/Moryx.Runtime/Modules/IServerModule.cs | 7 ++ src/Moryx.Runtime/Modules/ServerModuleBase.cs | 3 +- .../ServerModuleFacadeControllerBase.cs | 3 +- .../Attributes/ComponentAttribute.cs | 39 +++++++-- .../DependencyRegistrationAttribute.cs | 3 +- .../FactoryRegistrationAttribute.cs | 68 --------------- .../Attributes/GlobalComponentAttribute.cs | 22 ----- .../Attributes/KernelComponentAttribute.cs | 55 ------------ .../Attributes/PluginFactoryAttribute.cs | 22 +++-- .../Attributes/RegistrationAttribute.cs | 56 ------------ src/Moryx/Container/IComponentRegistrator.cs | 2 +- .../PluginNameSelectorAttribute.cs | 2 +- .../Local/LocalContainerTest.cs | 6 +- .../Local/StrategySelectionTest.cs | 2 +- .../Moryx.Container.Tests/Named/Component.cs | 2 +- .../Registrator/NamedDummy.cs | 4 +- .../ModuleMocks/ModuleBase.cs | 3 + .../Moryx.Runtime.Tests/ModuleBaseTest.cs | 3 +- 33 files changed, 148 insertions(+), 455 deletions(-) delete mode 100644 src/Moryx.Container/Installer/DoubleRegistrationCheck.cs delete mode 100644 src/Moryx.Container/Installer/IConfiguredInstaller.cs delete mode 100644 src/Moryx.Container/LocalContainer/LocalContainer.cs delete mode 100644 src/Moryx.Container/LocalContainer/LocalRegistrator.cs delete mode 100644 src/Moryx.Runtime/Container/IContainerHost.cs delete mode 100644 src/Moryx/Container/Attributes/FactoryRegistrationAttribute.cs delete mode 100644 src/Moryx/Container/Attributes/GlobalComponentAttribute.cs delete mode 100644 src/Moryx/Container/Attributes/KernelComponentAttribute.cs delete mode 100644 src/Moryx/Container/Attributes/RegistrationAttribute.cs diff --git a/Directory.Build.targets b/Directory.Build.targets index d7fb096cb..6eae9de9e 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -47,9 +47,7 @@ - - - + diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs index 76338d25b..a2e8b1099 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs @@ -15,7 +15,6 @@ using Moryx.Tools; using Moryx.AbstractionLayer.Properties; using Moryx.Runtime.Modules; -using Moryx.Runtime.Container; namespace Moryx.AbstractionLayer.Resources.Endpoints { @@ -36,8 +35,7 @@ public ResourceModificationController(IResourceManagement resourceManagement, IR _resourceManagement = resourceManagement ?? throw new ArgumentNullException(nameof(resourceManagement)); _resourceTypeTree = resourceTypeTree ?? throw new ArgumentNullException(nameof(resourceTypeTree)); var module = moduleManager.AllModules.FirstOrDefault(module => module is IFacadeContainer); - var containerHost = (IContainerHost)module; - _serialization = new ResourceSerialization(containerHost.Container); + _serialization = new ResourceSerialization(module.Container); } [HttpGet] diff --git a/src/Moryx.Container/CastleContainer.cs b/src/Moryx.Container/CastleContainer.cs index 40f1ee2a0..1052928d8 100644 --- a/src/Moryx.Container/CastleContainer.cs +++ b/src/Moryx.Container/CastleContainer.cs @@ -30,12 +30,22 @@ public class CastleContainer : IContainer #region Constructors + private readonly IDictionary _strategies; + /// - /// Create new container instance with default registrator + /// Create instance without strategies /// public CastleContainer() - : this(new ComponentRegistrator()) + : this(new Dictionary()) + { + } + /// + /// Create container with strategies + /// + /// + public CastleContainer(IDictionary strategies) { + _strategies = strategies; } /// @@ -82,7 +92,10 @@ public IContainer ExecuteInstaller(IContainerInstaller installer) /// Instance of type public virtual T Resolve() { - return Container.Kernel.HasComponent(typeof(T)) ? Container.Resolve() : default(T); + var service = typeof(T); + return _strategies.ContainsKey(service) + ? Resolve(_strategies[service]) + : Container.Kernel.HasComponent(typeof(T)) ? Container.Resolve() : default(T); } /// @@ -90,7 +103,9 @@ public virtual T Resolve() /// public virtual object Resolve(Type service) { - return Container.Kernel.HasComponent(service) ? Container.Resolve(service) : null; + return _strategies.ContainsKey(service) + ? Resolve(service, _strategies[service]) + : Container.Kernel.HasComponent(service) ? Container.Resolve(service) : null; } /// @@ -161,16 +176,39 @@ public virtual void LoadComponents(Predicate condition) where T : class _knownTypes = ReflectionTool.GetAssemblies() .Where(a => a.GetCustomAttribute() == null) .SelectMany(a => a.GetTypes()) - .Where(t => t.GetCustomAttribute(true) != null).ToArray(); + .Where(t => t.GetCustomAttribute(true) != null).ToArray(); } foreach (var type in _knownTypes.Where(type => typeof(T).IsAssignableFrom(type))) { - if(Registrator.ShallInstall(type) && (condition?.Invoke(type) ?? true)) + if (Registrator.ShallInstall(type) && (condition?.Invoke(type) ?? true)) + { Registrator.Register(type); + + RegisterAdditionalDependencies(type); + } } } + private void RegisterAdditionalDependencies(Type implementation) + { + var att = implementation.GetCustomAttribute(); + if (att == null) + return; + + var installer = att.InstallerMode == InstallerMode.All ? new AutoInstaller(implementation.Assembly) + : new DependencyAutoInstaller(implementation.Assembly, att); + ExecuteInstaller(installer); + if (att.Initializer == null) + return; + + if (!typeof(ISubInitializer).IsAssignableFrom(att.Initializer)) + throw new InvalidCastException($"SubInitializer {att.Initializer.Name} of component {implementation.Name} does not implement interface ISubInitializer"); + + // If someone registered this sub initializer before just skip + if (!Container.Kernel.HasComponent(att.Initializer)) + Container.Register(Component.For(typeof(ISubInitializer), att.Initializer).ImplementedBy(att.Initializer)); + } #endregion #region Register methods @@ -204,7 +242,7 @@ public IContainer Register() where TFactory : class public IContainer Register(string name) where TFactory : class { var factoryType = typeof(TFactory); - var att = typeof(TFactory).GetCustomAttribute(); + var att = typeof(TFactory).GetCustomAttribute(); Registrator.RegisterFactory(factoryType, name, att?.Selector); return this; } diff --git a/src/Moryx.Container/Installer/ComponentRegistrator.cs b/src/Moryx.Container/Installer/ComponentRegistrator.cs index fc05ca508..c93c0565c 100644 --- a/src/Moryx.Container/Installer/ComponentRegistrator.cs +++ b/src/Moryx.Container/Installer/ComponentRegistrator.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0 using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using Castle.Facilities.TypedFactory; @@ -12,18 +13,25 @@ namespace Moryx.Container { internal class ComponentRegistrator : IComponentRegistrator { + private readonly IDictionary _strategies; + /// /// Internal windsor container for registration /// protected internal IWindsorContainer Container { get; set; } + public ComponentRegistrator(IDictionary strategies) + { + _strategies = strategies; + } + /// /// Method to determine if this component shall be installed /// public virtual bool ShallInstall(Type foundType) { - var regAtt = foundType.GetCustomAttribute(); - var facAtt = foundType.GetCustomAttribute(); + var regAtt = foundType.GetCustomAttribute(); + var facAtt = foundType.GetCustomAttribute(); return (regAtt != null || facAtt != null) && NotRegisteredYet(foundType, regAtt); } @@ -34,7 +42,7 @@ public virtual bool ShallInstall(Type foundType) /// Type that must be checked for suitability to register /// /// True if the component was not registered before - protected bool NotRegisteredYet(Type foundType, RegistrationAttribute regAtt) + protected bool NotRegisteredYet(Type foundType, ComponentAttribute regAtt) { var name = string.IsNullOrEmpty(regAtt?.Name) ? foundType.FullName : regAtt.Name; return !Container.Kernel.HasComponent(name); @@ -57,7 +65,7 @@ public void Register(Type type) /// public static Type[] GetComponentServices(Type type) { - var att = type.GetCustomAttribute(); + var att = type.GetCustomAttribute(); if (att != null) return att.Services.Any() ? att.Services : new[] { type }; @@ -67,7 +75,7 @@ public static Type[] GetComponentServices(Type type) public void Register(Type type, Type[] services) { - var regAtt = type.GetCustomAttribute(); + var regAtt = type.GetCustomAttribute(); Register(type, services, regAtt?.Name, regAtt?.LifeStyle ?? LifeCycle.Singleton); } @@ -140,14 +148,19 @@ protected virtual ComponentRegistration BuildRegistration(Type type, Typ protected virtual ServiceOverride OverrideDependency(string dependencyName, Type dependencyType, ICustomAttributeProvider attributeProvider) { var atts = attributeProvider.GetCustomAttributes(typeof(NamedAttribute), false); - return atts.Any() ? Dependency.OnComponent(dependencyName, ((NamedAttribute)atts[0]).ComponentName) : null; + var dependency = atts.Any() ? Dependency.OnComponent(dependencyName, ((NamedAttribute)atts[0]).ComponentName) : null; + + if (dependency == null && _strategies.ContainsKey(dependencyType)) + dependency = Dependency.OnComponent(dependencyName, _strategies[dependencyType]); + + return dependency; } public void RegisterFactory(Type factoryInterface) { - var facAtt = factoryInterface.GetCustomAttribute(); - RegisterFactory(factoryInterface, facAtt?.Name, facAtt?.Selector); + var facAtt = factoryInterface.GetCustomAttribute(); + RegisterFactory(factoryInterface, null, facAtt?.Selector); } diff --git a/src/Moryx.Container/Installer/DoubleRegistrationCheck.cs b/src/Moryx.Container/Installer/DoubleRegistrationCheck.cs deleted file mode 100644 index 8028180c7..000000000 --- a/src/Moryx.Container/Installer/DoubleRegistrationCheck.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Castle.MicroKernel; - -namespace Moryx.Container.Installer -{ - /// - /// Class used to check the kernel for an exisiting component registration of this type - /// - public static class DoubleRegistrationCheck - { - /// - /// Look for an existing component in the kernel - /// - public static bool AllreadyRegistered(IKernel kernel, Type foundComponent, RegistrationAttribute regAtt) - { - var name = regAtt == null || string.IsNullOrEmpty(regAtt.Name) ? foundComponent.FullName : regAtt.Name; - return kernel.HasComponent(name); - } - } -} diff --git a/src/Moryx.Container/Installer/IConfiguredInstaller.cs b/src/Moryx.Container/Installer/IConfiguredInstaller.cs deleted file mode 100644 index 9ff7795bf..000000000 --- a/src/Moryx.Container/Installer/IConfiguredInstaller.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Container -{ - internal interface IConfiguredInstaller - { - /// - /// Set config on installer - /// - void SetRegistrator(ComponentRegistrator config); - } -} diff --git a/src/Moryx.Container/LocalContainer/LocalContainer.cs b/src/Moryx.Container/LocalContainer/LocalContainer.cs deleted file mode 100644 index 1b85033f1..000000000 --- a/src/Moryx.Container/LocalContainer/LocalContainer.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Castle.MicroKernel.Registration; - -namespace Moryx.Container -{ - /// - /// Module internal castle container - /// - public class LocalContainer : CastleContainer - { - private readonly IDictionary _strategies; - - /// - /// Default constructor without strategies - /// - public LocalContainer() : this(new Dictionary()) - { - } - - /// - /// Constructor for the local castle container. - /// - /// Configuration for the container. - public LocalContainer(IDictionary strategies) - : base(new LocalRegistrator(strategies)) - { - _strategies = strategies; - } - - /// - public override T Resolve() - { - var service = typeof(T); - return _strategies.ContainsKey(service) ? Resolve(_strategies[service]) : base.Resolve(); - } - - /// - public override object Resolve(Type service) - { - return _strategies.ContainsKey(service) ? Resolve(service, _strategies[service]) : base.Resolve(service); - } - - /// - public override void LoadComponents(Predicate condition) - { - // Save all current handlers - var handlers = Container.Kernel.GetHandlers(typeof(T)).Select(handler => handler.ComponentModel.Implementation); - - // Invoke registration - base.LoadComponents(condition); - - // Check registered types for additional registrations - RegisterAdditionalDependencies(Container.Kernel.GetHandlers(typeof(T)) - .Select(handler => handler.ComponentModel.Implementation) - .Except(handlers)); - } - - private void RegisterAdditionalDependencies(IEnumerable modulePlugins) - { - foreach (var implementation in modulePlugins) - { - var att = implementation.GetCustomAttribute(); - if (att == null) - continue; - - var installer = att.InstallerMode == InstallerMode.All ? new AutoInstaller(implementation.Assembly) - : new DependencyAutoInstaller(implementation.Assembly, att); - ExecuteInstaller(installer); - if (att.Initializer == null) - continue; - - if (!typeof(ISubInitializer).IsAssignableFrom(att.Initializer)) - throw new InvalidCastException($"SubInitializer {att.Initializer.Name} of component {implementation.Name} does not implement interface ISubInitializer"); - - // If someone registered this sub initializer before just skip - if (!Container.Kernel.HasComponent(att.Initializer)) - Container.Register(Component.For(typeof(ISubInitializer), att.Initializer).ImplementedBy(att.Initializer)); - } - } - } -} diff --git a/src/Moryx.Container/LocalContainer/LocalRegistrator.cs b/src/Moryx.Container/LocalContainer/LocalRegistrator.cs deleted file mode 100644 index 7acc38bc6..000000000 --- a/src/Moryx.Container/LocalContainer/LocalRegistrator.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Collections.Generic; -using System.Reflection; -using Castle.MicroKernel.Registration; - -namespace Moryx.Container -{ - internal class LocalRegistrator : ComponentRegistrator - { - private readonly IDictionary _strategies; - - public LocalRegistrator(IDictionary strategies) - { - _strategies = strategies; - } - - /// - /// Method to determine if this component shall be installed - /// - public override bool ShallInstall(Type foundType) - { - var regAtt = foundType.GetCustomAttribute(); - var facAtt = foundType.GetCustomAttribute(); - - return (regAtt != null || facAtt != null) && NotRegisteredYet(foundType, regAtt); - } - - /// - /// Determine a possible override for this member. Base implementatin checks for named attribute - /// - protected override ServiceOverride OverrideDependency(string dependencyName, Type dependencyType, ICustomAttributeProvider attributeProvider) - { - var dependency = base.OverrideDependency(dependencyName, dependencyType, attributeProvider); - - if (dependency == null && _strategies.ContainsKey(dependencyType)) - dependency = Dependency.OnComponent(dependencyName, _strategies[dependencyType]); - - return dependency; - } - } -} diff --git a/src/Moryx.Model/DbContextManager.cs b/src/Moryx.Model/DbContextManager.cs index 8a7f3ef96..2069f3992 100644 --- a/src/Moryx.Model/DbContextManager.cs +++ b/src/Moryx.Model/DbContextManager.cs @@ -18,7 +18,6 @@ namespace Moryx.Model /// /// Kernel component handling data models and their runtime configurators /// - [InitializableKernelComponent(typeof(IDbContextManager))] public class DbContextManager : IDbContextManager { private ModelWrapper[] _knownModels; diff --git a/src/Moryx.Products.Management/Implementation/Storage/AutoConfigurator.cs b/src/Moryx.Products.Management/Implementation/Storage/AutoConfigurator.cs index 4e9975ff2..db0245800 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/AutoConfigurator.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/AutoConfigurator.cs @@ -176,7 +176,7 @@ private TConfig StrategyConfig(Type targetType) var config = tuple.Item2; config.TargetType = targetType.FullName; - config.PluginName = tuple.Item1.GetCustomAttribute().Name; + config.PluginName = tuple.Item1.GetCustomAttribute().Name; ValueProviderExecutor.Execute(config, new ValueProviderExecutorSettings().AddDefaultValueProvider()); @@ -208,7 +208,7 @@ private TConfig StrategyConfig(Type targetType) var strategy = propertyTuple.Item1; var propertyConfig = propertyTuple.Item2; propertyConfig.PropertyName = property.Name; - propertyConfig.PluginName = strategy.GetCustomAttribute().Name; + propertyConfig.PluginName = strategy.GetCustomAttribute().Name; var columnType = strategy.GetCustomAttribute()?.ColumnType ?? typeof(string); var column = remainingColumns.FirstOrDefault(rc => rc.PropertyType == columnType); diff --git a/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs b/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs index b8e2e3990..29ef4fbd6 100644 --- a/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs +++ b/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs @@ -8,7 +8,6 @@ using System.Threading; using Moryx.Configuration; using Moryx.Modules; -using Moryx.Runtime.Container; using Moryx.Runtime.Modules; using Moryx.Serialization; using Microsoft.AspNetCore.Mvc; @@ -250,11 +249,9 @@ public ActionResult InvokeMethod([FromRoute] string moduleName, [FromBody /// /// Create serialization for this module /// - private ICustomSerialization CreateSerialization(IModule module) + private ICustomSerialization CreateSerialization(IServerModule module) { - var host = (IContainerHost)module; - // TODO: This is dangerous - return new PossibleValuesSerialization(host.Container, (IEmptyPropertyProvider)_configManager) + return new PossibleValuesSerialization(module.Container, (IEmptyPropertyProvider)_configManager) { FormatProvider = Thread.CurrentThread.CurrentUICulture }; @@ -263,11 +260,9 @@ private ICustomSerialization CreateSerialization(IModule module) /// /// Create serialization for this module /// - private ICustomSerialization CreateEditorSerializeSerialization(IModule module) + private ICustomSerialization CreateEditorSerializeSerialization(IServerModule module) { - var host = (IContainerHost)module; - // TODO: This is dangerous - return new AdvancedEntrySerializeSerialization(host.Container, (IEmptyPropertyProvider)_configManager) + return new AdvancedEntrySerializeSerialization(module.Container, (IEmptyPropertyProvider)_configManager) { FormatProvider = Thread.CurrentThread.CurrentUICulture }; diff --git a/src/Moryx.Runtime.Kernel/Configuration/ConfigManager.cs b/src/Moryx.Runtime.Kernel/Configuration/ConfigManager.cs index c851a6de4..4ea6f6095 100644 --- a/src/Moryx.Runtime.Kernel/Configuration/ConfigManager.cs +++ b/src/Moryx.Runtime.Kernel/Configuration/ConfigManager.cs @@ -14,7 +14,6 @@ namespace Moryx.Runtime.Kernel /// /// Manages the configs of the runtime and its modules. /// - [KernelComponent(typeof(IConfigManager))] public class ConfigManager : IConfigManager, IEmptyPropertyProvider { private readonly ConfigLiveUpdater _liveUpdater = new ConfigLiveUpdater(); diff --git a/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs b/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs index ed959591d..1a74a52e7 100644 --- a/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs +++ b/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs @@ -12,13 +12,12 @@ namespace Moryx.Runtime.Kernel /// /// Factory to create local containers of /// - [KernelComponent(typeof(IModuleContainerFactory))] public class ModuleContainerFactory : IModuleContainerFactory { /// public IContainer Create(IDictionary strategies, Assembly moduleAssembly) { - var container = new LocalContainer(strategies) + var container = new CastleContainer(strategies) .ExecuteInstaller(new AutoInstaller(moduleAssembly)); return container; } diff --git a/src/Moryx.Runtime.Kernel/Modules/ModuleManager.cs b/src/Moryx.Runtime.Kernel/Modules/ModuleManager.cs index dcaca872c..620916251 100644 --- a/src/Moryx.Runtime.Kernel/Modules/ModuleManager.cs +++ b/src/Moryx.Runtime.Kernel/Modules/ModuleManager.cs @@ -14,7 +14,6 @@ namespace Moryx.Runtime.Kernel /// /// Manages all the modules on the server side. /// - [InitializableKernelComponent(typeof(IModuleManager))] public class ModuleManager : IModuleManager { #region Fields and Properties diff --git a/src/Moryx.Runtime/Container/IContainerHost.cs b/src/Moryx.Runtime/Container/IContainerHost.cs deleted file mode 100644 index 61e774fc8..000000000 --- a/src/Moryx.Runtime/Container/IContainerHost.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Collections.Generic; -using Moryx.Container; - -namespace Moryx.Runtime.Container -{ - /// - /// Base contract for all components hosting their own container - /// - public interface IContainerHost - { - /// - /// Strategy configuration of this host - /// - IDictionary Strategies { get; } - - /// - /// Container hosted by this component - /// - IContainer Container { get; } - } -} diff --git a/src/Moryx.Runtime/Modules/IServerModule.cs b/src/Moryx.Runtime/Modules/IServerModule.cs index 056e951d8..c11bd784d 100644 --- a/src/Moryx.Runtime/Modules/IServerModule.cs +++ b/src/Moryx.Runtime/Modules/IServerModule.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0 using System; +using System.Collections.Generic; +using Moryx.Container; using Moryx.Modules; namespace Moryx.Runtime.Modules @@ -17,6 +19,11 @@ namespace Moryx.Runtime.Modules /// public interface IServerModule : IModule { + /// + /// Internal service provider of the module + /// + IContainer Container { get; } + /// /// Console to interact with the module /// diff --git a/src/Moryx.Runtime/Modules/ServerModuleBase.cs b/src/Moryx.Runtime/Modules/ServerModuleBase.cs index 4af32cad3..a96092980 100644 --- a/src/Moryx.Runtime/Modules/ServerModuleBase.cs +++ b/src/Moryx.Runtime/Modules/ServerModuleBase.cs @@ -10,7 +10,6 @@ using Moryx.Container; using Moryx.Logging; using Moryx.Modules; -using Moryx.Runtime.Container; using Moryx.StateMachines; using Moryx.Threading; @@ -21,7 +20,7 @@ namespace Moryx.Runtime.Modules /// /// Configuration type for the server module. [DebuggerDisplay("{" + nameof(Name) + "} - {" + nameof(State) + "}")] - public abstract class ServerModuleBase : IServerModule, IContainerHost, IServerModuleStateContext + public abstract class ServerModuleBase : IServerModule, IServerModuleStateContext where TConf : class, IConfig, new() { /// diff --git a/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs b/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs index c48f04e9d..a987f34c9 100644 --- a/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs +++ b/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Logging; using Moryx.Configuration; using Moryx.Container; -using Moryx.Runtime.Container; namespace Moryx.Runtime.Modules { @@ -104,7 +103,7 @@ private object FillProperty(IContainer container, PropertyInfo property) private string StrategyName(Type dependencyType) { - var config = ((IContainerHost)this).Strategies; + var config = Strategies; return config.ContainsKey(dependencyType) ? config[dependencyType] : null; } } diff --git a/src/Moryx/Container/Attributes/ComponentAttribute.cs b/src/Moryx/Container/Attributes/ComponentAttribute.cs index 47af8b205..64cae13f1 100644 --- a/src/Moryx/Container/Attributes/ComponentAttribute.cs +++ b/src/Moryx/Container/Attributes/ComponentAttribute.cs @@ -8,21 +8,48 @@ namespace Moryx.Container /// /// Registration attribute to decorate components of a module. /// - public class ComponentAttribute : RegistrationAttribute + public class ComponentAttribute : Attribute { + /// + /// Life cycle of this component + /// + public LifeCycle LifeStyle { get; } + + /// + /// Implemented service + /// + public Type[] Services { get; } + + /// + /// Optional name of component + /// + public string Name { get; set; } + /// /// Constructor with life cycle /// /// Life style of component /// Implemented service - public ComponentAttribute(LifeCycle lifeStyle, params Type[] services) - : base(lifeStyle, services) - { + public ComponentAttribute(LifeCycle lifeStyle, params Type[] services) + { + LifeStyle = lifeStyle; + Services = services; } + } + + /// + /// Life cycle for this component + /// + public enum LifeCycle + { + /// + /// Create only one instance during container life time + /// + Singleton, /// - /// Flag that this plugin shall not be intercepted + /// Create a new instance for every request /// - public bool DontIntercept { get; set; } + Transient } } diff --git a/src/Moryx/Container/Attributes/DependencyRegistrationAttribute.cs b/src/Moryx/Container/Attributes/DependencyRegistrationAttribute.cs index bcbbbc04c..6fdc9ea9f 100644 --- a/src/Moryx/Container/Attributes/DependencyRegistrationAttribute.cs +++ b/src/Moryx/Container/Attributes/DependencyRegistrationAttribute.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +using Microsoft.Extensions.DependencyInjection; using System; namespace Moryx.Container @@ -72,6 +73,6 @@ public interface ISubInitializer /// /// Execute further initialization /// - void Initialize(IContainer container); + void Initialize(IContainer services); } } diff --git a/src/Moryx/Container/Attributes/FactoryRegistrationAttribute.cs b/src/Moryx/Container/Attributes/FactoryRegistrationAttribute.cs deleted file mode 100644 index d6fb1cc9e..000000000 --- a/src/Moryx/Container/Attributes/FactoryRegistrationAttribute.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; - -namespace Moryx.Container -{ - /// - /// Installation attribute for factories - /// - [AttributeUsage(AttributeTargets.Interface)] - public class FactoryRegistrationAttribute : Attribute - { - /// - /// Optional component selector - /// - public Type Selector - { - get; - private set; - } - - /// - /// Optional name of factory - /// - public string Name - { - get; - private set; - } - - /// - /// Default constructor - /// - public FactoryRegistrationAttribute() - { - } - - /// - /// Constructor with component selector - /// - /// Selector - public FactoryRegistrationAttribute(Type selectorType) - { - Selector = selectorType; - } - - /// - /// Constructor with name - /// - /// Name of factory - public FactoryRegistrationAttribute(string name) - { - Name = name; - } - - /// - /// Constructor with name and selector - /// - /// Name - /// Selector - public FactoryRegistrationAttribute(string name, Type selectorType) - { - Selector = selectorType; - Name = name; - } - } -} diff --git a/src/Moryx/Container/Attributes/GlobalComponentAttribute.cs b/src/Moryx/Container/Attributes/GlobalComponentAttribute.cs deleted file mode 100644 index 74c1560f2..000000000 --- a/src/Moryx/Container/Attributes/GlobalComponentAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; - -namespace Moryx.Container -{ - /// - /// Base attribute for all registrations of the global container - /// - [AttributeUsage(AttributeTargets.Class)] - public class GlobalComponentAttribute : RegistrationAttribute - { - /// - /// Constructor with life cycle - /// - /// Life style of componentImplemented service - public GlobalComponentAttribute(LifeCycle lifeStyle, params Type[] services) : base(lifeStyle, services) - { - } - } -} diff --git a/src/Moryx/Container/Attributes/KernelComponentAttribute.cs b/src/Moryx/Container/Attributes/KernelComponentAttribute.cs deleted file mode 100644 index 4bb66b56d..000000000 --- a/src/Moryx/Container/Attributes/KernelComponentAttribute.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Linq; -using Moryx.Modules; - -namespace Moryx.Container -{ - /// - /// Register a kernel component - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class KernelComponentAttribute : GlobalComponentAttribute - { - /// - /// Register a kernel component - /// - public KernelComponentAttribute(params Type[] services) - : base(LifeCycle.Singleton, services) - { - } - } - - /// - /// Register a kernel component - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class InitializableKernelComponentAttribute : KernelComponentAttribute - { - /// - /// Register a kernel component - /// - public InitializableKernelComponentAttribute(params Type[] services) - : base(new[] { typeof(IInitializable) }.Union(services).ToArray()) - { - } - } - - /// - /// Register a kernel plugin - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class KernelPluginAttribute : GlobalComponentAttribute - { - /// - /// Register a kernel component - /// - public KernelPluginAttribute(params Type[] services) - : base(LifeCycle.Singleton, services) - { - } - } - -} diff --git a/src/Moryx/Container/Attributes/PluginFactoryAttribute.cs b/src/Moryx/Container/Attributes/PluginFactoryAttribute.cs index c8f0c6988..a2e53e61c 100644 --- a/src/Moryx/Container/Attributes/PluginFactoryAttribute.cs +++ b/src/Moryx/Container/Attributes/PluginFactoryAttribute.cs @@ -9,23 +9,31 @@ namespace Moryx.Container /// Interface for plguin factories within the local container /// [AttributeUsage(AttributeTargets.Interface)] - public class PluginFactoryAttribute : FactoryRegistrationAttribute + public class PluginFactoryAttribute : Attribute { /// - /// + /// Optional component selector /// - public PluginFactoryAttribute() + public Type Selector { - + get; + private set; } /// - /// + /// Default constructor /// - /// - public PluginFactoryAttribute(Type selectorType) : base(selectorType) + public PluginFactoryAttribute() { + } + /// + /// Constructor with component selector + /// + /// Selector + public PluginFactoryAttribute(Type selectorType) + { + Selector = selectorType; } } } diff --git a/src/Moryx/Container/Attributes/RegistrationAttribute.cs b/src/Moryx/Container/Attributes/RegistrationAttribute.cs deleted file mode 100644 index fd23d854d..000000000 --- a/src/Moryx/Container/Attributes/RegistrationAttribute.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; - -namespace Moryx.Container -{ - /// - /// Installation attribute for castle windsor - /// - [AttributeUsage(AttributeTargets.Class)] - public class RegistrationAttribute : Attribute - { - /// - /// Life cycle of this component - /// - public LifeCycle LifeStyle { get; } - - /// - /// Implemented service - /// - public Type[] Services { get; } - - /// - /// Optional name of component - /// - public string Name { get; set; } - - /// - /// Constructor with life cycle - /// - /// Life style of component - /// Implemented service - public RegistrationAttribute(LifeCycle lifeStyle, params Type[] services) - { - LifeStyle = lifeStyle; - Services = services; - } - } - - /// - /// Lifecylce for this component - /// - public enum LifeCycle - { - /// - /// Create only one instance during container life time - /// - Singleton, - - /// - /// Create a new instance for every request - /// - Transient - } -} diff --git a/src/Moryx/Container/IComponentRegistrator.cs b/src/Moryx/Container/IComponentRegistrator.cs index d76bb64c7..ac2bdf7d1 100644 --- a/src/Moryx/Container/IComponentRegistrator.cs +++ b/src/Moryx/Container/IComponentRegistrator.cs @@ -6,7 +6,7 @@ namespace Moryx.Container { /// - /// Responensible for component registration based on information given in + /// Responensible for component registration based on information given in /// public interface IComponentRegistrator { diff --git a/src/Moryx/Serialization/PossibleValues/PluginNameSelectorAttribute.cs b/src/Moryx/Serialization/PossibleValues/PluginNameSelectorAttribute.cs index 025280109..fa2a62d6b 100644 --- a/src/Moryx/Serialization/PossibleValues/PluginNameSelectorAttribute.cs +++ b/src/Moryx/Serialization/PossibleValues/PluginNameSelectorAttribute.cs @@ -36,7 +36,7 @@ public override IEnumerable GetValues(IContainer container) private static string GetComponentName(Type component) { - var att = component.GetCustomAttribute(); + var att = component.GetCustomAttribute(); return string.IsNullOrEmpty(att?.Name) ? component.FullName : att.Name; } diff --git a/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs b/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs index d7fd56353..9787bfa3c 100644 --- a/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs +++ b/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs @@ -2,18 +2,20 @@ // Licensed under the Apache License, Version 2.0 using NUnit.Framework; +using System; +using System.Collections.Generic; namespace Moryx.Container.Tests { [TestFixture] public class LocalContainerTest { - private LocalContainer _container; + private CastleContainer _container; [SetUp] public void Init() { - _container = new LocalContainer(); + _container = new CastleContainer(new Dictionary()); _container.ExecuteInstaller(new AutoInstaller(GetType().Assembly)); } diff --git a/src/Tests/Moryx.Container.Tests/Local/StrategySelectionTest.cs b/src/Tests/Moryx.Container.Tests/Local/StrategySelectionTest.cs index aa80ab7d6..de8250206 100644 --- a/src/Tests/Moryx.Container.Tests/Local/StrategySelectionTest.cs +++ b/src/Tests/Moryx.Container.Tests/Local/StrategySelectionTest.cs @@ -122,7 +122,7 @@ public void OverrideWithFactory(string rootName, string pluginName) private static IContainer CreateContainer(IDictionary strategies) { - var container = new LocalContainer(strategies); + var container = new CastleContainer(strategies); container.LoadComponents(); container.LoadComponents(); diff --git a/src/Tests/Moryx.Container.Tests/Named/Component.cs b/src/Tests/Moryx.Container.Tests/Named/Component.cs index c79d6c014..19e62fedf 100644 --- a/src/Tests/Moryx.Container.Tests/Named/Component.cs +++ b/src/Tests/Moryx.Container.Tests/Named/Component.cs @@ -3,7 +3,7 @@ namespace Moryx.Container.Tests { - [Registration(LifeCycle.Singleton)] + [Component(LifeCycle.Singleton)] internal class Component { public IDependency Unnamed { get; set; } diff --git a/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs b/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs index 63438a50a..f6b433b6b 100644 --- a/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs +++ b/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs @@ -3,12 +3,12 @@ namespace Moryx.Container.Tests { - [Registration(LifeCycle.Transient, Name = "Dummy")] + [Component(LifeCycle.Transient, Name = "Dummy")] internal class NamedDummy { } - [Registration(LifeCycle.Transient)] + [Component(LifeCycle.Transient)] internal class UnnamedDummy { diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ModuleBase.cs b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ModuleBase.cs index e06b85b3a..fe046cf5f 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ModuleBase.cs +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ModuleBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0 using System; +using Moryx.Container; using Moryx.Modules; using Moryx.Runtime.Modules; @@ -20,6 +21,8 @@ internal class ModuleBase : IServerModule /// public IServerModuleConsole Console { get; private set; } + public IContainer Container => throw new NotImplementedException(); + /// /// Initialize this component and prepare it for incoming taks. This must only involve preparation and must not start /// any active functionality and/or periodic execution of logic. diff --git a/src/Tests/Moryx.Runtime.Tests/ModuleBaseTest.cs b/src/Tests/Moryx.Runtime.Tests/ModuleBaseTest.cs index fc5c7fb6f..484e6261b 100644 --- a/src/Tests/Moryx.Runtime.Tests/ModuleBaseTest.cs +++ b/src/Tests/Moryx.Runtime.Tests/ModuleBaseTest.cs @@ -1,7 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using Moryx.Runtime.Container; using Moryx.Runtime.Modules; using Moryx.Runtime.Tests.Mocks; using Moryx.Runtime.Tests.Modules; @@ -36,7 +35,7 @@ public void StrategiesInConfigFound() var casted = (IServerModule) _moduleUnderTest; casted.Initialize(); - var containerConfig = ((IContainerHost) _moduleUnderTest).Strategies; + var containerConfig = _moduleUnderTest.Strategies; Assert.GreaterOrEqual(containerConfig.Count, 1, "No strategy found!"); Assert.IsTrue(containerConfig.ContainsKey(typeof(IStrategy)), "Wrong type!"); From e7c1e28f612aa4bef5496d6db78a3931a6c77815 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Mon, 24 Jul 2023 12:03:08 +0200 Subject: [PATCH 08/57] Replace registrator and installers with extensions --- src/Moryx.Container/CastleContainer.cs | 236 ++++++++---------- .../Installer/AutoInstaller.cs | 48 ---- .../Installer/ComponentRegistrator.cs | 196 --------------- .../Installer/DependencyAutoInstaller.cs | 52 ---- .../DbContextContainerExtension.cs | 13 +- .../Container/ModuleContainerFactory.cs | 4 +- .../BasicInterceptorInstaller.cs | 8 +- .../ContainerLoadComponentsExtension.cs | 131 ++++++++++ .../ContainerRegistrationExtensions.cs | 171 +++++++++++++ src/Moryx/Container/IComponentRegistrator.cs | 59 ----- src/Moryx/Container/IContainer.cs | 72 +----- src/Moryx/Container/IContainerInstaller.cs | 16 -- .../Local/LocalContainerTest.cs | 2 +- .../Registrator/FakeAutoInstaller.cs | 28 --- .../Registrator/RegistratorTest.cs | 10 +- 15 files changed, 419 insertions(+), 627 deletions(-) delete mode 100644 src/Moryx.Container/Installer/AutoInstaller.cs delete mode 100644 src/Moryx.Container/Installer/ComponentRegistrator.cs delete mode 100644 src/Moryx.Container/Installer/DependencyAutoInstaller.cs create mode 100644 src/Moryx/Container/ContainerLoadComponentsExtension.cs create mode 100644 src/Moryx/Container/ContainerRegistrationExtensions.cs delete mode 100644 src/Moryx/Container/IComponentRegistrator.cs delete mode 100644 src/Moryx/Container/IContainerInstaller.cs delete mode 100644 src/Tests/Moryx.Container.Tests/Registrator/FakeAutoInstaller.cs diff --git a/src/Moryx.Container/CastleContainer.cs b/src/Moryx.Container/CastleContainer.cs index 1052928d8..6a4b895d5 100644 --- a/src/Moryx.Container/CastleContainer.cs +++ b/src/Moryx.Container/CastleContainer.cs @@ -18,18 +18,11 @@ namespace Moryx.Container /// public class CastleContainer : IContainer { - /// - /// Internal windsor container doing the real DI - /// - protected IWindsorContainer Container { get; private set; } - - /// - /// Registrator used to evaluate attributes - /// - protected IComponentRegistrator Registrator { get; } #region Constructors + private readonly IWindsorContainer _container; + private readonly IDictionary _strategies; /// @@ -46,23 +39,15 @@ public CastleContainer() public CastleContainer(IDictionary strategies) { _strategies = strategies; - } - /// - /// Constructor to modify the applied registrator - /// - /// Registrator replacement - internal CastleContainer(ComponentRegistrator registrator) - { - // Boot up the container and give it to the registrator - Container = registrator.Container = new WindsorContainer(); - Registrator = registrator; + // Boot up the container + _container = new WindsorContainer(); - Container.AddFacility(); - Container.AddFacility(); + _container.AddFacility(); + _container.AddFacility(); // Self registration for framework functionality - SetInstance(this); + RegisterInstance(new[] { typeof(IContainer) }, this, null); } #endregion @@ -70,19 +55,7 @@ internal CastleContainer(ComponentRegistrator registrator) /// public virtual void Destroy() { - Container.Dispose(); - Container = null; - } - - /// - /// Execute the installer for this assembly - /// - /// - public IContainer ExecuteInstaller(IContainerInstaller installer) - { - installer.Install(Registrator); - - return this; + _container.Dispose(); } /// @@ -93,9 +66,9 @@ public IContainer ExecuteInstaller(IContainerInstaller installer) public virtual T Resolve() { var service = typeof(T); - return _strategies.ContainsKey(service) - ? Resolve(_strategies[service]) - : Container.Kernel.HasComponent(typeof(T)) ? Container.Resolve() : default(T); + return _strategies.ContainsKey(service) + ? Resolve(_strategies[service]) + : _container.Kernel.HasComponent(typeof(T)) ? _container.Resolve() : default(T); } /// @@ -105,7 +78,7 @@ public virtual object Resolve(Type service) { return _strategies.ContainsKey(service) ? Resolve(service, _strategies[service]) - : Container.Kernel.HasComponent(service) ? Container.Resolve(service) : null; + : _container.Kernel.HasComponent(service) ? _container.Resolve(service) : null; } /// @@ -115,7 +88,7 @@ public virtual object Resolve(Type service) /// Instance of type public T Resolve(string name) { - return Container.Kernel.HasComponent(name) ? Container.Resolve(name) : default(T); + return _container.Kernel.HasComponent(name) ? _container.Resolve(name) : default(T); } /// @@ -123,7 +96,7 @@ public T Resolve(string name) /// public object Resolve(Type service, string name) { - return Container.Kernel.HasComponent(name) ? Container.Resolve(name, service) : null; + return _container.Kernel.HasComponent(name) ? _container.Resolve(name, service) : null; } /// @@ -133,7 +106,7 @@ public object Resolve(Type service, string name) /// public T[] ResolveAll() { - return Container.ResolveAll(); + return _container.ResolveAll(); } /// @@ -141,7 +114,7 @@ public T[] ResolveAll() /// public Array ResolveAll(Type service) { - return Container.ResolveAll(service); + return _container.ResolveAll(service); } /// @@ -150,136 +123,123 @@ public Array ResolveAll(Type service) /// public IEnumerable GetRegisteredImplementations(Type componentInterface) { - return Container.Kernel.GetHandlers(componentInterface).Select(handler => handler.ComponentModel.Implementation); + return _container.Kernel.GetHandlers(componentInterface).Select(handler => handler.ComponentModel.Implementation); } - #region LoadComponents - private static Type[] _knownTypes; + #region Register methods /// - /// Load all implementations of type from currently known types - /// KnownTypes: Types in default framework folders and deeper. + /// Register a component in the container /// - public void LoadComponents() where T : class + public void Register(Type type, Type[] services, string name, LifeCycle lifeCycle) { - LoadComponents(null); - } + // Make sure component is not registered yet + var componentName = name ?? type.FullName; + if (_container.Kernel.HasComponent(componentName)) + return; - /// - /// Loads all implementations of type from the currently known types - /// KnownTypes: Types in default framework folders and deeper. - /// - public virtual void LoadComponents(Predicate condition) where T : class - { - if (_knownTypes == null) + var registration = Component.For(services).ImplementedBy(type); + + // Register name + if (!string.IsNullOrEmpty(name)) { - _knownTypes = ReflectionTool.GetAssemblies() - .Where(a => a.GetCustomAttribute() == null) - .SelectMany(a => a.GetTypes()) - .Where(t => t.GetCustomAttribute(true) != null).ToArray(); + registration.Named(name); } - foreach (var type in _knownTypes.Where(type => typeof(T).IsAssignableFrom(type))) + // Register life style + switch (lifeCycle) { - if (Registrator.ShallInstall(type) && (condition?.Invoke(type) ?? true)) - { - Registrator.Register(type); - - RegisterAdditionalDependencies(type); - } + case LifeCycle.Transient: + registration.LifestyleTransient(); + break; + case LifeCycle.Singleton: + registration.LifestyleSingleton(); + break; } - } - - private void RegisterAdditionalDependencies(Type implementation) - { - var att = implementation.GetCustomAttribute(); - if (att == null) - return; - var installer = att.InstallerMode == InstallerMode.All ? new AutoInstaller(implementation.Assembly) - : new DependencyAutoInstaller(implementation.Assembly, att); - ExecuteInstaller(installer); - if (att.Initializer == null) - return; + // Optionally override property injection + foreach (var property in registration.Implementation.GetProperties()) + { + // Check if this property has an override + var dependency = OverrideDependency(property.Name, property.PropertyType, property); - if (!typeof(ISubInitializer).IsAssignableFrom(att.Initializer)) - throw new InvalidCastException($"SubInitializer {att.Initializer.Name} of component {implementation.Name} does not implement interface ISubInitializer"); + // Override property injection for this property if found + if (dependency != null) + registration.DependsOn(dependency); + } - // If someone registered this sub initializer before just skip - if (!Container.Kernel.HasComponent(att.Initializer)) - Container.Register(Component.For(typeof(ISubInitializer), att.Initializer).ImplementedBy(att.Initializer)); - } - #endregion + // Override Constructor injection as well + foreach (var constructorParameter in registration.Implementation.GetConstructors().SelectMany(constructor => constructor.GetParameters())) + { + // Check if this paramter has an override + var dependency = OverrideDependency(constructorParameter.Name, constructorParameter.ParameterType, constructorParameter); - #region Register methods + // Override constructor injection for this property if found + if (dependency != null) + registration.DependsOn(dependency); + } - /// - public IContainer Register() - where TService : class - where TComp : TService - { - Registrator.Register(typeof(TComp), new[] { typeof(TService) }); - return this; + _container.Register(registration); } - /// - public IContainer Register(string name, LifeCycle lifeCycle) - where TService : class - where TComp : TService + /// + /// Determine a possible override for this member. Base implementatin checks for named attribute + /// + private ServiceOverride OverrideDependency(string dependencyName, Type dependencyType, ICustomAttributeProvider attributeProvider) { - Registrator.Register(typeof(TComp), new[] { typeof(TService) }, name, lifeCycle); - return this; - } + var atts = attributeProvider.GetCustomAttributes(typeof(NamedAttribute), false); + var dependency = atts.Any() ? Dependency.OnComponent(dependencyName, ((NamedAttribute)atts[0]).ComponentName) : null; - /// - public IContainer Register() where TFactory : class - { - Registrator.RegisterFactory(typeof(TFactory)); - return this; - } + if (dependency == null && _strategies.ContainsKey(dependencyType)) + dependency = Dependency.OnComponent(dependencyName, _strategies[dependencyType]); - /// - public IContainer Register(string name) where TFactory : class - { - var factoryType = typeof(TFactory); - var att = typeof(TFactory).GetCustomAttribute(); - Registrator.RegisterFactory(factoryType, name, att?.Selector); - return this; + return dependency; } - #endregion - - #region SetInstances - /// - /// Set instance of service + /// Register factory interface /// - /// Type of service - /// Instance implementing the service - public IContainer SetInstance(T instance) where T : class + public void RegisterFactory(Type factoryInterface, string name, Type selector) { - if (instance != null) + var registration = Component.For(factoryInterface); + + if (!string.IsNullOrEmpty(name)) + { + registration.Named(name); + } + + if (selector == null) { - Container.Register(Component.For().Instance(instance)); + registration.AsFactory(); } - return this; + else + { + // Make sure selector is registered in the container + // TODO: Super dirty hack to use interfaces in component selectors + var selectorName = selector.IsClass ? selector.FullName : $"{selector.Namespace}.{selector.Name.Substring(1)}"; + registration.AsFactory(config => config.SelectedWith(selectorName)); + } + + _container.Register(registration); } /// - /// Set globally imported instance with name + /// Register instance in the container /// - /// Type of service - /// Instance to register - /// Name of instance - public IContainer SetInstance(T instance, string name) where T : class + public void RegisterInstance(Type[] services, object instance, string name) { - if (instance != null) - { - Container.Register(Component.For().Instance(instance).Named(name)); - } - return this; + var registration = Component.For(services).Instance(instance); + + if (!string.IsNullOrEmpty(name)) + registration.Named(name); + + _container.Register(registration); } + #endregion + + #region SetInstances + public void Extend() where TExtension : new() { var facilityType = typeof(IFacility); @@ -287,7 +247,7 @@ public IContainer SetInstance(T instance, string name) where T : class throw new InvalidOperationException("The underlying container only supports " + facilityType.FullName + "!"); var facility = (IFacility)new TExtension(); - Container.AddFacility(facility); + _container.AddFacility(facility); } #endregion diff --git a/src/Moryx.Container/Installer/AutoInstaller.cs b/src/Moryx.Container/Installer/AutoInstaller.cs deleted file mode 100644 index ef772eed2..000000000 --- a/src/Moryx.Container/Installer/AutoInstaller.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Reflection; - -namespace Moryx.Container -{ - /// - /// Installer for automatic registration - /// - public class AutoInstaller : IContainerInstaller - { - private readonly Assembly _targetAssembly; - - /// - /// Create a new instance of the for this assembly - /// - public AutoInstaller(Assembly targetAssembly) - { - _targetAssembly = targetAssembly ?? GetType().Assembly; - } - - - /// - /// Install components to the container - /// - /// Registrator to register new types - public virtual void Install(IComponentRegistrator registrator) - { - // Install all components - foreach (var type in _targetAssembly.GetTypes()) - { - // Register all we want - if (ShallInstall(registrator, type)) - registrator.Register(type); - } - } - - /// - /// Method to determine if this component shall be installed - /// - protected internal virtual bool ShallInstall(IComponentRegistrator registrator, Type foundType) - { - return registrator.ShallInstall(foundType); - } - } -} diff --git a/src/Moryx.Container/Installer/ComponentRegistrator.cs b/src/Moryx.Container/Installer/ComponentRegistrator.cs deleted file mode 100644 index c93c0565c..000000000 --- a/src/Moryx.Container/Installer/ComponentRegistrator.cs +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Castle.Facilities.TypedFactory; -using Castle.MicroKernel.Registration; -using Castle.Windsor; - -namespace Moryx.Container -{ - internal class ComponentRegistrator : IComponentRegistrator - { - private readonly IDictionary _strategies; - - /// - /// Internal windsor container for registration - /// - protected internal IWindsorContainer Container { get; set; } - - public ComponentRegistrator(IDictionary strategies) - { - _strategies = strategies; - } - - /// - /// Method to determine if this component shall be installed - /// - public virtual bool ShallInstall(Type foundType) - { - var regAtt = foundType.GetCustomAttribute(); - var facAtt = foundType.GetCustomAttribute(); - - return (regAtt != null || facAtt != null) && NotRegisteredYet(foundType, regAtt); - } - - /// - /// Check if the type was not registered yet - /// - /// Type that must be checked for suitability to register - /// - /// True if the component was not registered before - protected bool NotRegisteredYet(Type foundType, ComponentAttribute regAtt) - { - var name = string.IsNullOrEmpty(regAtt?.Name) ? foundType.FullName : regAtt.Name; - return !Container.Kernel.HasComponent(name); - } - - public void Register(Type type) - { - if (type.IsInterface) - { - RegisterFactory(type); - } - else - { - Register(type, GetComponentServices(type)); - } - } - - /// - /// Get all services of this component - /// - public static Type[] GetComponentServices(Type type) - { - var att = type.GetCustomAttribute(); - if (att != null) - return att.Services.Any() ? att.Services : new[] { type }; - - var interfaces = type.GetInterfaces(); - return interfaces.Any() ? interfaces : new[] { type }; - } - - public void Register(Type type, Type[] services) - { - var regAtt = type.GetCustomAttribute(); - Register(type, services, regAtt?.Name, regAtt?.LifeStyle ?? LifeCycle.Singleton); - } - - - public void Register(Type type, Type[] services, string name) - { - Register(type, services, name, LifeCycle.Singleton); - } - - - public void Register(Type type, Type[] services, string name, LifeCycle lifeCycle) - { - var registration = BuildRegistration(type, services, name, lifeCycle); - - Container.Register(registration); - } - - /// - /// Build registration from arguments - /// - protected virtual ComponentRegistration BuildRegistration(Type type, Type[] services, string name, LifeCycle lifeCycle) - { - var registration = Component.For(services).ImplementedBy(type); - - // Register name - if (!string.IsNullOrEmpty(name)) - { - registration.Named(name); - } - - // Register life style - switch (lifeCycle) - { - case LifeCycle.Transient: - registration.LifestyleTransient(); - break; - case LifeCycle.Singleton: - registration.LifestyleSingleton(); - break; - } - - // Optionally override property injection - foreach (var property in registration.Implementation.GetProperties()) - { - // Check if this property has an override - var dependency = OverrideDependency(property.Name, property.PropertyType, property); - - // Override property injection for this property if found - if (dependency != null) - registration.DependsOn(dependency); - } - - // Override Constructor injection as well - foreach (var constructorParameter in registration.Implementation.GetConstructors().SelectMany(constructor => constructor.GetParameters())) - { - // Check if this paramter has an override - var dependency = OverrideDependency(constructorParameter.Name, constructorParameter.ParameterType, constructorParameter); - - // Override constructor injection for this property if found - if (dependency != null) - registration.DependsOn(dependency); - } - - return registration; - } - - /// - /// Determine a possible override for this member. Base implementatin checks for named attribute - /// - protected virtual ServiceOverride OverrideDependency(string dependencyName, Type dependencyType, ICustomAttributeProvider attributeProvider) - { - var atts = attributeProvider.GetCustomAttributes(typeof(NamedAttribute), false); - var dependency = atts.Any() ? Dependency.OnComponent(dependencyName, ((NamedAttribute)atts[0]).ComponentName) : null; - - if (dependency == null && _strategies.ContainsKey(dependencyType)) - dependency = Dependency.OnComponent(dependencyName, _strategies[dependencyType]); - - return dependency; - } - - - public void RegisterFactory(Type factoryInterface) - { - var facAtt = factoryInterface.GetCustomAttribute(); - RegisterFactory(factoryInterface, null, facAtt?.Selector); - } - - - public void RegisterFactory(Type factoryInterface, string name) - { - RegisterFactory(factoryInterface, name, null); - } - - public virtual void RegisterFactory(Type factoryInterface, string name, Type selector) - { - var registration = Component.For(factoryInterface); - - if (!string.IsNullOrEmpty(name)) - { - registration.Named(name); - } - - if (selector == null) - { - registration.AsFactory(); - } - else - { - // Make sure selector is registered in the container - // TODO: Super dirty hack to use interfaces in component selectors - var selectorName = selector.IsClass ? selector.FullName : $"{selector.Namespace}.{selector.Name.Substring(1)}"; - registration.AsFactory(config => config.SelectedWith(selectorName)); - } - - Container.Register(registration); - } - } -} diff --git a/src/Moryx.Container/Installer/DependencyAutoInstaller.cs b/src/Moryx.Container/Installer/DependencyAutoInstaller.cs deleted file mode 100644 index 46315d1fc..000000000 --- a/src/Moryx.Container/Installer/DependencyAutoInstaller.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Linq; -using System.Reflection; - -namespace Moryx.Container -{ - /// - /// Creates automatically a new instance of the given assembly. - /// - public class DependencyAutoInstaller : AutoInstaller - { - private readonly DependencyRegistrationAttribute _depReg; - - /// - /// Create new instance for the given assembly - /// - /// Assembly to execute installer for - /// Dependency registration attribute - public DependencyAutoInstaller(Assembly targetAssembly, DependencyRegistrationAttribute depReg) : base(targetAssembly) - { - _depReg = depReg; - } - - /// - /// Method to determine if this component shall be installed - /// - protected internal override bool ShallInstall(IComponentRegistrator registrator, Type foundType) - { - if (base.ShallInstall(registrator, foundType)) - { - return _depReg.InstallerMode == InstallerMode.All || TypeRequired(foundType); - } - return false; - } - - private bool TypeRequired(Type foundType) - { - // Check if interface was specified as required - if(foundType.IsInterface && _depReg.RequiredTypes.Contains(foundType)) - return true; - - // Check if class exports required type - if(foundType.IsClass && _depReg.RequiredTypes.Intersect(ComponentRegistrator.GetComponentServices(foundType)).Any()) - return true; - - return false; - } - } -} diff --git a/src/Moryx.Model/DbContextContainerExtension.cs b/src/Moryx.Model/DbContextContainerExtension.cs index 38886a986..2b14f9453 100644 --- a/src/Moryx.Model/DbContextContainerExtension.cs +++ b/src/Moryx.Model/DbContextContainerExtension.cs @@ -17,18 +17,11 @@ public static class DbContextContainerExtension public static IContainer ActivateDbContexts(this IContainer container, IDbContextManager contextManager) { container.SetInstance(contextManager); - container.ExecuteInstaller(new ContextFactoryInstaller()); - return container; - } + container.Register(typeof(ContextFactory<>), new[] { typeof(IContextFactory<>) }, "GenericContextFactory", LifeCycle.Singleton); + container.Register(typeof(UnitOfWorkFactory<>), new[] { typeof(IUnitOfWorkFactory<>) }, "UnitOfWorkFactory", LifeCycle.Singleton); - private class ContextFactoryInstaller : IContainerInstaller - { - public void Install(IComponentRegistrator registrator) - { - registrator.Register(typeof(ContextFactory<>), new []{ typeof(IContextFactory<>) }, "GenericContextFactory", LifeCycle.Singleton); - registrator.Register(typeof(UnitOfWorkFactory<>), new[] { typeof(IUnitOfWorkFactory<>) }, "UnitOfWorkFactory", LifeCycle.Singleton); - } + return container; } } } \ No newline at end of file diff --git a/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs b/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs index 1a74a52e7..adef0095e 100644 --- a/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs +++ b/src/Moryx.Runtime.Kernel/Container/ModuleContainerFactory.cs @@ -17,8 +17,8 @@ public class ModuleContainerFactory : IModuleContainerFactory /// public IContainer Create(IDictionary strategies, Assembly moduleAssembly) { - var container = new CastleContainer(strategies) - .ExecuteInstaller(new AutoInstaller(moduleAssembly)); + var container = new CastleContainer(strategies); + container.LoadFromAssembly(moduleAssembly); return container; } } diff --git a/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs b/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs index a5520a0bc..fa99bec14 100644 --- a/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs +++ b/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs @@ -10,13 +10,13 @@ namespace Moryx.TestTools.UnitTest /// /// Installer registering the interceptor /// - public class BasicInterceptorInstaller : IContainerInstaller + public static class BasicInterceptorInstaller { /// - public void Install(IComponentRegistrator registrator) + public static void Install(this IContainer container) { - registrator.Register(typeof(EmptyInterceptor)); - registrator.Register(typeof(NullLoggerFactory), new []{typeof(ILoggerFactory)}); + container.Register(typeof(EmptyInterceptor)); + container.Register(typeof(NullLoggerFactory), new []{typeof(ILoggerFactory)}); } } } diff --git a/src/Moryx/Container/ContainerLoadComponentsExtension.cs b/src/Moryx/Container/ContainerLoadComponentsExtension.cs new file mode 100644 index 000000000..b4c37c155 --- /dev/null +++ b/src/Moryx/Container/ContainerLoadComponentsExtension.cs @@ -0,0 +1,131 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using Moryx.Tools; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Moryx.Container +{ + /// + /// Extension to replace load components on + /// + public static class ContainerLoadComponentsExtension + { + private static Type[] _knownTypes; + + /// + /// Load all types from an assembly + /// + public static void LoadFromAssembly(this IContainer container, Assembly assembly) + { + container.LoadFromAssembly(assembly, t => true); + } + + /// + /// Load types from assembly filtered by dependency attribute + /// + public static void LoadFromAssembly(this IContainer container, Assembly assembly, DependencyRegistrationAttribute att) + { + container.LoadFromAssembly(assembly, type => TypeRequired(att, type)); + } + + /// + /// Load filtered types from assembly + /// + public static void LoadFromAssembly(this IContainer container, Assembly assembly, Predicate predicate) + { + // Install all components + foreach (var type in assembly.GetTypes()) + { + // Register all we want + if (ShallInstall(type) && predicate(type)) + container.Register(type); + } + } + + /// + /// Method to determine if this component shall be installed + /// + private static bool ShallInstall(Type foundType) + { + var regAtt = foundType.GetCustomAttribute(); + var facAtt = foundType.GetCustomAttribute(); + + return (regAtt != null || facAtt != null); + } + + private static bool TypeRequired(DependencyRegistrationAttribute att, Type foundType) + { + if (att.InstallerMode == InstallerMode.All) + return true; + + // Check if interface was specified as required + if (foundType.IsInterface && att.RequiredTypes.Contains(foundType)) + return true; + + // Check if class exports required type + var services = ContainerRegistrationExtensions.GetComponentServices(foundType); + if (foundType.IsClass && att.RequiredTypes.Intersect(services).Any()) + return true; + + return false; + } + + /// + /// Load all implementations of type from currently known types + /// KnownTypes: Types in default framework folders and deeper. + /// + public static void LoadComponents(this IContainer container) where T : class + { + LoadComponents(container, null); + } + + /// + /// Loads all implementations of type from the currently known types + /// KnownTypes: Types in default framework folders and deeper. + /// + public static IContainer LoadComponents(this IContainer container, Predicate condition) where T : class + { + if (_knownTypes == null) + { + _knownTypes = ReflectionTool.GetAssemblies() + .Where(a => a.GetCustomAttribute() == null) + .SelectMany(a => a.GetTypes()) + .Where(t => t.GetCustomAttribute(true) != null).ToArray(); + } + + foreach (var type in _knownTypes.Where(type => typeof(T).IsAssignableFrom(type))) + { + if (condition?.Invoke(type) ?? true) + { + container.Register(type); + + RegisterAdditionalDependencies(container, type); + } + } + + return container; + } + + private static void RegisterAdditionalDependencies(IContainer container, Type implementation) + { + var att = implementation.GetCustomAttribute(); + if (att == null) + return; + + container.LoadFromAssembly(implementation.Assembly, att); + + if (att.Initializer == null) + return; + + if (!typeof(ISubInitializer).IsAssignableFrom(att.Initializer)) + throw new InvalidCastException($"SubInitializer {att.Initializer.Name} of component {implementation.Name} does not implement interface ISubInitializer"); + + container.Register(att.Initializer, new[] { typeof(ISubInitializer), att.Initializer }, null, LifeCycle.Singleton); + } + } +} diff --git a/src/Moryx/Container/ContainerRegistrationExtensions.cs b/src/Moryx/Container/ContainerRegistrationExtensions.cs new file mode 100644 index 000000000..5534aea18 --- /dev/null +++ b/src/Moryx/Container/ContainerRegistrationExtensions.cs @@ -0,0 +1,171 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Moryx.Container +{ + /// + /// Extensions on the reduced interface + /// + public static class ContainerRegistrationExtensions + { + /// + /// Register external type in local container + /// + public static IContainer Register(this IContainer container) + where TComp : TService + where TService : class + { + var type = typeof(TComp); + var regAtt = type.GetCustomAttribute(); + container.Register(type, new[] { typeof(TService) }, regAtt?.Name, regAtt?.LifeStyle ?? LifeCycle.Singleton); + + return container; + } + + /// + /// Register external type in local container + /// + public static IContainer Register(this IContainer container, string name, LifeCycle lifeCycle) + where TComp : TService + where TService : class + { + container.Register(typeof(TComp), new[] { typeof(TService) }, name, lifeCycle); + + return container; + } + + /// + /// Register type and determine factory and services automatically + /// + public static IContainer Register(this IContainer container, Type type) + { + if (type.IsInterface) + { + container.RegisterFactory(type); + } + else + { + var services = GetComponentServices(type); + container.Register(type, services); + } + + return container; + } + + /// + /// Get all services of this component + /// + public static Type[] GetComponentServices(Type type) + { + var att = type.GetCustomAttribute(); + if (att != null) + return att.Services.Any() ? att.Services : new[] { type }; + + var interfaces = type.GetInterfaces(); + return interfaces.Any() ? interfaces : new[] { type }; + } + + + /// + /// Register a type for different services + /// + public static IContainer Register(this IContainer container, Type type, Type[] services) + { + var regAtt = type.GetCustomAttribute(); + container.Register(type, services, regAtt?.Name, regAtt?.LifeStyle ?? LifeCycle.Singleton); + + return container; + } + + /// + /// Register named component for the services + /// + public static IContainer Register(this IContainer container, Type type, Type[] services, string name) + { + container.Register(type, services, name, LifeCycle.Singleton); + + return container; + } + + /// + /// Register a factory by generic interface + /// + public static IContainer Register(this IContainer container) where TFactory : class + { + var att = typeof(TFactory).GetCustomAttribute(); + container.RegisterFactory(typeof(TFactory), null, att?.Selector); + return container; + } + + /// + /// Register a named factory + /// + public static IContainer Register(this IContainer container, string name) where TFactory : class + { + var factoryType = typeof(TFactory); + var att = typeof(TFactory).GetCustomAttribute(); + container.RegisterFactory(factoryType, name, att?.Selector); + + return container; + } + + /// + /// Register factory by type + /// + public static IContainer RegisterFactory(this IContainer container, Type factoryInterface) + { + var facAtt = factoryInterface.GetCustomAttribute(); + container.RegisterFactory(factoryInterface, null, facAtt?.Selector); + + return container; + } + + /// + /// Register named factory by type + /// + public static IContainer RegisterFactory(this IContainer container, Type factoryInterface, string name) + { + container.RegisterFactory(factoryInterface, name, null); + + return container; + } + + /// + /// Set instance of service + /// + /// Type of service + /// Container to register in + /// Instance implementing the service + public static IContainer SetInstance(this IContainer container, T instance) where T : class + { + if (instance != null) + { + container.RegisterInstance(new[] {typeof(T)}, instance, null); + } + return container; + } + + /// + /// Set globally imported instance with name + /// + /// Type of service + /// Container to register in + /// Instance to register + /// Name of instance + public static IContainer SetInstance(this IContainer container, T instance, string name) where T : class + { + if (instance != null) + { + container.RegisterInstance(new[] { typeof(T) }, instance, name); + } + return container; + } + } +} diff --git a/src/Moryx/Container/IComponentRegistrator.cs b/src/Moryx/Container/IComponentRegistrator.cs deleted file mode 100644 index ac2bdf7d1..000000000 --- a/src/Moryx/Container/IComponentRegistrator.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; - -namespace Moryx.Container -{ - /// - /// Responensible for component registration based on information given in - /// - public interface IComponentRegistrator - { - /// - /// Check if a type shall be registered - /// - /// - /// - bool ShallInstall(Type foundType); - - /// - /// Register a type in the container. Automatically registers interfaces as factory - /// - /// Type to register - void Register(Type type); - - /// - /// Register a type for a couple of services - /// - /// - /// - void Register(Type type, Type[] services); - - /// - /// Register a type for services under a given name - /// - void Register(Type type, Type[] services, string name); - - /// - /// Full registration method - /// - void Register(Type type, Type[] services, string name, LifeCycle lifeCycle); - - /// - /// Register a factory - /// - /// - void RegisterFactory(Type factoryInterface); - - /// - /// Register a factory under a special name - /// - void RegisterFactory(Type factoryInterface, string name); - - /// - /// Register a factory under a special name - /// - void RegisterFactory(Type factoryInterface, string name, Type selector); - } -} diff --git a/src/Moryx/Container/IContainer.cs b/src/Moryx/Container/IContainer.cs index 43d68fbac..6b7c2baa1 100644 --- a/src/Moryx/Container/IContainer.cs +++ b/src/Moryx/Container/IContainer.cs @@ -62,80 +62,20 @@ public interface IContainer /// IEnumerable GetRegisteredImplementations(Type componentInterface); - #region LoadComponents - - /// - /// Load all implementations of type from currently known types - /// KnownTypes: Types in default framework folders and deeper. - /// - void LoadComponents() - where T : class; - - /// - /// Load all implementations of type from currently known types - /// KnownTypes: Types in default framework folders and deeper. - /// - void LoadComponents(Predicate condition) - where T : class; - - #endregion - - #region Register - /// - /// Execute the installer + /// Full registration method /// - /// - IContainer ExecuteInstaller(IContainerInstaller installer); + void Register(Type type, Type[] services, string name, LifeCycle lifeCycle); /// - /// Register external type in local container + /// Register a factory interface for automatic implementation /// - IContainer Register() - where TComp : TService - where TService : class; + void RegisterFactory(Type factoryInterface, string name, Type selector); /// - /// Register external type in local container + /// Register instance for given services in the container /// - IContainer Register(string name, LifeCycle lifeCycle) - where TComp : TService - where TService : class; - - /// - /// Register factory interface - /// - /// - IContainer Register() - where TFactory : class; - - /// - /// Register factory interface - /// - /// - IContainer Register(string name) - where TFactory : class; - - #endregion - - #region Set instance - - /// - /// Set instance of service - /// - /// Type of service - /// Instance implementing the service - IContainer SetInstance(T instance) where T : class; - - /// - /// Set globally imported instance with name - /// - /// Type of service - /// Instance to register - /// Name of instance - IContainer SetInstance(T instance, string name) where T : class; - - #endregion + void RegisterInstance(Type[] services, object instance, string name); #region Extensions diff --git a/src/Moryx/Container/IContainerInstaller.cs b/src/Moryx/Container/IContainerInstaller.cs deleted file mode 100644 index 3d21ae311..000000000 --- a/src/Moryx/Container/IContainerInstaller.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Container -{ - /// - /// Interface for all installers that extend the - /// - public interface IContainerInstaller - { - /// - /// Install using the given registrator - /// - void Install(IComponentRegistrator registrator); - } -} diff --git a/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs b/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs index 9787bfa3c..82db45d09 100644 --- a/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs +++ b/src/Tests/Moryx.Container.Tests/Local/LocalContainerTest.cs @@ -16,7 +16,7 @@ public class LocalContainerTest public void Init() { _container = new CastleContainer(new Dictionary()); - _container.ExecuteInstaller(new AutoInstaller(GetType().Assembly)); + _container.LoadFromAssembly(GetType().Assembly); } [Test] diff --git a/src/Tests/Moryx.Container.Tests/Registrator/FakeAutoInstaller.cs b/src/Tests/Moryx.Container.Tests/Registrator/FakeAutoInstaller.cs deleted file mode 100644 index 8d68f3e84..000000000 --- a/src/Tests/Moryx.Container.Tests/Registrator/FakeAutoInstaller.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Container.Tests -{ - internal class FakeAutoInstaller : AutoInstaller - { - /// - /// Create a new instance of the for this assembly - /// - public FakeAutoInstaller() : base(typeof(FakeAutoInstaller).Assembly) - { - } - - public bool SkippedNamed { get; private set; } - public bool SkippedUnnamed { get; private set; } - - /// - /// Install all components - /// - public override void Install(IComponentRegistrator registrator) - { - SkippedNamed = !ShallInstall(registrator, typeof(NamedDummy)); - - SkippedUnnamed = !ShallInstall(registrator, typeof(UnnamedDummy)); - } - } -} diff --git a/src/Tests/Moryx.Container.Tests/Registrator/RegistratorTest.cs b/src/Tests/Moryx.Container.Tests/Registrator/RegistratorTest.cs index 76811947a..35c32946a 100644 --- a/src/Tests/Moryx.Container.Tests/Registrator/RegistratorTest.cs +++ b/src/Tests/Moryx.Container.Tests/Registrator/RegistratorTest.cs @@ -22,18 +22,14 @@ public void Init() [Test] public void DoubleRegistrationWithRegister() { - Assert.Throws(() => _container.Register()); - Assert.Throws(() => _container.Register()); + Assert.DoesNotThrow(() => _container.Register()); + Assert.DoesNotThrow(() => _container.Register()); } [Test] public void DoubleRegistrationWithAutoInstaller() { - var fakeAutoInstaller = new FakeAutoInstaller(); - _container.ExecuteInstaller(fakeAutoInstaller); - - Assert.True(fakeAutoInstaller.SkippedNamed, "Named was not skipped"); - Assert.True(fakeAutoInstaller.SkippedUnnamed, "Unnamed was not skipped"); + Assert.DoesNotThrow(() => _container.LoadFromAssembly(GetType().Assembly)); } } } From 1a2715f89f120a7a8d03979e90f4583671173d92 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Tue, 25 Jul 2023 16:20:10 +0200 Subject: [PATCH 09/57] Replace Resolve overloads with extension --- src/Moryx.Container/CastleContainer.cs | 81 +++++-------------- .../ModuleController/ModuleConsole.cs | 1 + .../Container/ContainerResolveExtensions.cs | 54 +++++++++++++ src/Moryx/Container/IContainer.cs | 42 +--------- 4 files changed, 76 insertions(+), 102 deletions(-) create mode 100644 src/Moryx/Container/ContainerResolveExtensions.cs diff --git a/src/Moryx.Container/CastleContainer.cs b/src/Moryx.Container/CastleContainer.cs index 6a4b895d5..2ec8feb94 100644 --- a/src/Moryx.Container/CastleContainer.cs +++ b/src/Moryx.Container/CastleContainer.cs @@ -52,61 +52,24 @@ public CastleContainer(IDictionary strategies) #endregion - /// - public virtual void Destroy() - { - _container.Dispose(); - } - - /// - /// Resolve an instance of the given service - /// - /// Type to resolve - /// Instance of type - public virtual T Resolve() - { - var service = typeof(T); - return _strategies.ContainsKey(service) - ? Resolve(_strategies[service]) - : _container.Kernel.HasComponent(typeof(T)) ? _container.Resolve() : default(T); - } - - /// - /// Resolve this dependency - /// - public virtual object Resolve(Type service) - { - return _strategies.ContainsKey(service) - ? Resolve(service, _strategies[service]) - : _container.Kernel.HasComponent(service) ? _container.Resolve(service) : null; - } - - /// - /// Resolve a named instance of the given service - /// - /// Type to resolve - /// Instance of type - public T Resolve(string name) - { - return _container.Kernel.HasComponent(name) ? _container.Resolve(name) : default(T); - } - /// /// Resolve this named dependency /// public object Resolve(Type service, string name) { - return _container.Kernel.HasComponent(name) ? _container.Resolve(name, service) : null; - } - - /// - /// Resolve all implementations of this contract - /// - /// Type to resolve - /// - public T[] ResolveAll() - { - return _container.ResolveAll(); + if(name == null && _strategies.ContainsKey(service)) + name = _strategies[service]; + + // Resolve by name if given or determined + if (name != null && _container.Kernel.HasComponent(name)) + return _container.Resolve(name, service); + + // Resolve by type if found + if (_container.Kernel.HasComponent(service)) + return _container.Resolve(service); + + // Otherwise return null + return null; } /// @@ -121,9 +84,9 @@ public Array ResolveAll(Type service) /// Get all implementations for a given component interface /// /// - public IEnumerable GetRegisteredImplementations(Type componentInterface) + public IEnumerable GetRegisteredImplementations(Type service) { - return _container.Kernel.GetHandlers(componentInterface).Select(handler => handler.ComponentModel.Implementation); + return _container.Kernel.GetHandlers(service).Select(handler => handler.ComponentModel.Implementation); } #region Register methods @@ -238,18 +201,10 @@ public void RegisterInstance(Type[] services, object instance, string name) #endregion - #region SetInstances - - public void Extend() where TExtension : new() + /// + public virtual void Destroy() { - var facilityType = typeof(IFacility); - if (!facilityType.IsAssignableFrom(typeof(TExtension))) - throw new InvalidOperationException("The underlying container only supports " + facilityType.FullName + "!"); - - var facility = (IFacility)new TExtension(); - _container.AddFacility(facility); + _container.Dispose(); } - - #endregion } } diff --git a/src/Moryx.TestModule/ModuleController/ModuleConsole.cs b/src/Moryx.TestModule/ModuleController/ModuleConsole.cs index 94ad538a2..b958beafe 100644 --- a/src/Moryx.TestModule/ModuleController/ModuleConsole.cs +++ b/src/Moryx.TestModule/ModuleController/ModuleConsole.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using Moryx.Runtime.Modules; using Moryx.Serialization; +using Moryx.Container; using IContainer = Moryx.Container.IContainer; namespace Moryx.TestModule diff --git a/src/Moryx/Container/ContainerResolveExtensions.cs b/src/Moryx/Container/ContainerResolveExtensions.cs new file mode 100644 index 000000000..de70d8d44 --- /dev/null +++ b/src/Moryx/Container/ContainerResolveExtensions.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Moryx.Container +{ + /// + /// Extensions to replace the overloads of + /// + public static class ContainerResolveExtensions + { + /// + /// Resolve an instance of the given service + /// + /// Type to resolve + /// Instance of type + public static T Resolve(this IContainer container) + { + return (T)container.Resolve(typeof(T), null); + } + + /// + /// Resolve this dependency + /// + public static object Resolve(this IContainer container, Type service) + { + return container.Resolve(service, null); + } + + /// + /// Resolve a named instance of the given service + /// + /// Type to resolve + /// Instance of type + public static T Resolve(this IContainer container, string name) + { + return (T)container.Resolve(typeof(T), name); + } + + /// + /// Resolve all implementations of this contract + /// + /// Type to resolve + /// + public static T[] ResolveAll(this IContainer container) + { + return (T[])container.ResolveAll(typeof(T)); + } + } +} diff --git a/src/Moryx/Container/IContainer.cs b/src/Moryx/Container/IContainer.cs index 6b7c2baa1..150d75552 100644 --- a/src/Moryx/Container/IContainer.cs +++ b/src/Moryx/Container/IContainer.cs @@ -12,55 +12,23 @@ namespace Moryx.Container /// public interface IContainer { - /// - /// Destroy the internal container and all registered objects - /// - void Destroy(); - - #region Resolve - - /// - /// Resolve an instance of the given service - /// - /// Type to resolve - /// Instance of type - T Resolve(); - - /// - /// Resolve this dependency - /// - object Resolve(Type service); - - /// - /// Resolve a named instance of the given service - /// - T Resolve(string name); - /// /// Resolve this named dependency /// object Resolve(Type service, string name); - /// - /// Resolve all implementations of this contract - /// - /// Type to resolve - /// - T[] ResolveAll(); - /// /// Resolve all implementations of this contract /// /// Service to resolve implementation for /// Array ResolveAll(Type service); - #endregion /// /// Get all implementations for a given component interface /// /// - IEnumerable GetRegisteredImplementations(Type componentInterface); + IEnumerable GetRegisteredImplementations(Type service); /// /// Full registration method @@ -77,13 +45,9 @@ public interface IContainer /// void RegisterInstance(Type[] services, object instance, string name); - #region Extensions - /// - /// + /// Destroy the internal container and all registered objects /// - void Extend() where TExtension : new(); - - #endregion + void Destroy(); } } From 148728b26d8ecf796abee39908b683caf2e71ad3 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Tue, 25 Jul 2023 16:46:17 +0200 Subject: [PATCH 10/57] Replace registration override with facility and subresolver --- src/Moryx.Container/CastleContainer.cs | 38 +------------ .../ChildContainerSubResolver.cs | 2 +- src/Moryx.Container/MoryxFacility.cs | 11 ++++ .../NamedDependencyResolver.cs | 54 +++++++++++++++++++ src/Moryx.Container/StrategySubResolver.cs | 35 ++++++++++++ 5 files changed, 102 insertions(+), 38 deletions(-) create mode 100644 src/Moryx.Container/NamedDependencyResolver.cs create mode 100644 src/Moryx.Container/StrategySubResolver.cs diff --git a/src/Moryx.Container/CastleContainer.cs b/src/Moryx.Container/CastleContainer.cs index 2ec8feb94..411a51257 100644 --- a/src/Moryx.Container/CastleContainer.cs +++ b/src/Moryx.Container/CastleContainer.cs @@ -44,7 +44,7 @@ public CastleContainer(IDictionary strategies) _container = new WindsorContainer(); _container.AddFacility(); - _container.AddFacility(); + _container.AddFacility(mf => mf.AddStrategies(strategies)); // Self registration for framework functionality RegisterInstance(new[] { typeof(IContainer) }, this, null); @@ -120,45 +120,9 @@ public void Register(Type type, Type[] services, string name, LifeCycle lifeCycl break; } - // Optionally override property injection - foreach (var property in registration.Implementation.GetProperties()) - { - // Check if this property has an override - var dependency = OverrideDependency(property.Name, property.PropertyType, property); - - // Override property injection for this property if found - if (dependency != null) - registration.DependsOn(dependency); - } - - // Override Constructor injection as well - foreach (var constructorParameter in registration.Implementation.GetConstructors().SelectMany(constructor => constructor.GetParameters())) - { - // Check if this paramter has an override - var dependency = OverrideDependency(constructorParameter.Name, constructorParameter.ParameterType, constructorParameter); - - // Override constructor injection for this property if found - if (dependency != null) - registration.DependsOn(dependency); - } - _container.Register(registration); } - /// - /// Determine a possible override for this member. Base implementatin checks for named attribute - /// - private ServiceOverride OverrideDependency(string dependencyName, Type dependencyType, ICustomAttributeProvider attributeProvider) - { - var atts = attributeProvider.GetCustomAttributes(typeof(NamedAttribute), false); - var dependency = atts.Any() ? Dependency.OnComponent(dependencyName, ((NamedAttribute)atts[0]).ComponentName) : null; - - if (dependency == null && _strategies.ContainsKey(dependencyType)) - dependency = Dependency.OnComponent(dependencyName, _strategies[dependencyType]); - - return dependency; - } - /// /// Register factory interface /// diff --git a/src/Moryx.Container/ChildContainerSubResolver.cs b/src/Moryx.Container/ChildContainerSubResolver.cs index 6e6275d24..d39dd5148 100644 --- a/src/Moryx.Container/ChildContainerSubResolver.cs +++ b/src/Moryx.Container/ChildContainerSubResolver.cs @@ -46,7 +46,7 @@ private static bool IsContainerChild(Type candidate) return candidate.IsGenericType && candidate.GetGenericTypeDefinition() == typeof(IContainerChild<>); } - private UseChildAttribute GetAttribute(Type targetType, DependencyModel dependency) + private static UseChildAttribute GetAttribute(Type targetType, DependencyModel dependency) { UseChildAttribute att = null; if (dependency.IsOptional) diff --git a/src/Moryx.Container/MoryxFacility.cs b/src/Moryx.Container/MoryxFacility.cs index 71abcae0d..65f123410 100644 --- a/src/Moryx.Container/MoryxFacility.cs +++ b/src/Moryx.Container/MoryxFacility.cs @@ -5,16 +5,27 @@ using Castle.MicroKernel; using Castle.MicroKernel.Registration; using Castle.MicroKernel.Resolvers.SpecializedResolvers; +using System; +using System.Collections.Generic; namespace Moryx.Container { internal class MoryxFacility : IFacility { + private IDictionary _strategies; + + public void AddStrategies(IDictionary strategies) + { + _strategies = strategies; + } + public void Init(IKernel kernel, IConfiguration facilityConfig) { kernel.Register(Component.For().ImplementedBy().LifestyleTransient()); kernel.Register(Component.For().ImplementedBy().LifestyleTransient()); kernel.Resolver.AddSubResolver(new CollectionResolver(kernel, true)); + kernel.Resolver.AddSubResolver(new NamedDependencyResolver(kernel)); + kernel.Resolver.AddSubResolver(new StrategySubResolver(kernel, _strategies)); kernel.Resolver.AddSubResolver(new ChildContainerSubResolver(kernel)); } diff --git a/src/Moryx.Container/NamedDependencyResolver.cs b/src/Moryx.Container/NamedDependencyResolver.cs new file mode 100644 index 000000000..2bf02c69b --- /dev/null +++ b/src/Moryx.Container/NamedDependencyResolver.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using Castle.Core; +using Castle.MicroKernel.Context; +using Castle.MicroKernel; +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; +using System.Reflection; + +namespace Moryx.Container +{ + internal class NamedDependencyResolver : ISubDependencyResolver + { + private readonly IKernel _kernel; + + public NamedDependencyResolver(IKernel kernel) + { + _kernel = kernel; + } + + public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) + { + return dependency.TargetType != null && GetAttribute(model.Implementation, dependency) != null; + } + + public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) + { + // The dependency is declared with a name + var att = GetAttribute(model.Implementation, dependency); + // The dependency is a registered strategy, resolve by strategy name instead + return _kernel.Resolve(att.ComponentName, dependency.TargetType); + } + + private static NamedAttribute GetAttribute(Type targetType, DependencyModel dependency) + { + NamedAttribute att = null; + if (dependency.IsOptional) + { + // Find property and look for attribute + var property = targetType.GetProperty(dependency.DependencyKey); + att = property.GetCustomAttribute(); + } + else if (dependency is ConstructorDependencyModel constDep) + { + var parameter = constDep.Constructor.Constructor.GetParameters().FirstOrDefault(param => param.Name == dependency.DependencyKey); + att = parameter.GetCustomAttribute(); + } + return att; + } + } +} diff --git a/src/Moryx.Container/StrategySubResolver.cs b/src/Moryx.Container/StrategySubResolver.cs new file mode 100644 index 000000000..441f5f8f2 --- /dev/null +++ b/src/Moryx.Container/StrategySubResolver.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using Castle.Core; +using Castle.MicroKernel.Context; +using Castle.MicroKernel; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Moryx.Container +{ + internal class StrategySubResolver : ISubDependencyResolver + { + private readonly IKernel _kernel; + private readonly IDictionary _strategies; + + public StrategySubResolver(IKernel kernel, IDictionary strategies) + { + _kernel = kernel; + _strategies = strategies; + } + + public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) + { + return dependency.TargetType != null && _strategies.ContainsKey(dependency.TargetType); + } + + public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) + { + // The dependency is a registered strategy, resolve by strategy name instead + return _kernel.Resolve(_strategies[dependency.TargetType], dependency.TargetType); + } + } +} From e39f6f73401ae54af1cef4414a1fa16a271896e0 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Sat, 5 Aug 2023 22:30:42 +0200 Subject: [PATCH 11/57] Reactivate tests on linux --- .../ResourceManagementController.cs | 1 - .../CommunicationSocketsTests.cs | 4 ---- .../CommunicationSocketsTestsBase.cs | 4 ---- .../DelimiterProtocol/DelimiterCommunicationSocketTests.cs | 4 ---- .../HeaderProtocol/HeaderedCommunicationSocketTests.cs | 4 ---- .../Moryx.Communication.Sockets.IntegrationTests.csproj | 4 ---- 6 files changed, 21 deletions(-) diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs index 8163127f8..81207a2a3 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs @@ -15,7 +15,6 @@ using Moryx.Tools; using Moryx.AbstractionLayer.Properties; using Moryx.Runtime.Modules; -using Moryx.Runtime.Container; using Moryx.Configuration; using Moryx.Resources.Management; diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs index 2e28b0f30..1eb19a2f3 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTests.cs @@ -9,9 +9,6 @@ namespace Moryx.Communication.Sockets.IntegrationTests { - // preprocessor statement for differentiating between different os - // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) - #if _WINDOWS [TestFixture] public class CommunicationSocketsTests : CommunicationSocketsTestsBase> { @@ -132,5 +129,4 @@ public void SendEmptyMessages() WaitForConnectionState(0, new TimeSpan(0, 0, 0, 1), BinaryConnectionState.AttemptingConnection); } } - #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs index 1196f240e..fc3b866b5 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/CommunicationSocketsTestsBase.cs @@ -11,9 +11,6 @@ namespace Moryx.Communication.Sockets.IntegrationTests { - // preprocessor statement for differentiating between different os - // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) - #if _WINDOWS public abstract class CommunicationSocketsTestsBase where TMessage : BinaryMessage { private List> _serverConnections; @@ -343,5 +340,4 @@ protected static TcpListenerConfig CreateServerConfig(IPAddress adress, int port }; } } - #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs index 4e0955067..8cf86bb2f 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/DelimiterProtocol/DelimiterCommunicationSocketTests.cs @@ -8,9 +8,6 @@ namespace Moryx.Communication.Sockets.IntegrationTests.DelimiterProtocol { - // preprocessor statement for differentiating between different os - // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) - #if _WINDOWS [TestFixture] public class DelimiterCommunicationSocketTests : CommunicationSocketsTestsBase { @@ -69,5 +66,4 @@ public void SendDelimitedMessage() EndDelimiterOnlyInterpreter.TestEndDelimiter.Length, published.Payload.Length); } } - #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs index 72e6d7b2a..44d6018a9 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/HeaderProtocol/HeaderedCommunicationSocketTests.cs @@ -10,9 +10,6 @@ namespace Moryx.Communication.Sockets.IntegrationTests { - // preprocessor statement for differentiating between different os - // see: https://github.com/PHOENIXCONTACT/MORYX-Framework/issues/100 (Moryx-Framework/src/Moryx/Communication/Sockets/TcpTransmission.cs in line 85) - #if _WINDOWS [TestFixture] public class HeaderedCommunicationSocketTests : CommunicationSocketsTestsBase> { @@ -302,5 +299,4 @@ protected override BinaryMessage CreateMessage(int senderId, byte[] payload) return new BinaryMessage(header, payload); } } - #endif } diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj index ad0e426c8..d2192d8c5 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj @@ -6,10 +6,6 @@ full - - _WINDOWS - - From 49b8134f5ee4df682bd1fbeebb3dcf3219bd59b9 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Wed, 16 Aug 2023 12:52:23 +0200 Subject: [PATCH 12/57] Start migration guide --- docs/migrations/v6_to_v8.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/migrations/v6_to_v8.md diff --git a/docs/migrations/v6_to_v8.md b/docs/migrations/v6_to_v8.md new file mode 100644 index 000000000..f8a306ebb --- /dev/null +++ b/docs/migrations/v6_to_v8.md @@ -0,0 +1,13 @@ +# Migration from MORYX Framework v6 to v8 + + +## Local Container Refactoring +The DI container within modules based on Castle Windsor was refactored and simplified. The most changes are caused by removing the historic split between local and global container, which was obsolete after switching the global container to ServiceCollection. We also removed the concept of installers and registrators and replaced everything with API on `IContainer` and extensions inspired by the `IServiceCollection`. + +- **Attribute changes:** The base attributes for registration were removed, use `ComponentAttribute`, `PluginAttribute` and `PluginFactory` instead. +- **Installers removed** The concept of installes was removed and with it their implementations `AutoInstaller` and `DependencyInstaller`. They were replaced by the extensions `LoadFromAssembly` with different signature options for `DependencyRegistrationAttribute` and `Predicate` +- **LoadComponents** was removed as a dedicate feature and is now an extension on `IContainer`. +- **IContainerHost** was removed. The seperate interface for accessing a modules container just caused unnecessary casts and the risk of invalid type. The property `Container` was added to `IServerModule` instead. +- **Extend** The flexible method for passing facilities to Castle was removed as it was only added and used by WCF. +- **MoryxFacility** All MORYX specific behavior like strategies and `Named` import overrides were refactored to follow Castle best practises and are now isolated in the `MoryxFacility`. This enables everyone to achieve the MORYX DI behavior with a Castle Container without the MORYX wrapper. +- **Installers** As previously mentioned installers were removed, but since the API on `IContainer` now supports everything previously reserved for installers and registrators, just migrate the registration onto the container like the [DbContextContainerExtension](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.Model/DbContextContainerExtension.cs) or the [BasicInterceptorInstaller](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs) \ No newline at end of file From 3e32ad960030d1d7dc87116ca237200460dfae25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 06:38:09 +0000 Subject: [PATCH 13/57] Bump Microsoft.NET.Test.Sdk from 17.6.3 to 17.7.1 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.3 to 17.7.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.6.3...v17.7.1) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index cd4ce9f7b..c1e61344a 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -18,7 +18,7 @@ - + From 645805e9428368b115b89e2cd792ac7e0ff115aa Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Tue, 22 Aug 2023 14:08:06 +0200 Subject: [PATCH 14/57] Trigger CI build --- .github/workflows/build-and-test.yml | 2 +- LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 67d3e1b88..edf6da4d2 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,7 +14,7 @@ on: - future env: - dotnet_sdk_version: '8.0.100-preview.5.23303.2' + dotnet_sdk_version: '8.0.100-preview.7.23376.3' REPOSITORY_NAME: ${{ github.event.repository.name }} MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package' MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json' diff --git a/LICENSE b/LICENSE index f433b1a53..33f844f2c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION From 677aa3f783bc23a3231b0b565499586f1760fe40 Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Wed, 23 Aug 2023 12:19:10 +0200 Subject: [PATCH 15/57] Missing property added --- src/Moryx.Runtime.Kernel/Modules/MissingServerModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Moryx.Runtime.Kernel/Modules/MissingServerModule.cs b/src/Moryx.Runtime.Kernel/Modules/MissingServerModule.cs index cbfb436f4..949c22c93 100644 --- a/src/Moryx.Runtime.Kernel/Modules/MissingServerModule.cs +++ b/src/Moryx.Runtime.Kernel/Modules/MissingServerModule.cs @@ -1,4 +1,5 @@ -using Moryx.Modules; +using Moryx.Container; +using Moryx.Modules; using Moryx.Runtime.Modules; using System; using System.Collections.Generic; @@ -58,5 +59,7 @@ public void Stop() } public Type RepresentedService { get; private set; } + + public IContainer Container => throw new NotImplementedException(); } } From 56be96b2262dcedd738abba634599a8254b10a2f Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Fri, 25 Aug 2023 12:41:18 +0200 Subject: [PATCH 16/57] Move IPublicResource To IResource --- .../ResourceManagementController.cs | 2 +- .../Resources/IPublicResource.cs | 24 ------------ .../Resources/IResource.cs | 13 +++++++ .../Resources/IResourceManagement.cs | 20 +++++----- .../Resources/PublicResource.cs | 38 ------------------- .../Resources/Resource.cs | 26 +++++++++++++ .../Extensions/ResourceExtensions.cs | 4 +- .../Facades/ResourceManagementFacade.cs | 26 ++++++------- .../Resources/IResourceManager.cs | 4 +- .../Resources/ResourceGraph.cs | 8 ++-- .../Resources/ResourceManager.cs | 16 ++++---- .../Resources/ResourceProxy.cs | 6 +++ .../Resources/ResourceProxyBuilder.cs | 2 +- src/Moryx.Resources.Samples/BufferResource.cs | 2 +- src/Moryx.Resources.Samples/Cell.cs | 2 +- .../RoutingResource.cs | 2 +- .../Mocks/ReferenceResource.cs | 4 +- .../Mocks/ResourceWithImplicitApi.cs | 4 +- .../Mocks/SimpleResource.cs | 6 +-- .../ResourceManagerTests.cs | 2 +- 20 files changed, 97 insertions(+), 114 deletions(-) delete mode 100644 src/Moryx.AbstractionLayer/Resources/IPublicResource.cs delete mode 100644 src/Moryx.AbstractionLayer/Resources/PublicResource.cs diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs index 8962f357b..15e8d1458 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourceManagementController.cs @@ -60,7 +60,7 @@ public ActionResult GetDetailsBatch([FromQuery] long[] ids) var converter = new ResourceToModelConverter(_resourceTypeTree, _serialization); if (ids is null || ids.Length == 0) - ids = _resourceManagement.GetResources().Select(r => r.Id).ToArray(); + ids = _resourceManagement.GetResources().Select(r => r.Id).ToArray(); return ids.Select(id => _resourceManagement.Read(id, r => converter.GetDetails(r))) .Where(details => details != null).ToArray(); diff --git a/src/Moryx.AbstractionLayer/Resources/IPublicResource.cs b/src/Moryx.AbstractionLayer/Resources/IPublicResource.cs deleted file mode 100644 index 0abe142e8..000000000 --- a/src/Moryx.AbstractionLayer/Resources/IPublicResource.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using Moryx.AbstractionLayer.Capabilities; - -namespace Moryx.AbstractionLayer.Resources -{ - /// - /// Interface for resources that are visible outside of the abstraction layer - /// - public interface IPublicResource : IResource - { - /// - /// The resource's capabilities - /// - ICapabilities Capabilities { get; } - - /// - /// Raised when the capabilities have changed. - /// - event EventHandler CapabilitiesChanged; - } -} diff --git a/src/Moryx.AbstractionLayer/Resources/IResource.cs b/src/Moryx.AbstractionLayer/Resources/IResource.cs index 60bad43ec..112617ebe 100644 --- a/src/Moryx.AbstractionLayer/Resources/IResource.cs +++ b/src/Moryx.AbstractionLayer/Resources/IResource.cs @@ -1,6 +1,9 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +using Moryx.AbstractionLayer.Capabilities; +using System; + namespace Moryx.AbstractionLayer.Resources { /// @@ -17,5 +20,15 @@ public interface IResource /// Name of this resource instance /// string Name { get; } + + /// + /// The resource's capabilities + /// + ICapabilities Capabilities { get; } + + /// + /// Raised when the capabilities have changed. + /// + event EventHandler CapabilitiesChanged; } } diff --git a/src/Moryx.AbstractionLayer/Resources/IResourceManagement.cs b/src/Moryx.AbstractionLayer/Resources/IResourceManagement.cs index 631a11cad..9e8bf7771 100644 --- a/src/Moryx.AbstractionLayer/Resources/IResourceManagement.cs +++ b/src/Moryx.AbstractionLayer/Resources/IResourceManagement.cs @@ -16,51 +16,51 @@ public interface IResourceManagement /// Get only resources of this type /// TResource GetResource() - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get typed resource by id /// TResource GetResource(long id) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get typed resource by name /// TResource GetResource(string name) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get the only resource that provides the required capabilities. /// /// Instance if only one match was found, otherwise null TResource GetResource(ICapabilities requiredCapabilities) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get the only resource that matches the given predicate /// /// Instance if only one match was found, otherwise null TResource GetResource(Func predicate) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get all resources of this type /// IEnumerable GetResources() - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get all resources of this type that provide the required capabilities /// IEnumerable GetResources(ICapabilities requiredCapabilities) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get all resources of this type that match the predicate /// IEnumerable GetResources(Func predicate) - where TResource : class, IPublicResource; + where TResource : class, IResource; /// /// Get all resources inluding the private ones of this type that match the predicate @@ -95,12 +95,12 @@ IEnumerable GetAllResources(Func predicat /// /// Event raised when a resource was added at runtime /// - event EventHandler ResourceAdded; + event EventHandler ResourceAdded; /// /// Event raised when a resource was removed at runtime /// - event EventHandler ResourceRemoved; + event EventHandler ResourceRemoved; /// /// Raised when the capabilities have changed. diff --git a/src/Moryx.AbstractionLayer/Resources/PublicResource.cs b/src/Moryx.AbstractionLayer/Resources/PublicResource.cs deleted file mode 100644 index b098c5b02..000000000 --- a/src/Moryx.AbstractionLayer/Resources/PublicResource.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using Moryx.AbstractionLayer.Capabilities; - -namespace Moryx.AbstractionLayer.Resources -{ - /// - /// Base class for all public resources - /// - public abstract class PublicResource : Resource, IPublicResource - { - /// - /// Current capabilities of this resource - /// - private ICapabilities _capabilities = NullCapabilities.Instance; - - /// - public ICapabilities Capabilities - { - get - { - return _capabilities; - } - protected set - { - _capabilities = value; - CapabilitiesChanged?.Invoke(this, _capabilities); - } - } - - /// - /// - /// - public event EventHandler CapabilitiesChanged; - } -} diff --git a/src/Moryx.AbstractionLayer/Resources/Resource.cs b/src/Moryx.AbstractionLayer/Resources/Resource.cs index edb9430bf..c2d520d2a 100644 --- a/src/Moryx.AbstractionLayer/Resources/Resource.cs +++ b/src/Moryx.AbstractionLayer/Resources/Resource.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.Serialization; using Microsoft.Extensions.Logging; +using Moryx.AbstractionLayer.Capabilities; using Moryx.Logging; using Moryx.Modules; using Moryx.Serialization; @@ -144,6 +145,31 @@ public override string ToString() return $"{Id}:{Name} ({GetType().Name})"; } + + /// + /// Current capabilities of this resource + /// + private ICapabilities _capabilities = NullCapabilities.Instance; + + /// + public ICapabilities Capabilities + { + get + { + return _capabilities; + } + protected set + { + _capabilities = value; + CapabilitiesChanged?.Invoke(this, _capabilities); + } + } + + /// + /// + /// + public event EventHandler CapabilitiesChanged; + /// /// Event raised when the resource was modified and the changes should be /// written to the data storage diff --git a/src/Moryx.Resources.Management/Extensions/ResourceExtensions.cs b/src/Moryx.Resources.Management/Extensions/ResourceExtensions.cs index f8b1a7bac..7c6eecc26 100644 --- a/src/Moryx.Resources.Management/Extensions/ResourceExtensions.cs +++ b/src/Moryx.Resources.Management/Extensions/ResourceExtensions.cs @@ -8,13 +8,13 @@ namespace Moryx.Resources.Management internal static class ResourceExtensions { public static TResource Proxify(this TResource source, IResourceTypeController typeController) - where TResource : class, IPublicResource + where TResource : class, IResource { return (TResource)typeController.GetProxy(source as Resource); } public static IEnumerable Proxify(this IEnumerable source, IResourceTypeController typeController) - where TResource : class, IPublicResource + where TResource : class, IResource { return source.Select(r => r.Proxify(typeController)); } diff --git a/src/Moryx.Resources.Management/Facades/ResourceManagementFacade.cs b/src/Moryx.Resources.Management/Facades/ResourceManagementFacade.cs index 177ab9f06..baa5f7a23 100644 --- a/src/Moryx.Resources.Management/Facades/ResourceManagementFacade.cs +++ b/src/Moryx.Resources.Management/Facades/ResourceManagementFacade.cs @@ -43,70 +43,70 @@ public void Deactivate() private void OnCapabilitiesChanged(object sender, ICapabilities args) { - CapabilitiesChanged?.Invoke(((IPublicResource)sender).Proxify(TypeController), args); + CapabilitiesChanged?.Invoke(((IResource)sender).Proxify(TypeController), args); } - private void OnResourceAdded(object sender, IPublicResource publicResource) + private void OnResourceAdded(object sender, IResource publicResource) { ResourceAdded?.Invoke(this, publicResource.Proxify(TypeController)); } - private void OnResourceRemoved(object sender, IPublicResource publicResource) + private void OnResourceRemoved(object sender, IResource publicResource) { ResourceRemoved?.Invoke(this, publicResource.Proxify(TypeController)); } #endregion #region IResourceManagement - public TResource GetResource() where TResource : class, IPublicResource + public TResource GetResource() where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResource().Proxify(TypeController); } public TResource GetResource(long id) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResource(id).Proxify(TypeController); } public TResource GetResource(string name) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResource(name).Proxify(TypeController); } public TResource GetResource(ICapabilities requiredCapabilities) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResource(r => requiredCapabilities.ProvidedBy(r.Capabilities)).Proxify(TypeController); } public TResource GetResource(Func predicate) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResource(predicate).Proxify(TypeController); } - public IEnumerable GetResources() where TResource : class, IPublicResource + public IEnumerable GetResources() where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResources().Proxify(TypeController); } public IEnumerable GetResources(ICapabilities requiredCapabilities) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResources(r => requiredCapabilities.ProvidedBy(r.Capabilities)).Proxify(TypeController); } public IEnumerable GetResources(Func predicate) - where TResource : class, IPublicResource + where TResource : class, IResource { ValidateHealthState(); return ResourceGraph.GetResources(predicate).Proxify(TypeController); @@ -177,10 +177,10 @@ public IEnumerable GetAllResources(Func p /// - public event EventHandler ResourceAdded; + public event EventHandler ResourceAdded; /// - public event EventHandler ResourceRemoved; + public event EventHandler ResourceRemoved; /// public event EventHandler CapabilitiesChanged; diff --git a/src/Moryx.Resources.Management/Resources/IResourceManager.cs b/src/Moryx.Resources.Management/Resources/IResourceManager.cs index c086a8168..dc2009cc0 100644 --- a/src/Moryx.Resources.Management/Resources/IResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/IResourceManager.cs @@ -20,12 +20,12 @@ internal interface IResourceManager : IInitializablePlugin /// /// Event raised when a resource was added at runtime /// - event EventHandler ResourceAdded; + event EventHandler ResourceAdded; /// /// Event raised when a resource was removed at runtime /// - event EventHandler ResourceRemoved; + event EventHandler ResourceRemoved; /// /// Raised when the capabilities have changed. diff --git a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs index f0f08c041..9c8d6e701 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs @@ -34,7 +34,7 @@ internal class ResourceGraph : IManagedResourceGraph /// /// Quick access to all public resources /// - private readonly IList _publicResources = new List(); + private readonly IList _publicResources = new List(); public Action SaveDelegate { get; set; } @@ -45,7 +45,7 @@ public ResourceWrapper Add(Resource instance) _graphLock.EnterWriteLock(); var wrapper = _graph[instance.Id] = new ResourceWrapper(instance); - if (instance is IPublicResource publicResource) + if (instance is IResource publicResource) _publicResources.Add(publicResource); _graphLock.ExitWriteLock(); @@ -57,7 +57,7 @@ public bool Remove(Resource instance) _graphLock.EnterWriteLock(); var found = _graph.Remove(instance.Id); if (found) - _publicResources.Remove(instance as IPublicResource); + _publicResources.Remove(instance as IResource); _graphLock.ExitWriteLock(); return found; @@ -121,7 +121,7 @@ public IEnumerable GetResources(Func pred IEnumerable matches; _graphLock.EnterReadLock(); // Use short cut if a public resource is requested - if (typeof(IPublicResource).IsAssignableFrom(typeof(TResource))) + if (typeof(IResource).IsAssignableFrom(typeof(TResource))) { matches = _publicResources.Where(p => _graph[p.Id].State.IsAvailable).OfType().Where(predicate); } diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index 5acf6d009..4b4465485 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -190,7 +190,7 @@ private void AddResource(Resource instance, bool registerEvents) } // Inform listeners about the new resource - if (instance is IPublicResource publicResource) + if (instance is IResource publicResource) RaiseResourceAdded(publicResource); } @@ -214,7 +214,7 @@ private void RegisterEvents(Resource instance) { instance.Changed += OnResourceChanged; - if (instance is IPublicResource asPublic) + if (instance is IResource asPublic) asPublic.CapabilitiesChanged += RaiseCapabilitiesChanged; foreach (var autoSaveCollection in ResourceReferenceTools.GetAutoSaveCollections(instance)) @@ -228,7 +228,7 @@ private void UnregisterEvents(Resource instance) { instance.Changed -= OnResourceChanged; - if (instance is IPublicResource asPublic) + if (instance is IResource asPublic) asPublic.CapabilitiesChanged -= RaiseCapabilitiesChanged; foreach (var autoSaveCollection in ResourceReferenceTools.GetAutoSaveCollections(instance)) @@ -410,7 +410,7 @@ public bool Destroy(IResource resource, bool permanent) var removed = Graph.Remove(instance); // Notify listeners about the removal of the resource - if (removed && instance is IPublicResource publicResource) + if (removed && instance is IResource publicResource) RaiseResourceRemoved(publicResource); // Destroy the object @@ -424,17 +424,17 @@ public bool Destroy(IResource resource, bool permanent) #region IResourceManagement - private void RaiseResourceAdded(IPublicResource newResource) + private void RaiseResourceAdded(IResource newResource) { ResourceAdded?.Invoke(this, newResource); } - public event EventHandler ResourceAdded; + public event EventHandler ResourceAdded; - private void RaiseResourceRemoved(IPublicResource newResource) + private void RaiseResourceRemoved(IResource newResource) { ResourceRemoved?.Invoke(this, newResource); } - public event EventHandler ResourceRemoved; + public event EventHandler ResourceRemoved; /// public event EventHandler CapabilitiesChanged; diff --git a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs index 22f11b086..be628fcca 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs @@ -1,8 +1,10 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +using System; using System.Collections.Generic; using System.Linq; +using Moryx.AbstractionLayer.Capabilities; using Moryx.AbstractionLayer.Resources; namespace Moryx.Resources.Management @@ -17,6 +19,8 @@ internal abstract class ResourceProxy : IResource /// private IResourceTypeController _typeController; + public event EventHandler CapabilitiesChanged; + /// /// Target resource of the proxy /// @@ -37,6 +41,8 @@ protected ResourceProxy(IResource target, IResourceTypeController typeController /// string IResource.Name => Target.Name; + public ICapabilities Capabilities => Target.Capabilities; + public virtual void Attach() { } diff --git a/src/Moryx.Resources.Management/Resources/ResourceProxyBuilder.cs b/src/Moryx.Resources.Management/Resources/ResourceProxyBuilder.cs index c09508ce4..a6a04f884 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceProxyBuilder.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceProxyBuilder.cs @@ -87,7 +87,7 @@ public Type Build(Type resourceType, IReadOnlyList interfaces) } // Target field for property and method forwarding - const string propertyName = nameof(ResourceProxy.Target); + const string propertyName = nameof(ResourceProxy.Target); var targetProperty = baseType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); var bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public; diff --git a/src/Moryx.Resources.Samples/BufferResource.cs b/src/Moryx.Resources.Samples/BufferResource.cs index 7202cdf96..208570a95 100644 --- a/src/Moryx.Resources.Samples/BufferResource.cs +++ b/src/Moryx.Resources.Samples/BufferResource.cs @@ -10,7 +10,7 @@ namespace Moryx.Resources.Samples { [ResourceRegistration] - public class BufferResource : PublicResource + public class BufferResource : Resource { [ReferenceOverride(nameof(Children), AutoSave = true)] public IReferences Values { get; set; } diff --git a/src/Moryx.Resources.Samples/Cell.cs b/src/Moryx.Resources.Samples/Cell.cs index ad4faeaf9..9e2bdb0fb 100644 --- a/src/Moryx.Resources.Samples/Cell.cs +++ b/src/Moryx.Resources.Samples/Cell.cs @@ -9,7 +9,7 @@ namespace Moryx.Resources.Samples { - public abstract class Cell : PublicResource + public abstract class Cell : Resource { #region Config diff --git a/src/Moryx.Resources.Samples/RoutingResource.cs b/src/Moryx.Resources.Samples/RoutingResource.cs index 9cd50a005..8dd22c915 100644 --- a/src/Moryx.Resources.Samples/RoutingResource.cs +++ b/src/Moryx.Resources.Samples/RoutingResource.cs @@ -7,7 +7,7 @@ namespace Moryx.Resources.Samples { - public class RoutingResource : PublicResource + public class RoutingResource : Resource { [EntrySerialize, ResourceTypes(typeof(IWpc))] [Description("Type of wpc for Autocreate")] diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs index 55cece266..6160bb6dc 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs @@ -8,7 +8,7 @@ namespace Moryx.Resources.Management.Tests { - public interface IReferenceResource : IPublicResource + public interface IReferenceResource : IResource { ISimpleResource Reference { get; set; } @@ -44,7 +44,7 @@ public class RequiredReferenceResource : Resource public IReferences References { get; set; } } - public class ReferenceResource : PublicResource, IReferenceResource + public class ReferenceResource : Resource, IReferenceResource { private ISimpleResource _reference; diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithImplicitApi.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithImplicitApi.cs index 84cec8f28..c1d214438 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithImplicitApi.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithImplicitApi.cs @@ -10,12 +10,12 @@ public interface IExtension int Add(int value); } - public interface IResourceWithImplicitApi : IPublicResource, IExtension + public interface IResourceWithImplicitApi : IResource, IExtension { } - public class ResourceWithImplicitApi : PublicResource, IResourceWithImplicitApi + public class ResourceWithImplicitApi : Resource, IResourceWithImplicitApi { public int Add(int value) { diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs index 832936f36..0624d3162 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs @@ -6,12 +6,12 @@ namespace Moryx.Resources.Management.Tests { - public interface IDuplicateFoo : IPublicResource + public interface IDuplicateFoo : IResource { int Foo { get; } } - public interface ISimpleResource : IPublicResource + public interface ISimpleResource : IResource { int Foo { get; set; } @@ -34,7 +34,7 @@ public interface INonResourceInterface } [ResourceAvailableAs(typeof(INonResourceInterface))] - public class SimpleResource : PublicResource, ISimpleResource, IDuplicateFoo, INonResourceInterface + public class SimpleResource : Resource, ISimpleResource, IDuplicateFoo, INonResourceInterface { private int _foo; diff --git a/src/Tests/Moryx.Resources.Management.Tests/ResourceManagerTests.cs b/src/Tests/Moryx.Resources.Management.Tests/ResourceManagerTests.cs index df5e432dc..4fa2a6183 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/ResourceManagerTests.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/ResourceManagerTests.cs @@ -306,7 +306,7 @@ public void RaiseChanged() } } - private class PublicResourceMock : ResourceMockBase, IPublicResource, IReferenceResource + private class PublicResourceMock : ResourceMockBase, IResource, IReferenceResource { public ICapabilities Capabilities { get; private set; } From 09a569fc193b91616b550d1db45faacf9d85db29 Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Fri, 25 Aug 2023 14:03:41 +0200 Subject: [PATCH 17/57] Remove ResourceWrapper Removed wrapper and state machine to reduce overhead per resource instance. Combined Initialize and Start of ResourceManager, pass resources from one step to the next. Split running and failed resources into two collections --- .../Resources/IManagedResourceGraph.cs | 6 +- .../Resources/ResourceGraph.cs | 16 +-- .../Resources/ResourceManager.cs | 136 +++++++++++------- .../Resources/ResourceWrapper.cs | 62 -------- .../States/CreatedState.cs | 25 ---- .../States/ErrorState.cs | 30 ---- .../States/InitializedState.cs | 25 ---- .../States/ResourceStateBase.cs | 87 ----------- .../States/StartedState.cs | 23 --- .../States/StoppedState.cs | 24 ---- .../ResourceLinkerTests.cs | 48 +++---- 11 files changed, 121 insertions(+), 361 deletions(-) delete mode 100644 src/Moryx.Resources.Management/Resources/ResourceWrapper.cs delete mode 100644 src/Moryx.Resources.Management/States/CreatedState.cs delete mode 100644 src/Moryx.Resources.Management/States/ErrorState.cs delete mode 100644 src/Moryx.Resources.Management/States/InitializedState.cs delete mode 100644 src/Moryx.Resources.Management/States/ResourceStateBase.cs delete mode 100644 src/Moryx.Resources.Management/States/StartedState.cs delete mode 100644 src/Moryx.Resources.Management/States/StoppedState.cs diff --git a/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs b/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs index b6c25a21a..9434643d2 100644 --- a/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs +++ b/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs @@ -15,7 +15,7 @@ internal interface IManagedResourceGraph : IResourceGraph /// /// Add a resource to the graph /// - ResourceWrapper Add(Resource instance); + Resource Add(Resource instance); /// /// Remove an instance from the graph @@ -25,12 +25,12 @@ internal interface IManagedResourceGraph : IResourceGraph /// /// Return the wrapper of a resource instance /// - ResourceWrapper GetWrapper(long id); + Resource GetWrapper(long id); /// /// Access the full graph /// - ICollection GetAll(); + ICollection GetAll(); /// /// TODO: Find a better way diff --git a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs index 9c8d6e701..bcc56cfe1 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs @@ -29,7 +29,7 @@ internal class ResourceGraph : IManagedResourceGraph /// /// All resources of the graph /// - private readonly IDictionary _graph = new Dictionary(); + private readonly IDictionary _graph = new Dictionary(); /// /// Quick access to all public resources @@ -40,10 +40,10 @@ internal class ResourceGraph : IManagedResourceGraph public Func DestroyDelegate { get; set; } - public ResourceWrapper Add(Resource instance) + public Resource Add(Resource instance) { _graphLock.EnterWriteLock(); - var wrapper = _graph[instance.Id] = new ResourceWrapper(instance); + var wrapper = _graph[instance.Id] = instance; if (instance is IResource publicResource) _publicResources.Add(publicResource); @@ -65,10 +65,10 @@ public bool Remove(Resource instance) public Resource Get(long id) { - return GetWrapper(id)?.Target; + return GetWrapper(id); } - public ResourceWrapper GetWrapper(long id) + public Resource GetWrapper(long id) { _graphLock.EnterReadLock(); var match = _graph.ContainsKey(id) ? _graph[id] : null; @@ -77,7 +77,7 @@ public ResourceWrapper GetWrapper(long id) return match; } - public ICollection GetAll() + public ICollection GetAll() { _graphLock.EnterReadLock(); var values = _graph.Values; @@ -123,11 +123,11 @@ public IEnumerable GetResources(Func pred // Use short cut if a public resource is requested if (typeof(IResource).IsAssignableFrom(typeof(TResource))) { - matches = _publicResources.Where(p => _graph[p.Id].State.IsAvailable).OfType().Where(predicate); + matches = _publicResources.Where(p => _graph[p.Id] is not null).OfType().Where(predicate); } else { - matches = from wrapper in _graph.Values let target = wrapper.Target as TResource + matches = from resource in _graph.Values let target = resource as TResource where target != null && predicate(target) select target; } _graphLock.ExitReadLock(); diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index 4b4465485..24c9dcb46 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Castle.Core.Resource; using Microsoft.Extensions.Logging; using Moryx.AbstractionLayer.Capabilities; using Moryx.AbstractionLayer.Resources; @@ -14,6 +15,7 @@ using Moryx.Modules; using Moryx.Resources.Model; using Moryx.Tools; +using IResource = Moryx.AbstractionLayer.Resources.IResource; namespace Moryx.Resources.Management { @@ -97,11 +99,20 @@ private enum ResourceStartupPhase /// private readonly object _fallbackLock = new(); + private List _failedResources = new(); + private List _runningResources = new(); + #endregion #region LifeCycle public void Initialize() + { + InitializeAndStart(); + } + + + private void InitializeAndStart() { // Set delegates on graph Graph.SaveDelegate = Save; @@ -113,26 +124,57 @@ public void Initialize() // Create all objects var allResources = ResourceEntityAccessor.FetchResourceTemplates(uow); if (allResources.Count > 0) - { LoadResources(allResources); - } } _startup = ResourceStartupPhase.Initializing; - // Boot resources - Parallel.ForEach(Graph.GetAll(), resourceWrapper => - { - try - { - resourceWrapper.Initialize(); - } - catch (Exception e) - { - resourceWrapper.ErrorOccured(); - Logger.Log(LogLevel.Warning, e, "Failed to initialize resource {0}-{1}", resourceWrapper.Target.Id, resourceWrapper.Target.Name); - } - }); + // initialize resources + Parallel.ForEach(Graph.GetAll(), InitializeResource); _startup = ResourceStartupPhase.Initialized; + + // start resources + _startup = ResourceStartupPhase.Starting; + Parallel.ForEach(Graph.GetAll(), StartResource); + _startup = ResourceStartupPhase.Started; + } + + private void ResourceFailed(Resource resource, Exception e) + { + //populate the failed resources list for tracking + lock (_failedResources) + { + if(_runningResources.Any(x => x.Id == resource.Id)) + _runningResources.Remove(resource); + + if(!_failedResources.Any(x => x.Id == resource.Id)) + _failedResources.Add(resource); + } + Logger.Log(LogLevel.Warning, e, "Failed to initialize resource {0}-{1}", resource.Id, resource.Name); + } + + private void InitializeResource(Resource resource) + { + try + { + ((IInitializable)resource).Initialize(); + } + catch (Exception e) + { + ResourceFailed(resource, e); + } + } + + private void StartResource(Resource resource) + { + try + { + ((IPlugin)resource).Start(); + ResourceStarted(resource); + } + catch (Exception e) + { + ResourceFailed(resource, e); + } } /// @@ -150,8 +192,21 @@ private void LoadResources(ICollection allResources) Parallel.ForEach(allResources, LinkReferences); // Register events after all links were set - foreach (var resourceWrapper in Graph.GetAll()) - RegisterEvents(resourceWrapper.Target); + foreach (var resource in Graph.GetAll()) + RegisterEvents(resource); + } + + private void ResourceStarted(IResource resource) + { + lock (_runningResources) + { + //check if the resource exist in failed resources + if (_failedResources.Any(x => x.Id == resource.Id)) + _failedResources.Remove(resource); + + if (!_runningResources.Any(x => x.Id == resource.Id)) + _runningResources.Add(resource); + } } /// @@ -160,7 +215,7 @@ private void LoadResources(ICollection allResources) private void AddResource(Resource instance, bool registerEvents) { // Add instance to the graph - var wrapped = Graph.Add(instance); + var resource = Graph.Add(instance); // Register to events if (registerEvents) @@ -174,12 +229,12 @@ private void AddResource(Resource instance, bool registerEvents) case ResourceStartupPhase.Initializing: case ResourceStartupPhase.Initialized: // Resources those are created during the initialize of a resource are automatically initialized also. - wrapped.Initialize(); + InitializeResource(resource); break; case ResourceStartupPhase.Starting: case ResourceStartupPhase.Started: // Resources those are created during the start of a resource are automatically initialized and started also. - InitializeAndStart(wrapped); + InitializeAndStart(resource); break; case ResourceStartupPhase.Stopping: case ResourceStartupPhase.Stopped: @@ -194,19 +249,12 @@ private void AddResource(Resource instance, bool registerEvents) RaiseResourceAdded(publicResource); } - private void InitializeAndStart(ResourceWrapper wrappedResource) + private void InitializeAndStart(Resource resource) { - wrappedResource.Initialize(); - try - { - wrappedResource.Start(); - } - catch (Exception ex) - { - Logger.Log(LogLevel.Warning, ex, "Could not start resource {0}-{1}!", wrappedResource.Target.Id, wrappedResource.Target.Name); - } + InitializeResource(resource); + StartResource(resource); } - + /// /// Register a resources events /// @@ -254,36 +302,23 @@ private void LinkReferences(ResourceEntityAccessor entityAccessor) public void Start() { - _startup = ResourceStartupPhase.Starting; - Parallel.ForEach(Graph.GetAll(), resourceWrapper => - { - try - { - resourceWrapper.Start(); - } - catch (Exception e) - { - resourceWrapper.ErrorOccured(); - Logger.Log(LogLevel.Warning, e, "Failed to start resource {0}-{1}", resourceWrapper.Target.Id, resourceWrapper.Target.Name); - } - }); - _startup = ResourceStartupPhase.Started; + InitializeAndStart(); } public void Stop() { _startup = ResourceStartupPhase.Stopping; - Parallel.ForEach(Graph.GetAll(), resourceWrapper => + Parallel.ForEach(Graph.GetAll(), resource => { try { - resourceWrapper.Stop(); - UnregisterEvents(resourceWrapper.Target); + ((IPlugin)resource).Stop(); + UnregisterEvents(resource); } catch (Exception e) { - Logger.Log(LogLevel.Warning, e, "Failed to stop resource {0}-{1}", resourceWrapper.Target.Id, resourceWrapper.Target.Name); + Logger.Log(LogLevel.Warning, e, "Failed to stop resource {0}-{1}", resource.Id, resource.Name); } }); @@ -441,8 +476,9 @@ private void RaiseResourceRemoved(IResource newResource) private void RaiseCapabilitiesChanged(object originalSender, ICapabilities capabilities) { + var availableResources = Graph.GetAll().Except(_failedResources); // Only forward events for available resources - if (Graph.GetWrapper(((IResource)originalSender).Id).State.IsAvailable) + if (availableResources.Any(x => x.Id == ((IResource)originalSender).Id)) CapabilitiesChanged?.Invoke(originalSender, capabilities); } diff --git a/src/Moryx.Resources.Management/Resources/ResourceWrapper.cs b/src/Moryx.Resources.Management/Resources/ResourceWrapper.cs deleted file mode 100644 index f319ffaf7..000000000 --- a/src/Moryx.Resources.Management/Resources/ResourceWrapper.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using Moryx.AbstractionLayer.Resources; -using Moryx.Modules; -using Moryx.StateMachines; - -namespace Moryx.Resources.Management -{ - internal sealed class ResourceWrapper : IStateContext - { - internal Resource Target { get; } - - internal ResourceStateBase State { get; private set; } - - void IStateContext.SetState(IState state) - { - State = (ResourceStateBase)state; - } - - internal ResourceWrapper(Resource target) - { - Target = target; - StateMachine.Initialize(this).With(); - } - - internal void Initialize() - { - State.Initialize(); - } - - internal void HandleInitialize() - { - ((IInitializable)Target).Initialize(); - } - - internal void Start() - { - State.Start(); - } - - internal void HandleStart() - { - ((IPlugin)Target).Start(); - } - - internal void ErrorOccured() - { - State.ErrorOccured(); - } - - internal void Stop() - { - State.Stop(); - } - - internal void HandleStop() - { - ((IPlugin)Target).Stop(); - } - } -} diff --git a/src/Moryx.Resources.Management/States/CreatedState.cs b/src/Moryx.Resources.Management/States/CreatedState.cs deleted file mode 100644 index ee7587076..000000000 --- a/src/Moryx.Resources.Management/States/CreatedState.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Resources.Management -{ - /// - /// State of a newly created - /// - internal class CreatedState : ResourceStateBase - { - /// - /// constructor - /// - public CreatedState(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - public override void Initialize() - { - Context.HandleInitialize(); - NextState(StateInitialized); - } - } -} diff --git a/src/Moryx.Resources.Management/States/ErrorState.cs b/src/Moryx.Resources.Management/States/ErrorState.cs deleted file mode 100644 index 5d050c697..000000000 --- a/src/Moryx.Resources.Management/States/ErrorState.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Resources.Management -{ - /// - /// State of a when an error occurred while acting on wrapped resource - /// - internal class ErrorState : ResourceStateBase - { - /// - /// constructor - /// - public ErrorState(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - public override void Initialize() - { - // Do nothing - } - - /// - public override void Start() - { - // Do nothing - } - } -} diff --git a/src/Moryx.Resources.Management/States/InitializedState.cs b/src/Moryx.Resources.Management/States/InitializedState.cs deleted file mode 100644 index 6ae605352..000000000 --- a/src/Moryx.Resources.Management/States/InitializedState.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Resources.Management -{ - /// - /// State of the when the wrappd resource was initialized - /// - internal class InitializedState : ResourceStateBase - { - /// - /// constructor - /// - public InitializedState(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - public override void Start() - { - Context.HandleStart(); - NextState(StateStarted); - } - } -} diff --git a/src/Moryx.Resources.Management/States/ResourceStateBase.cs b/src/Moryx.Resources.Management/States/ResourceStateBase.cs deleted file mode 100644 index 608c5eb56..000000000 --- a/src/Moryx.Resources.Management/States/ResourceStateBase.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using Moryx.StateMachines; - -namespace Moryx.Resources.Management -{ - /// - /// Base class for states of the - /// - internal abstract class ResourceStateBase : StateBase - { - /// - /// constructor - /// - protected ResourceStateBase(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - /// Flag if the resource is avaiable for external interaction - /// - public virtual bool IsAvailable => false; - - /// - /// Initialize the wrapped resource - /// - public virtual void Initialize() - { - InvalidState(); - } - - /// - /// Start the wrapped resource - /// - public virtual void Start() - { - InvalidState(); - } - /// - /// Handle an error and set the wrapped resource to the error state - /// - public virtual void ErrorOccured() - { - NextState(StateError); - } - - /// - /// Stop the wrapped resource - /// - public virtual void Stop() - { - Context.HandleStop(); - NextState(StateStopped); - } - - /// - /// The wrapped resource was created - /// - [StateDefinition(typeof(CreatedState), IsInitial = true)] - protected const int StateCreated = 0; - - /// - /// The wrapped resource was initialized - /// - [StateDefinition(typeof(InitializedState))] - protected const int StateInitialized = 10; - - /// - /// The wrapped resource was started - /// - [StateDefinition(typeof(StartedState))] - protected const int StateStarted = 20; - - /// - /// The wrapped resource was stopped - /// - [StateDefinition(typeof(StoppedState))] - protected const int StateStopped = 30; - - /// - /// An error occurred while performing an action on the wrapped resource. - /// - [StateDefinition(typeof(ErrorState))] - protected const int StateError = 40; - } -} diff --git a/src/Moryx.Resources.Management/States/StartedState.cs b/src/Moryx.Resources.Management/States/StartedState.cs deleted file mode 100644 index a0acf4d34..000000000 --- a/src/Moryx.Resources.Management/States/StartedState.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Resources.Management -{ - /// - /// State of the when the wrappd resource was started - /// - internal class StartedState : ResourceStateBase - { - /// - /// constructor - /// - public StartedState(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - /// Indicate that resource is available for interaction - /// - public override bool IsAvailable => true; - } -} diff --git a/src/Moryx.Resources.Management/States/StoppedState.cs b/src/Moryx.Resources.Management/States/StoppedState.cs deleted file mode 100644 index 0f99273d0..000000000 --- a/src/Moryx.Resources.Management/States/StoppedState.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -namespace Moryx.Resources.Management -{ - /// - /// State of the when the wrappd resource was stopped - /// - internal class StoppedState : ResourceStateBase - { - /// - /// constructor - /// - public StoppedState(ResourceWrapper context, StateMap stateMap) : base(context, stateMap) - { - } - - /// - public override void Initialize() - { - NextState(StateInitialized); - } - } -} diff --git a/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs b/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs index 81e026397..41b269427 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs @@ -20,13 +20,13 @@ public class ResourceLinkerTests { private ResourceLinker _linker; - private readonly Dictionary _graph = new Dictionary(); + private readonly Dictionary _graph = new Dictionary(); [OneTimeSetUp] public void PrepareLinker() { var mock = new Mock(); - mock.Setup(g => g.Get(It.IsAny())).Returns(id => _graph.ContainsKey(id) ? _graph[id].Target : null); + mock.Setup(g => g.Get(It.IsAny())).Returns(id => _graph.ContainsKey(id) ? _graph[id] : null); _linker = new ResourceLinker { @@ -83,12 +83,12 @@ public void LinkResource() { // Arrange var instance = new ReferenceResource { Id = 1 }; - _graph[1] = new ResourceWrapper(instance); - _graph[2] = new ResourceWrapper(new SimpleResource { Id = 2, Name = "Ref1" }); - _graph[3] = new ResourceWrapper(new SimpleResource { Id = 3, Name = "Pos1" }); - _graph[4] = new ResourceWrapper(new DerivedResource { Id = 4, Name = "Ref2" }); - _graph[5] = new ResourceWrapper(new DerivedResource { Id = 5, Name = "ChildOnly" }); - _graph[6] = new ResourceWrapper(new DerivedResource { Id = 6, Name = "BackRef" }); + _graph[1] = instance; + _graph[2] = new SimpleResource { Id = 2, Name = "Ref1" }; + _graph[3] = new SimpleResource { Id = 3, Name = "Pos1" }; + _graph[4] = new DerivedResource { Id = 4, Name = "Ref2" }; + _graph[5] = new DerivedResource { Id = 5, Name = "ChildOnly" }; + _graph[6] = new DerivedResource { Id = 6, Name = "BackRef" }; var relations = new List { // All Parent-Child relations @@ -142,11 +142,11 @@ public void SaveReferences() var ref5 = new DerivedResource { Id = 6, Name = "BackRef" }; ResourceReferenceTools.InitializeCollections(ref5); // Fill graph - _graph[1] = new ResourceWrapper(instance); - _graph[2] = new ResourceWrapper(ref1); - _graph[3] = new ResourceWrapper(ref2); - _graph[5] = new ResourceWrapper(ref4); - _graph[6] = new ResourceWrapper(ref5); + _graph[1] = instance; + _graph[2] = ref1; + _graph[3] = ref2; + _graph[5] = ref4; + _graph[6] = ref5; // Set single references instance.Parent = ref5; // Parent is set and // ref5.Children.Add(instance); Bidirectional reference synced --> no longer necessary @@ -211,10 +211,10 @@ public void ReferenceInterferenceOnSave() var other = new OtherResource { Id = 3, Name = "Ref2" }; var different = new DifferentResource { Id = 4, Name = "Different" }; // Fill graph - _graph[1] = new ResourceWrapper(instance); - _graph[2] = new ResourceWrapper(derived); - _graph[3] = new ResourceWrapper(other); - _graph[4] = new ResourceWrapper(different); + _graph[1] = instance; + _graph[2] = derived; + _graph[3] = other; + _graph[4] = different; // Set references instance.Derived = derived; instance.Others.Add(other); @@ -267,8 +267,8 @@ public void SetParentWhenAddingChild() ResourceReferenceTools.InitializeCollections(child); var mocks = SetupDbMocks(new List()); // Setup graph mock - _graph[1] = new ResourceWrapper(parent); - _graph[2] = new ResourceWrapper(child); + _graph[1] = parent; + _graph[2] = child; // Act parent.Children.Add(child); @@ -297,8 +297,8 @@ public void ClearParentWhenRemovingChild() }; var mocks = SetupDbMocks(relations); // Setup graph mock - _graph[1] = new ResourceWrapper(parent); - _graph[2] = new ResourceWrapper(child); + _graph[1] = parent; + _graph[2] = child; // Act parent.Children.Remove(child); @@ -329,9 +329,9 @@ public void SyncChildrenOnParentModification() }; var mocks = SetupDbMocks(relations); // Setup graph mock - _graph[1] = new ResourceWrapper(parent1); - _graph[2] = new ResourceWrapper(parent2); - _graph[3] = new ResourceWrapper(child); + _graph[1] = parent1; + _graph[2] = parent2; + _graph[3] = child; // Act child.Parent = parent2; From 6a856490a0f9ce973ac094ddd4dcf32ff1795a45 Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Fri, 25 Aug 2023 14:13:00 +0200 Subject: [PATCH 18/57] Updated ResourceManager --- .../Resources/ResourceManager.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index 24c9dcb46..cbde98578 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -131,11 +131,6 @@ private void InitializeAndStart() // initialize resources Parallel.ForEach(Graph.GetAll(), InitializeResource); _startup = ResourceStartupPhase.Initialized; - - // start resources - _startup = ResourceStartupPhase.Starting; - Parallel.ForEach(Graph.GetAll(), StartResource); - _startup = ResourceStartupPhase.Started; } private void ResourceFailed(Resource resource, Exception e) @@ -302,7 +297,10 @@ private void LinkReferences(ResourceEntityAccessor entityAccessor) public void Start() { - InitializeAndStart(); + // start resources + _startup = ResourceStartupPhase.Starting; + Parallel.ForEach(Graph.GetAll(), StartResource); + _startup = ResourceStartupPhase.Started; } public void Stop() From 4283de8a0a0cdba36913611e382bd982512f870f Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Fri, 25 Aug 2023 14:29:03 +0200 Subject: [PATCH 19/57] Added public api for InitializeAndStart --- .../Resources/IResourceManager.cs | 6 +++ .../Resources/ResourceManager.cs | 48 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/Moryx.Resources.Management/Resources/IResourceManager.cs b/src/Moryx.Resources.Management/Resources/IResourceManager.cs index dc2009cc0..b61ff1769 100644 --- a/src/Moryx.Resources.Management/Resources/IResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/IResourceManager.cs @@ -31,5 +31,11 @@ internal interface IResourceManager : IInitializablePlugin /// Raised when the capabilities have changed. /// event EventHandler CapabilitiesChanged; + + + /// + /// Initialize and start all the resources available + /// + void InitializeAndStart(); } } diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index cbde98578..e35206961 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -107,12 +107,6 @@ private enum ResourceStartupPhase #region LifeCycle public void Initialize() - { - InitializeAndStart(); - } - - - private void InitializeAndStart() { // Set delegates on graph Graph.SaveDelegate = Save; @@ -133,7 +127,20 @@ private void InitializeAndStart() _startup = ResourceStartupPhase.Initialized; } - private void ResourceFailed(Resource resource, Exception e) + + public void InitializeAndStart() + { + Initialize(); + Start(); + } + + /// + /// Handles the failed resource by adding it to the list of failed resources + /// + /// Failed resource + /// Exception that cause this resource to fail + /// Resource failed during Initialization. default true + private void HandleResourceFailed(Resource resource, Exception e, bool failedDuringInitialization = true) { //populate the failed resources list for tracking lock (_failedResources) @@ -144,9 +151,14 @@ private void ResourceFailed(Resource resource, Exception e) if(!_failedResources.Any(x => x.Id == resource.Id)) _failedResources.Add(resource); } - Logger.Log(LogLevel.Warning, e, "Failed to initialize resource {0}-{1}", resource.Id, resource.Name); + var label = failedDuringInitialization == true ? "initialize":"start"; + Logger.Log(LogLevel.Warning, e, "Failed to {0} resource {1}-{2}", label, resource.Id, resource.Name); } + /// + /// Handles the initialization of the resource + /// + /// private void InitializeResource(Resource resource) { try @@ -155,20 +167,24 @@ private void InitializeResource(Resource resource) } catch (Exception e) { - ResourceFailed(resource, e); + HandleResourceFailed(resource, e); } } + /// + /// Starts a resource and handles in case of failure. + /// + /// private void StartResource(Resource resource) { try { ((IPlugin)resource).Start(); - ResourceStarted(resource); + HandleResourceStarted(resource); } catch (Exception e) { - ResourceFailed(resource, e); + HandleResourceFailed(resource, e,false); } } @@ -191,7 +207,11 @@ private void LoadResources(ICollection allResources) RegisterEvents(resource); } - private void ResourceStarted(IResource resource) + /// + /// Handles the resource started by adding it to the list of running resources and removes it from failed resources + /// + /// Started resource + private void HandleResourceStarted(IResource resource) { lock (_runningResources) { @@ -244,6 +264,10 @@ private void AddResource(Resource instance, bool registerEvents) RaiseResourceAdded(publicResource); } + /// + /// Initialize and start the current resource + /// + /// Current resource private void InitializeAndStart(Resource resource) { InitializeResource(resource); From a35030b05d806b1ddd26aaf60941ef8351788877 Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Mon, 28 Aug 2023 12:56:40 +0200 Subject: [PATCH 20/57] Removed duplicated collection. Forwarded Capabilities event and extended existing test in TypeControllerTest for event forwarding in the proxy. --- .../Resources/IManagedResourceGraph.cs | 4 +- .../Resources/IResourceManager.cs | 6 --- .../Resources/ResourceGraph.cs | 22 +-------- .../Resources/ResourceManager.cs | 46 ++++++------------- .../Resources/ResourceProxy.cs | 6 ++- .../Mocks/SimpleResource.cs | 5 ++ .../TypeControllerTests.cs | 15 +++++- 7 files changed, 43 insertions(+), 61 deletions(-) diff --git a/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs b/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs index 9434643d2..e041f2ed4 100644 --- a/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs +++ b/src/Moryx.Resources.Management/Resources/IManagedResourceGraph.cs @@ -23,9 +23,9 @@ internal interface IManagedResourceGraph : IResourceGraph bool Remove(Resource instance); /// - /// Return the wrapper of a resource instance + /// Return the resource instance /// - Resource GetWrapper(long id); + Resource GetResource(long id); /// /// Access the full graph diff --git a/src/Moryx.Resources.Management/Resources/IResourceManager.cs b/src/Moryx.Resources.Management/Resources/IResourceManager.cs index b61ff1769..dc2009cc0 100644 --- a/src/Moryx.Resources.Management/Resources/IResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/IResourceManager.cs @@ -31,11 +31,5 @@ internal interface IResourceManager : IInitializablePlugin /// Raised when the capabilities have changed. /// event EventHandler CapabilitiesChanged; - - - /// - /// Initialize and start all the resources available - /// - void InitializeAndStart(); } } diff --git a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs index bcc56cfe1..300b5ccf9 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceGraph.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceGraph.cs @@ -31,11 +31,6 @@ internal class ResourceGraph : IManagedResourceGraph /// private readonly IDictionary _graph = new Dictionary(); - /// - /// Quick access to all public resources - /// - private readonly IList _publicResources = new List(); - public Action SaveDelegate { get; set; } public Func DestroyDelegate { get; set; } @@ -44,9 +39,6 @@ public Resource Add(Resource instance) { _graphLock.EnterWriteLock(); var wrapper = _graph[instance.Id] = instance; - - if (instance is IResource publicResource) - _publicResources.Add(publicResource); _graphLock.ExitWriteLock(); return wrapper; @@ -56,8 +48,6 @@ public bool Remove(Resource instance) { _graphLock.EnterWriteLock(); var found = _graph.Remove(instance.Id); - if (found) - _publicResources.Remove(instance as IResource); _graphLock.ExitWriteLock(); return found; @@ -65,10 +55,10 @@ public bool Remove(Resource instance) public Resource Get(long id) { - return GetWrapper(id); + return GetResource(id); } - public Resource GetWrapper(long id) + public Resource GetResource(long id) { _graphLock.EnterReadLock(); var match = _graph.ContainsKey(id) ? _graph[id] : null; @@ -120,16 +110,8 @@ public IEnumerable GetResources(Func pred { IEnumerable matches; _graphLock.EnterReadLock(); - // Use short cut if a public resource is requested - if (typeof(IResource).IsAssignableFrom(typeof(TResource))) - { - matches = _publicResources.Where(p => _graph[p.Id] is not null).OfType().Where(predicate); - } - else - { matches = from resource in _graph.Values let target = resource as TResource where target != null && predicate(target) select target; - } _graphLock.ExitReadLock(); return matches; diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index e35206961..6be713ea1 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -100,7 +100,6 @@ private enum ResourceStartupPhase private readonly object _fallbackLock = new(); private List _failedResources = new(); - private List _runningResources = new(); #endregion @@ -123,17 +122,14 @@ public void Initialize() _startup = ResourceStartupPhase.Initializing; // initialize resources - Parallel.ForEach(Graph.GetAll(), InitializeResource); + var availableResources = Graph + .GetAll() + .Except(_failedResources) + .Select(x => x as Resource); + Parallel.ForEach(availableResources, InitializeResource); _startup = ResourceStartupPhase.Initialized; } - - public void InitializeAndStart() - { - Initialize(); - Start(); - } - /// /// Handles the failed resource by adding it to the list of failed resources /// @@ -145,10 +141,7 @@ private void HandleResourceFailed(Resource resource, Exception e, bool failedDur //populate the failed resources list for tracking lock (_failedResources) { - if(_runningResources.Any(x => x.Id == resource.Id)) - _runningResources.Remove(resource); - - if(!_failedResources.Any(x => x.Id == resource.Id)) + if(_failedResources.FirstOrDefault(x => x.Id == resource.Id) is null) _failedResources.Add(resource); } var label = failedDuringInitialization == true ? "initialize":"start"; @@ -213,14 +206,11 @@ private void LoadResources(ICollection allResources) /// Started resource private void HandleResourceStarted(IResource resource) { - lock (_runningResources) + lock (_failedResources) { //check if the resource exist in failed resources - if (_failedResources.Any(x => x.Id == resource.Id)) + if (_failedResources.FirstOrDefault(x => x.Id == resource.Id) is not null) _failedResources.Remove(resource); - - if (!_runningResources.Any(x => x.Id == resource.Id)) - _runningResources.Add(resource); } } @@ -259,9 +249,7 @@ private void AddResource(Resource instance, bool registerEvents) throw new ArgumentOutOfRangeException(); } - // Inform listeners about the new resource - if (instance is IResource publicResource) - RaiseResourceAdded(publicResource); + RaiseResourceAdded(resource); } /// @@ -280,9 +268,7 @@ private void InitializeAndStart(Resource resource) private void RegisterEvents(Resource instance) { instance.Changed += OnResourceChanged; - - if (instance is IResource asPublic) - asPublic.CapabilitiesChanged += RaiseCapabilitiesChanged; + instance.CapabilitiesChanged += RaiseCapabilitiesChanged; foreach (var autoSaveCollection in ResourceReferenceTools.GetAutoSaveCollections(instance)) autoSaveCollection.CollectionChanged += OnAutoSaveCollectionChanged; @@ -294,9 +280,7 @@ private void RegisterEvents(Resource instance) private void UnregisterEvents(Resource instance) { instance.Changed -= OnResourceChanged; - - if (instance is IResource asPublic) - asPublic.CapabilitiesChanged -= RaiseCapabilitiesChanged; + instance.CapabilitiesChanged -= RaiseCapabilitiesChanged; foreach (var autoSaveCollection in ResourceReferenceTools.GetAutoSaveCollections(instance)) autoSaveCollection.CollectionChanged -= OnAutoSaveCollectionChanged; @@ -351,7 +335,7 @@ public void Stop() public void Save(Resource resource) { - lock (Graph.GetWrapper(resource.Id) ?? _fallbackLock) + lock (Graph.GetResource(resource.Id) ?? _fallbackLock) { using var uow = UowFactory.Create(); var newResources = new HashSet(); @@ -396,7 +380,7 @@ private void OnAutoSaveCollectionChanged(object sender, ReferenceCollectionChang var instance = args.Parent; var property = args.CollectionProperty; - lock (Graph.GetWrapper(instance.Id)) // Unlike Save AutoSave collections are ALWAYS part of the Graph + lock (Graph.GetResource(instance.Id)) // Unlike Save AutoSave collections are ALWAYS part of the Graph { using var uow = UowFactory.Create(); var newResources = ResourceLinker.SaveSingleCollection(uow, instance, property); @@ -467,8 +451,8 @@ public bool Destroy(IResource resource, bool permanent) var removed = Graph.Remove(instance); // Notify listeners about the removal of the resource - if (removed && instance is IResource publicResource) - RaiseResourceRemoved(publicResource); + if (removed) + RaiseResourceRemoved(instance); // Destroy the object TypeController.Destroy(instance); diff --git a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs index be628fcca..7fc863e89 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs @@ -19,7 +19,11 @@ internal abstract class ResourceProxy : IResource /// private IResourceTypeController _typeController; - public event EventHandler CapabilitiesChanged; + public event EventHandler CapabilitiesChanged + { + add { Target.CapabilitiesChanged += value; } + remove { Target.CapabilitiesChanged -= value; } + } /// /// Target resource of the proxy diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs index 0624d3162..c398803d9 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/SimpleResource.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0 using System; +using Moryx.AbstractionLayer.Capabilities; using Moryx.AbstractionLayer.Resources; namespace Moryx.Resources.Management.Tests @@ -69,6 +70,10 @@ public void RaiseEvent() SomeEvent?.Invoke(this, EventArgs.Empty); } + public void UpdateCapabilities(ICapabilities capabilities) + { + Capabilities = capabilities; + } public void Validate() { } diff --git a/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs b/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs index 58fbee6ee..9de8553d9 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs @@ -8,6 +8,7 @@ using Moryx.Container; using Moq; using NUnit.Framework; +using Moryx.AbstractionLayer.Capabilities; namespace Moryx.Resources.Management.Tests { @@ -147,8 +148,9 @@ public void ForwardEventsFromProxy() var proxy = (ISimpleResource) _typeController.GetProxy(instance); // Act: Register listener and change foo - object eventSender = null, eventSender2 = null; + object eventSender = null, eventSender2 = null, eventSender3 = null; int eventValue = 0; + ICapabilities capabilitiesValue = null; var finallyEven = false; Assert.DoesNotThrow(() => instance.Foo = 10); EventHandler eventHandler = (sender, foo) => @@ -156,18 +158,29 @@ public void ForwardEventsFromProxy() eventSender = sender; eventValue = foo; }; + EventHandler eventHandler2 = (sender, capabilities) => + { + eventSender3 = sender; + capabilitiesValue = capabilities; + }; + proxy.FooChanged += eventHandler; proxy.FooEven += (sender, b) => finallyEven = b; proxy.SomeEvent += (sender, args) => eventSender2 = sender; + proxy.CapabilitiesChanged += eventHandler2; instance.Foo = 100; instance.RaiseEvent(); + instance.UpdateCapabilities(NullCapabilities.Instance); proxy.FooChanged -= eventHandler; + proxy.CapabilitiesChanged -= eventHandler2; // Assert: Check if eventSender is not null and equals the proxy Assert.NotNull(eventSender); Assert.NotNull(eventSender2); + Assert.NotNull(eventSender3); Assert.AreNotEqual(0, eventValue); Assert.AreEqual(proxy, eventSender); + Assert.AreEqual(NullCapabilities.Instance, capabilitiesValue); Assert.AreEqual(100, eventValue); Assert.IsTrue(finallyEven); } From ceb88627269cdc3c93149d7eb879ff520a42d75a Mon Sep 17 00:00:00 2001 From: Milad Katebi Date: Fri, 24 Feb 2023 14:21:47 +0100 Subject: [PATCH 21/57] Erase Sqlite Database --- src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs | 5 +---- src/Tests/Moryx.Model.Tests/SqliteTests.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs b/src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs index c58362563..b49b7e87e 100644 --- a/src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs +++ b/src/Moryx.Model.Sqlite/SqliteModelConfigurator.cs @@ -2,15 +2,12 @@ // Licensed under the Apache License, Version 2.0 using System; -using System.Collections.Generic; using System.Data.Common; using System.IO; -using System.Linq; using System.Threading.Tasks; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Moryx.Model.Configuration; -using Moryx.Tools; using Moryx.Model.Sqlite.Attributes; namespace Moryx.Model.Sqlite @@ -41,7 +38,7 @@ protected override DbCommand CreateCommand(string cmdText, DbConnection connecti /// public override Task DeleteDatabase(IDatabaseConfig config) { - SqliteConnection.ClearAllPools(); + SqliteConnection.ClearAllPools(); var dbFilePath = GetFilePath(config); if (File.Exists(dbFilePath)) diff --git a/src/Tests/Moryx.Model.Tests/SqliteTests.cs b/src/Tests/Moryx.Model.Tests/SqliteTests.cs index 335237e51..4309b919d 100644 --- a/src/Tests/Moryx.Model.Tests/SqliteTests.cs +++ b/src/Tests/Moryx.Model.Tests/SqliteTests.cs @@ -8,7 +8,7 @@ namespace Moryx.Model.Tests { [TestFixture] - public class SqliteTests + public class SqliteTests { private SqliteDatabaseConfig dbConfig; private SqliteModelConfigurator configurator; @@ -30,7 +30,7 @@ public void Setup() public async Task SqliteCreateDatabaseShouldWork() { var result = await configurator.TestConnection(dbConfig); - Assert.AreEqual(TestConnectionResult.ConnectionOkDbDoesNotExist,result); + Assert.AreEqual(TestConnectionResult.ConnectionOkDbDoesNotExist, result); bool isCreated = await configurator.CreateDatabase(dbConfig); @@ -46,7 +46,7 @@ public async Task SqliteCreateDatabaseShouldWork() public async Task SqliteDeleteDatabaseShouldWork() { var connectionResult = await configurator.TestConnection(dbConfig); - Assert.AreEqual(TestConnectionResult.ConnectionOkDbDoesNotExist,connectionResult); + Assert.AreEqual(TestConnectionResult.ConnectionOkDbDoesNotExist, connectionResult); bool isCreated = await configurator.CreateDatabase(dbConfig); Assert.IsTrue(isCreated); @@ -67,10 +67,10 @@ private static ConfigManager CreateConfigManager() [TearDown] public void Destroy() { - if(File.Exists(datasource)) - //remove the database - configurator.DeleteDatabase(dbConfig).Wait(); + if (File.Exists(datasource)) + //remove the database + configurator.DeleteDatabase(dbConfig).Wait(); } } -} +} \ No newline at end of file From 0bef393379a3f7e002afc3410e83bcb4ea30b157 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Wed, 30 Aug 2023 12:12:48 +0200 Subject: [PATCH 22/57] Migrate LoadComponents fix to future --- .../ContainerLoadComponentsExtension.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Moryx/Container/ContainerLoadComponentsExtension.cs b/src/Moryx/Container/ContainerLoadComponentsExtension.cs index b4c37c155..50586ecbe 100644 --- a/src/Moryx/Container/ContainerLoadComponentsExtension.cs +++ b/src/Moryx/Container/ContainerLoadComponentsExtension.cs @@ -15,8 +15,6 @@ namespace Moryx.Container /// public static class ContainerLoadComponentsExtension { - private static Type[] _knownTypes; - /// /// Load all types from an assembly /// @@ -90,15 +88,7 @@ public static void LoadComponents(this IContainer container) where T : class /// public static IContainer LoadComponents(this IContainer container, Predicate condition) where T : class { - if (_knownTypes == null) - { - _knownTypes = ReflectionTool.GetAssemblies() - .Where(a => a.GetCustomAttribute() == null) - .SelectMany(a => a.GetTypes()) - .Where(t => t.GetCustomAttribute(true) != null).ToArray(); - } - - foreach (var type in _knownTypes.Where(type => typeof(T).IsAssignableFrom(type))) + foreach (var type in ReflectionTool.GetPublicClasses(LoadComponentCandidate)) { if (condition?.Invoke(type) ?? true) { @@ -110,6 +100,17 @@ public static IContainer LoadComponents(this IContainer container, Predicate< return container; } + + private static bool LoadComponentCandidate(Type type) + { + if (type.Assembly.GetCustomAttribute() != null) + return false; + + if (type.GetCustomAttribute(true) == null) + return false; + + return true; + } private static void RegisterAdditionalDependencies(IContainer container, Type implementation) { From b4fea9a5e74cf1fce5d4c1ab104ec16bad8cb982 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Tue, 22 Aug 2023 11:51:19 +0200 Subject: [PATCH 23/57] Reduce module bases into single class --- src/Moryx.Runtime/Modules/ServerModuleBase.cs | 82 +++++++++++-- .../ServerModuleFacadeControllerBase.cs | 109 ------------------ 2 files changed, 74 insertions(+), 117 deletions(-) delete mode 100644 src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs diff --git a/src/Moryx.Runtime/Modules/ServerModuleBase.cs b/src/Moryx.Runtime/Modules/ServerModuleBase.cs index a96092980..69f1bf98c 100644 --- a/src/Moryx.Runtime/Modules/ServerModuleBase.cs +++ b/src/Moryx.Runtime/Modules/ServerModuleBase.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using System.Reflection; using System.Threading; using Microsoft.Extensions.Logging; using Moryx.Configuration; @@ -26,6 +28,11 @@ public abstract class ServerModuleBase : IServerModule, IServerModuleStat /// public abstract string Name { get; } + /// + /// All facades that were activated + /// + private readonly ICollection _activeFacades = new List(); + /// /// Logger of this module. /// @@ -126,14 +133,10 @@ void IServerModuleStateContext.Start() void IServerModuleStateContext.Started() { - OnStarted(); - } - - /// - /// Called when module has been started - /// - protected internal virtual void OnStarted() - { + foreach (var facade in _activeFacades.OfType()) + { + facade.Activated(); + } } void IServerModule.Stop() @@ -165,6 +168,69 @@ void IServerModuleStateContext.Destruct() #endregion + #region Facade + + /// + /// Activate our public API facade and link all dependencies into the local container + /// + protected void ActivateFacade(IFacadeControl facade) + { + // First activation + facade.ValidateHealthState = ValidateHealthState; + + FillProperties(facade, FillProperty); + facade.Activate(); + + _activeFacades.Add(facade); + } + + /// + /// Deactivate our public facade and remove all references into the container + /// + protected void DeactivateFacade(IFacadeControl facade) + { + if (!_activeFacades.Remove(facade)) + return; + + facade.Deactivate(); + FillProperties(facade, (a, b) => null); + + var lifeCycleBoundFacade = facade as ILifeCycleBoundFacade; + lifeCycleBoundFacade?.Deactivated(); + } + + + private void FillProperties(object instance, Func fillingFunc) + { + // Fill everything available in the container + foreach (var prop in instance.GetType().GetProperties()) + { + var type = prop.PropertyType; + type = typeof(Array).IsAssignableFrom(type) ? type.GetElementType() : type; + var implementations = Container.GetRegisteredImplementations(type); + if (!implementations.Any()) + continue; + + if (prop.SetMethod == null) + continue; + + prop.SetValue(instance, fillingFunc(Container, prop)); + } + } + + private object FillProperty(IContainer container, PropertyInfo property) + { + var propType = property.PropertyType; + if (typeof(Array).IsAssignableFrom(propType)) + return container.ResolveAll(propType.GetElementType()); + + var strategyName = Strategies.ContainsKey(propType) ? Strategies[propType] : null; + return strategyName == null ? Container.Resolve(propType) + : Container.Resolve(propType, strategyName); + } + + #endregion + #region Container /// diff --git a/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs b/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs deleted file mode 100644 index f8870aec2..000000000 --- a/src/Moryx.Runtime/Modules/ServerModuleFacadeControllerBase.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG -// Licensed under the Apache License, Version 2.0 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Microsoft.Extensions.Logging; -using Moryx.Configuration; -using Moryx.Container; - -namespace Moryx.Runtime.Modules -{ - /// - /// Base class for the facade contoller. - /// - /// Configuration type of the server module. - public abstract class ServerModuleFacadeControllerBase : ServerModuleBase - where TConf : class, IConfig, new() - { - /// - /// All facades that were activated - /// - private readonly ICollection _activeFacades = new List(); - - protected ServerModuleFacadeControllerBase(IModuleContainerFactory containerFactory, IConfigManager configManager, ILoggerFactory loggerFactory) - : base(containerFactory, configManager, loggerFactory) - { - } - - /// - /// Activate our public API facade - /// - protected void ActivateFacade(IFacadeControl facade) - { - // First activation - facade.ValidateHealthState = ValidateHealthState; - - FillProperties(facade, FillProperty); - facade.Activate(); - - _activeFacades.Add(facade); - } - - /// - /// Deactivate our public facade - /// - protected void DeactivateFacade(IFacadeControl facade) - { - if (!_activeFacades.Contains(facade)) - return; - - facade.Deactivate(); - FillProperties(facade, (a, b) => null); - - _activeFacades.Remove(facade); - - var lifeCycleBoundFacade = facade as ILifeCycleBoundFacade; - lifeCycleBoundFacade?.Deactivated(); - } - - - /// - protected internal sealed override void OnStarted() - { - base.OnStarted(); - - foreach (var facade in _activeFacades.OfType()) - { - facade.Activated(); - } - } - - private void FillProperties(object instance, Func fillingFunc) - { - // Fill everythin available in the container - foreach (var prop in instance.GetType().GetProperties()) - { - var type = prop.PropertyType; - type = typeof(Array).IsAssignableFrom(type) ? type.GetElementType() : type; - var implementations = Container.GetRegisteredImplementations(type); - if (!implementations.Any()) - continue; - - if (prop.SetMethod == null) - continue; - - prop.SetValue(instance, fillingFunc(Container, prop)); - } - } - - private object FillProperty(IContainer container, PropertyInfo property) - { - var propType = property.PropertyType; - if (typeof(Array).IsAssignableFrom(propType)) - return container.ResolveAll(propType.GetElementType()); - - var strategyName = StrategyName(propType); - return strategyName == null ? Container.Resolve(propType) - : Container.Resolve(propType, strategyName); - } - - private string StrategyName(Type dependencyType) - { - var config = Strategies; - return config.ContainsKey(dependencyType) ? config[dependencyType] : null; - } - } -} From 7464d9569b79974e426bf1374b819266fe748f6f Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Tue, 22 Aug 2023 11:51:40 +0200 Subject: [PATCH 24/57] Change facade module base in affacted modules --- .../ModuleController/ModuleController.cs | 2 +- .../ModuleController/ModuleController.cs | 2 +- .../ModuleController/ModuleController.cs | 2 +- src/Moryx.TestModule/ModuleController/ModuleController.cs | 2 +- .../ModuleMocks/LifeCycleBoundFacadeTestModule.cs | 2 +- .../Moryx.Runtime.Kernel.Tests/ModuleMocks/ServerModuleA.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Moryx.DependentTestModule/ModuleController/ModuleController.cs b/src/Moryx.DependentTestModule/ModuleController/ModuleController.cs index 940f3415b..40400f4bb 100644 --- a/src/Moryx.DependentTestModule/ModuleController/ModuleController.cs +++ b/src/Moryx.DependentTestModule/ModuleController/ModuleController.cs @@ -12,7 +12,7 @@ namespace Moryx.DependentTestModule { [Description("Test module for System tests")] - public class ModuleController : ServerModuleFacadeControllerBase, IFacadeContainer + public class ModuleController : ServerModuleBase, IFacadeContainer { /// /// Name of this module diff --git a/src/Moryx.Products.Management/ModuleController/ModuleController.cs b/src/Moryx.Products.Management/ModuleController/ModuleController.cs index 83f5d8ab9..db0e8c1ab 100644 --- a/src/Moryx.Products.Management/ModuleController/ModuleController.cs +++ b/src/Moryx.Products.Management/ModuleController/ModuleController.cs @@ -14,7 +14,7 @@ namespace Moryx.Products.Management /// /// The main controller of all product modules. /// - public class ModuleController : ServerModuleFacadeControllerBase, + public class ModuleController : ServerModuleBase, IFacadeContainer, IFacadeContainer { diff --git a/src/Moryx.Resources.Management/ModuleController/ModuleController.cs b/src/Moryx.Resources.Management/ModuleController/ModuleController.cs index cbdb687bd..0a3611d23 100644 --- a/src/Moryx.Resources.Management/ModuleController/ModuleController.cs +++ b/src/Moryx.Resources.Management/ModuleController/ModuleController.cs @@ -16,7 +16,7 @@ namespace Moryx.Resources.Management /// /// The main controller of all resource modules. /// - public class ModuleController : ServerModuleFacadeControllerBase, + public class ModuleController : ServerModuleBase, IFacadeContainer, IFacadeContainer, IFacadeContainer diff --git a/src/Moryx.TestModule/ModuleController/ModuleController.cs b/src/Moryx.TestModule/ModuleController/ModuleController.cs index ce8ae334b..1077405ba 100644 --- a/src/Moryx.TestModule/ModuleController/ModuleController.cs +++ b/src/Moryx.TestModule/ModuleController/ModuleController.cs @@ -13,7 +13,7 @@ namespace Moryx.TestModule { [Description("Test module for System tests")] - public class ModuleController : ServerModuleFacadeControllerBase, IFacadeContainer + public class ModuleController : ServerModuleBase, IFacadeContainer { /// /// Db context factory for data models diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/LifeCycleBoundFacadeTestModule.cs b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/LifeCycleBoundFacadeTestModule.cs index 8ee4d51d2..3d7f69fcc 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/LifeCycleBoundFacadeTestModule.cs +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/LifeCycleBoundFacadeTestModule.cs @@ -10,7 +10,7 @@ namespace Moryx.Runtime.Kernel.Tests.ModuleMocks { - public class LifeCycleBoundFacadeTestModule : ServerModuleFacadeControllerBase + public class LifeCycleBoundFacadeTestModule : ServerModuleBase { public override string Name => "LifeCycleBoundTestModule"; diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ServerModuleA.cs b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ServerModuleA.cs index d887de84c..296aa5a41 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ServerModuleA.cs +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleMocks/ServerModuleA.cs @@ -10,7 +10,7 @@ namespace Moryx.Runtime.Kernel.Tests.ModuleMocks { - public class ServerModuleA : ServerModuleFacadeControllerBase, IFacadeContainer + public class ServerModuleA : ServerModuleBase, IFacadeContainer { public ServerModuleA(IModuleContainerFactory containerFactory, IConfigManager configManager, ILoggerFactory loggerFactory) : base(containerFactory, configManager, loggerFactory) From 1f80f537c17d6e1ab998d2d1bea21f9083a484be Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Tue, 22 Aug 2023 11:53:06 +0200 Subject: [PATCH 25/57] Add migration --- docs/migrations/v6_to_v8.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/migrations/v6_to_v8.md b/docs/migrations/v6_to_v8.md index f8a306ebb..56a988787 100644 --- a/docs/migrations/v6_to_v8.md +++ b/docs/migrations/v6_to_v8.md @@ -10,4 +10,8 @@ The DI container within modules based on Castle Windsor was refactored and simpl - **IContainerHost** was removed. The seperate interface for accessing a modules container just caused unnecessary casts and the risk of invalid type. The property `Container` was added to `IServerModule` instead. - **Extend** The flexible method for passing facilities to Castle was removed as it was only added and used by WCF. - **MoryxFacility** All MORYX specific behavior like strategies and `Named` import overrides were refactored to follow Castle best practises and are now isolated in the `MoryxFacility`. This enables everyone to achieve the MORYX DI behavior with a Castle Container without the MORYX wrapper. -- **Installers** As previously mentioned installers were removed, but since the API on `IContainer` now supports everything previously reserved for installers and registrators, just migrate the registration onto the container like the [DbContextContainerExtension](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.Model/DbContextContainerExtension.cs) or the [BasicInterceptorInstaller](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs) \ No newline at end of file +- **Installers** As previously mentioned installers were removed, but since the API on `IContainer` now supports everything previously reserved for installers and registrators, just migrate the registration onto the container like the [DbContextContainerExtension](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.Model/DbContextContainerExtension.cs) or the [BasicInterceptorInstaller](https://github.com/PHOENIXCONTACT/MORYX-Framework/blob/future/src/Moryx.TestTools.UnitTest/BasicInterceptorInstaller.cs) + +## ServerModuleBase + +To simplify development and prepare easier integration of the Moryx.Cli we merged the `ServerModuleFacadeControllerBase` into the `ServerModuleBase`. Just replace the base type if your module is affected by this. \ No newline at end of file From 76055da36822955c88beeb50468aa7ba59625fe9 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Wed, 30 Aug 2023 19:15:22 +0200 Subject: [PATCH 26/57] Add note about public exportes only to migration guide --- docs/migrations/v6_to_v8.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/migrations/v6_to_v8.md b/docs/migrations/v6_to_v8.md index 56a988787..5f5cd6bd0 100644 --- a/docs/migrations/v6_to_v8.md +++ b/docs/migrations/v6_to_v8.md @@ -6,7 +6,7 @@ The DI container within modules based on Castle Windsor was refactored and simpl - **Attribute changes:** The base attributes for registration were removed, use `ComponentAttribute`, `PluginAttribute` and `PluginFactory` instead. - **Installers removed** The concept of installes was removed and with it their implementations `AutoInstaller` and `DependencyInstaller`. They were replaced by the extensions `LoadFromAssembly` with different signature options for `DependencyRegistrationAttribute` and `Predicate` -- **LoadComponents** was removed as a dedicate feature and is now an extension on `IContainer`. +- **LoadComponents** was removed as a dedicate feature and is now an extension on `IContainer`. It has also been restricted to public/exported types. - **IContainerHost** was removed. The seperate interface for accessing a modules container just caused unnecessary casts and the risk of invalid type. The property `Container` was added to `IServerModule` instead. - **Extend** The flexible method for passing facilities to Castle was removed as it was only added and used by WCF. - **MoryxFacility** All MORYX specific behavior like strategies and `Named` import overrides were refactored to follow Castle best practises and are now isolated in the `MoryxFacility`. This enables everyone to achieve the MORYX DI behavior with a Castle Container without the MORYX wrapper. From bb40dfbf2dfd395c5c7352428d9c88fca5763ec8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 17:18:59 +0000 Subject: [PATCH 27/57] Bump Moq from 4.17.2 to 4.20.69 Bumps [Moq](https://github.com/moq/moq) from 4.17.2 to 4.20.69. - [Release notes](https://github.com/moq/moq/releases) - [Changelog](https://github.com/moq/moq/blob/main/CHANGELOG.md) - [Commits](https://github.com/moq/moq/compare/v4.17.2...v4.20.69) --- updated-dependencies: - dependency-name: Moq dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index c1e61344a..dbfeec834 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -19,7 +19,7 @@ - + From d3481734cb4cb6b835ab173eeac2db85121f37c2 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Fri, 30 Jun 2023 08:37:07 +0200 Subject: [PATCH 28/57] Remove unused references from projects and unnecessary imports --- .../Moryx.AbstractionLayer.TestTools.csproj | 5 ----- .../Moryx.DependentTestModule.csproj | 4 ---- src/Moryx.Model.PostgreSQL/NpgsqlDatabaseConfig.cs | 1 - src/Moryx.Model/Configuration/ModelConfiguratorBase.cs | 1 - src/Moryx.Model/DatabaseConfig.cs | 2 -- src/Moryx.Model/DatabaseConnectionSettings.cs | 2 -- src/Moryx.Model/EntityBase.cs | 1 - .../ModuleController/ModuleConsole.cs | 2 -- src/Moryx.Resources.Management/Model/ResourcesContext.cs | 4 ---- .../Resources/ResourceEntityAccessor.cs | 1 - src/Moryx.Resources.Samples/StrategyUsingResource.cs | 9 +-------- .../Databases/Endpoint/Exceptions/Exceptions.cs | 4 ---- .../Databases/Endpoint/Models/DataModel.cs | 3 --- .../Endpoint/Services/DatabaseConfigUpdateService.cs | 2 -- src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj | 5 ----- src/Moryx.TestModule/Moryx.TestModule.csproj | 4 ---- .../Moryx.TestTools.Test.Model.csproj | 2 -- src/StartProject.Asp/Program.cs | 1 - .../Moryx.Communication.Sockets.IntegrationTests.csproj | 2 -- .../Moryx.Container.Tests/Moryx.Container.Tests.csproj | 1 - src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj | 2 -- ...oryx.AbstractionLayer.Products.Endpoints.Tests.csproj | 1 - .../Databases/UpdateConfigSqliteTests.cs | 9 --------- .../Moryx.Runtime.Endpoints.Tests.csproj | 1 - .../Moryx.Runtime.Kernel.Tests.csproj | 1 - src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj | 1 - src/Tests/Moryx.Tests/Moryx.Tests.csproj | 1 - .../Serialization/EntryConvertInvokeMethodTests.cs | 3 --- 28 files changed, 1 insertion(+), 74 deletions(-) diff --git a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj index f572eb116..d261b6e64 100644 --- a/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj +++ b/src/Moryx.AbstractionLayer.TestTools/Moryx.AbstractionLayer.TestTools.csproj @@ -7,14 +7,9 @@ MORYX;IIoT;IoT;Abstraction;Tests - - - - - diff --git a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj index b3691c8a7..bd0b9ea42 100644 --- a/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj +++ b/src/Moryx.DependentTestModule/Moryx.DependentTestModule.csproj @@ -7,10 +7,6 @@ false - - - - diff --git a/src/Moryx.Model.PostgreSQL/NpgsqlDatabaseConfig.cs b/src/Moryx.Model.PostgreSQL/NpgsqlDatabaseConfig.cs index 00624d587..e2fb6b4dd 100644 --- a/src/Moryx.Model.PostgreSQL/NpgsqlDatabaseConfig.cs +++ b/src/Moryx.Model.PostgreSQL/NpgsqlDatabaseConfig.cs @@ -1,7 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using Moryx.Tools; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; diff --git a/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs b/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs index 0df40c9c1..b3a91b333 100644 --- a/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs +++ b/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.Logging; using Moryx.Configuration; using Moryx.Tools; diff --git a/src/Moryx.Model/DatabaseConfig.cs b/src/Moryx.Model/DatabaseConfig.cs index 41b2fbf6c..b3346b4a2 100644 --- a/src/Moryx.Model/DatabaseConfig.cs +++ b/src/Moryx.Model/DatabaseConfig.cs @@ -3,9 +3,7 @@ using System.Runtime.Serialization; using Moryx.Configuration; -using Moryx.Model.Attributes; using Moryx.Model.Configuration; -using Moryx.Serialization; namespace Moryx.Model { diff --git a/src/Moryx.Model/DatabaseConnectionSettings.cs b/src/Moryx.Model/DatabaseConnectionSettings.cs index 88d6decbd..34c94607d 100644 --- a/src/Moryx.Model/DatabaseConnectionSettings.cs +++ b/src/Moryx.Model/DatabaseConnectionSettings.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0 using System.Collections.Generic; -using System.ComponentModel; -using System.Reflection; using System.Runtime.Serialization; namespace Moryx.Model diff --git a/src/Moryx.Model/EntityBase.cs b/src/Moryx.Model/EntityBase.cs index b09494f42..277d2fef5 100644 --- a/src/Moryx.Model/EntityBase.cs +++ b/src/Moryx.Model/EntityBase.cs @@ -1,7 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/Moryx.Products.Management/ModuleController/ModuleConsole.cs b/src/Moryx.Products.Management/ModuleController/ModuleConsole.cs index f6fd4e8a0..40a220883 100644 --- a/src/Moryx.Products.Management/ModuleController/ModuleConsole.cs +++ b/src/Moryx.Products.Management/ModuleController/ModuleConsole.cs @@ -1,9 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System; using System.ComponentModel; -using System.Linq; using Moryx.AbstractionLayer.Products; using Moryx.AbstractionLayer.Recipes; using Moryx.Configuration; diff --git a/src/Moryx.Resources.Management/Model/ResourcesContext.cs b/src/Moryx.Resources.Management/Model/ResourcesContext.cs index ad7904e9f..3065d705d 100644 --- a/src/Moryx.Resources.Management/Model/ResourcesContext.cs +++ b/src/Moryx.Resources.Management/Model/ResourcesContext.cs @@ -1,12 +1,8 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System.IO; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Moryx.Model; -using Moryx.Model.Attributes; -using Moryx.Model.PostgreSQL; // ReSharper disable once CheckNamespace namespace Moryx.Resources.Model diff --git a/src/Moryx.Resources.Management/Resources/ResourceEntityAccessor.cs b/src/Moryx.Resources.Management/Resources/ResourceEntityAccessor.cs index d5542932c..7a3637f7f 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceEntityAccessor.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceEntityAccessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System; using System.Collections.Generic; using System.Linq; using Moryx.AbstractionLayer.Resources; diff --git a/src/Moryx.Resources.Samples/StrategyUsingResource.cs b/src/Moryx.Resources.Samples/StrategyUsingResource.cs index 410d1886d..0870ebf47 100644 --- a/src/Moryx.Resources.Samples/StrategyUsingResource.cs +++ b/src/Moryx.Resources.Samples/StrategyUsingResource.cs @@ -1,13 +1,6 @@ -using Moryx.AbstractionLayer.Drivers.Rfid; -using Moryx.AbstractionLayer.Drivers; -using Moryx.AbstractionLayer.Resources; +using Moryx.AbstractionLayer.Resources; using Moryx.Container; -using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Moryx.Serialization; using System.Runtime.Serialization; using System.Text.RegularExpressions; diff --git a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Exceptions/Exceptions.cs b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Exceptions/Exceptions.cs index 70db0546d..fbf8cadd3 100644 --- a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Exceptions/Exceptions.cs +++ b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Exceptions/Exceptions.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Moryx.Runtime.Endpoints.Databases.Endpoint.Exceptions { diff --git a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Models/DataModel.cs b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Models/DataModel.cs index ac433d6de..44b4b25ff 100644 --- a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Models/DataModel.cs +++ b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Models/DataModel.cs @@ -1,9 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using Moryx.Model.Configuration; -using Moryx.Serialization; - namespace Moryx.Runtime.Endpoints.Databases.Endpoint.Models { /// diff --git a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Services/DatabaseConfigUpdateService.cs b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Services/DatabaseConfigUpdateService.cs index 8a0541fe5..7f51a46f9 100644 --- a/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Services/DatabaseConfigUpdateService.cs +++ b/src/Moryx.Runtime.Endpoints/Databases/Endpoint/Services/DatabaseConfigUpdateService.cs @@ -5,8 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Moryx.Runtime.Endpoints.Databases.Endpoint.Services { diff --git a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj index 6b50d5ad1..054c7834f 100644 --- a/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj +++ b/src/Moryx.Runtime.Kernel/Moryx.Runtime.Kernel.csproj @@ -7,11 +7,6 @@ MORYX;Kernel;Runtime;Server - - - - - diff --git a/src/Moryx.TestModule/Moryx.TestModule.csproj b/src/Moryx.TestModule/Moryx.TestModule.csproj index 4a68a1cf7..3be921835 100644 --- a/src/Moryx.TestModule/Moryx.TestModule.csproj +++ b/src/Moryx.TestModule/Moryx.TestModule.csproj @@ -7,10 +7,6 @@ false - - - - diff --git a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj index 3fa69dc19..2051f30f4 100644 --- a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj +++ b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj @@ -6,8 +6,6 @@ - - diff --git a/src/StartProject.Asp/Program.cs b/src/StartProject.Asp/Program.cs index f47c08d31..80867a324 100644 --- a/src/StartProject.Asp/Program.cs +++ b/src/StartProject.Asp/Program.cs @@ -3,7 +3,6 @@ using Moryx.Runtime.Kernel; using Moryx.Tools; using Moryx.Model; -using Moryx.Runtime.Endpoints; namespace StartProject.Asp { diff --git a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj index d2192d8c5..8da75c14b 100644 --- a/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj +++ b/src/Tests/Moryx.Communication.Sockets.IntegrationTests/Moryx.Communication.Sockets.IntegrationTests.csproj @@ -8,14 +8,12 @@ - - diff --git a/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj b/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj index 4dfd568fc..69fe60437 100644 --- a/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj +++ b/src/Tests/Moryx.Container.Tests/Moryx.Container.Tests.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj b/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj index 26e8e1f1e..7f438b982 100644 --- a/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj +++ b/src/Tests/Moryx.Model.Tests/Moryx.Model.Tests.csproj @@ -9,7 +9,6 @@ - @@ -19,7 +18,6 @@ - diff --git a/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj b/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj index de0cad0be..e96309139 100644 --- a/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj +++ b/src/Tests/Moryx.Products.Management.Tests/Moryx.AbstractionLayer.Products.Endpoints.Tests.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Tests/Moryx.Runtime.Endpoints.Tests/Databases/UpdateConfigSqliteTests.cs b/src/Tests/Moryx.Runtime.Endpoints.Tests/Databases/UpdateConfigSqliteTests.cs index 70ff1c4bb..5e77dc3f2 100644 --- a/src/Tests/Moryx.Runtime.Endpoints.Tests/Databases/UpdateConfigSqliteTests.cs +++ b/src/Tests/Moryx.Runtime.Endpoints.Tests/Databases/UpdateConfigSqliteTests.cs @@ -2,23 +2,14 @@ // Licensed under the Apache License, Version 2.0 using Microsoft.Extensions.Logging; -using Moq; using Moryx.Model; using Moryx.Runtime.Endpoints.Databases.Endpoint.Services; using Moryx.Runtime.Kernel; using Moryx.TestTools.Test.Model; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.ComponentModel; -using System.Xml.Linq; using Moryx.Runtime.Endpoints.Databases.Endpoint.Models; using Moryx.Model.Sqlite; -using System.Runtime.CompilerServices; using NUnit.Framework; -using Moryx.Model.Configuration; using Moryx.Runtime.Endpoints.Databases.Endpoint.Exceptions; namespace Moryx.Runtime.Endpoints.Tests.Databases diff --git a/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj b/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj index d8c44f249..547ca8d9e 100644 --- a/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Endpoints.Tests/Moryx.Runtime.Endpoints.Tests.csproj @@ -10,7 +10,6 @@ - diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj b/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj index ce8d4a08d..e0763d99c 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/Moryx.Runtime.Kernel.Tests.csproj @@ -17,7 +17,6 @@ - diff --git a/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj b/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj index ce8d4a08d..e0763d99c 100644 --- a/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj +++ b/src/Tests/Moryx.Runtime.Tests/Moryx.Runtime.Tests.csproj @@ -17,7 +17,6 @@ - diff --git a/src/Tests/Moryx.Tests/Moryx.Tests.csproj b/src/Tests/Moryx.Tests/Moryx.Tests.csproj index 29b8cd319..5587d8866 100644 --- a/src/Tests/Moryx.Tests/Moryx.Tests.csproj +++ b/src/Tests/Moryx.Tests/Moryx.Tests.csproj @@ -14,7 +14,6 @@ - diff --git a/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs b/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs index 7240476d4..b983856b7 100644 --- a/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs +++ b/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs @@ -1,9 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System.Collections.Generic; -using System.Globalization; -using System.Linq; using Moryx.Serialization; using NUnit.Framework; From 3fa19ba86c0acb2e38fbb38af8dca1bfcc559d9d Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Mon, 10 Jul 2023 14:23:23 +0200 Subject: [PATCH 29/57] Cleanup warnings --- .../PartialSerialization.cs | 3 ++ .../ProductManagementController.cs | 2 +- .../ProductPermissions.cs | 38 +++++++++++++++++++ .../WorkplanPermissions.cs | 18 +++++++++ .../ResourcePermissions.cs | 35 +++++++++++++++++ .../DummyProductPartLink.cs | 1 + .../DummyProductRecipe.cs | 7 ++++ .../DummyProductType.cs | 5 ++- .../DummyWorkplan.cs | 4 ++ .../Resources/ResourceGraphMock.cs | 11 ++++++ .../Process/ProcessBindingResolverFactory.cs | 4 ++ .../Configuration/NullModelConfigurator.cs | 1 + .../FloatStrategyConfigurationAttribute.cs | 2 + .../IntegerStrategyConfigurationAttribute.cs | 2 + .../AvailableColumnsAttribute.cs | 3 ++ .../GenericStrategies/PropertyMapper.cs | 3 ++ .../Entities/PartLinkEntity.cs | 1 + .../Entities/ProductInstanceEntity.cs | 1 + .../Entities/ProductRecipeEntity.cs | 1 + .../Entities/ProductTypeEntity.cs | 1 + .../Entities/ProductTypePropertiesEntity.cs | 1 + .../Entities/WorkplanEntity.cs | 1 + .../WorkplanOutputDescriptionEntity.cs | 1 + .../Entities/WorkplanReferenceEntity.cs | 1 + .../Entities/WorkplanStepEntity.cs | 1 + .../20220906133824_InitialCreate.Designer.cs | 8 ++-- .../Npgsql/20220906133824_InitialCreate.cs | 6 ++- .../20230214165158_InitialCreate.Designer.cs | 8 ++-- .../Sqlite/20230214165158_InitialCreate.cs | 6 ++- .../Model/Entities/ResourceEntity.cs | 1 + .../Model/Entities/ResourceRelationEntity.cs | 1 + .../20211104134830_InitialCreate.Designer.cs | 6 ++- .../Npgsql/20211104134830_InitialCreate.cs | 6 ++- .../20230215071938_InitialCreate.Designer.cs | 7 +++- .../Sqlite/20230215071938_InitialCreate.cs | 6 ++- .../ModuleController/ModuleConsole.cs | 6 --- .../ModuleController/ModuleController.cs | 1 + .../DataMemberAttributeValueProviderFilter.cs | 1 + .../AssembleResource.cs | 1 + src/Moryx.Resources.Samples/BufferResource.cs | 1 + src/Moryx.Resources.Samples/Cell.cs | 1 + .../IVisualInstructor.cs | 1 + src/Moryx.Resources.Samples/SolderingCell.cs | 1 + .../Components/MissingFacadeException.cs | 1 + .../Management/HealthStateException.cs | 1 + src/Moryx.Runtime/Modules/ServerModuleBase.cs | 3 ++ src/Moryx/Configuration/IConfigManager.cs | 1 + .../Configuration/InvalidConfigException.cs | 1 + .../ValueProviderExecutorSettings.cs | 2 +- .../CollectionStrategy/ArrayIListStrategy.cs | 9 +++++ .../CustomAttributeProviderExtensions.cs | 4 +- .../ModuleManagerTests.cs | 1 - .../EntryConvertInvokeMethodTests.cs | 1 - 53 files changed, 214 insertions(+), 26 deletions(-) diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/PartialSerialization.cs b/src/Moryx.AbstractionLayer.Products.Endpoints/PartialSerialization.cs index d8d510dfc..8b4dea2c7 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/PartialSerialization.cs +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/PartialSerialization.cs @@ -28,6 +28,9 @@ static PartialSerialization() _serialization = new EntrySerializeSerialization(); } + /// + /// Creates a new instance + /// public PartialSerialization() : base(null, new EmptyValueProvider()) { } diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs index af0aaea26..981aad47b 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs @@ -176,7 +176,7 @@ public ActionResult GetTypeById(long id) { productType = _productManagement.LoadType(id); } - catch (ProductNotFoundException e) + catch (ProductNotFoundException) { } if (productType == null) diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductPermissions.cs b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductPermissions.cs index d9399c4d9..df0e1b110 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductPermissions.cs +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductPermissions.cs @@ -1,15 +1,53 @@ namespace Moryx.AbstractionLayer.Products.Endpoints { + /// + /// Permissions used to authorize for the + /// public static class ProductPermissions { + /// + /// Prefix used for all permissions of the controller + /// private const string _prefix = "Moryx.Products."; + + /// + /// Permission for all actions related to viewing one or multiple product types + /// public const string CanViewTypes = _prefix + "CanViewTypes"; + + /// + /// Permission for all actions related to creating and editing recipes + /// public const string CanCreateAndEditRecipes = _prefix + "CanCreateAndEditRecipes"; + + /// + /// Permission for all actions related to editing one or multiple product types + /// public const string CanEditType = _prefix + "CanEditType"; + + /// + /// Permission for all actions related to duplicating one or multiple product types + /// public const string CanDuplicateType = _prefix + "CanDuplicateType"; + + /// + /// Permission for all actions related to see and execute a product importer + /// public const string CanImport = _prefix + "CanImport"; + + /// + /// Permission for all actions related to deleting one or multiple product types + /// public const string CanDeleteType = _prefix + "CanDeleteType"; + + /// + /// Permission for all actions related to viewing one or multiple product instances + /// public const string CanViewInstances = _prefix + "CanViewInstances"; + + /// + /// Permission for all actions related to creating one or multiple product instances + /// public const string CanCreateInstances = _prefix + "CanCreateInstances"; } } diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/WorkplanPermissions.cs b/src/Moryx.AbstractionLayer.Products.Endpoints/WorkplanPermissions.cs index d09a886fe..4ae545160 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/WorkplanPermissions.cs +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/WorkplanPermissions.cs @@ -1,10 +1,28 @@ namespace Moryx.AbstractionLayer.Products.Endpoints { + /// + /// Permissions used to authorize for the + /// public static class WorkplanPermissions { + /// + /// Prefix used for all permissions of the controller + /// private const string _prefix = "Moryx.Workplans."; + + /// + /// Permission for all actions related to viewing one or multiple workplans + /// public const string CanView = _prefix + "CanView"; + + /// + /// Permission for all actions related to editing or creating one or multiple workplans + /// public const string CanEdit = _prefix + "CanEdit"; + + /// + /// Permission for all actions related to deleting one or multiple workplans + /// public const string CanDelete = _prefix + "CanDelete"; } } diff --git a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourcePermissions.cs b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourcePermissions.cs index 926f7dc64..4abe04817 100644 --- a/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourcePermissions.cs +++ b/src/Moryx.AbstractionLayer.Resources.Endpoints/ResourcePermissions.cs @@ -1,14 +1,49 @@ namespace Moryx.AbstractionLayer.Resources.Endpoints { + /// + /// Permissions used to authorize for the + /// public static class ResourcePermissions { + /// + /// Prefix used for all permissions of the controller + /// private const string _prefix = "Moryx.Resources."; + + /// + /// Permission for all actions related to viewing the resource instance tree + /// public const string CanViewTree = _prefix + "CanViewTree"; + + /// + /// Permission for all actions related to viewing the instance information of a resource + /// public const string CanViewDetails = _prefix + "CanViewDetails"; + + /// + /// Permission for all actions related to editing the resource graph and its members + /// public const string CanEdit = _prefix + "CanEdit"; + + // ToDo: Rename permission to CanViewTypeTree + /// + /// Permission for all actions related to viewing the resource type tree + /// public const string CanViewTypeTree = _prefix + "CanAddResource"; + + /// + /// Permission for all actions related to adding one or multiple resources + /// public const string CanAdd = _prefix + "CanAdd"; + + /// + /// Permission for all actions related to adding one or multiple resources + /// public const string CanDelete = _prefix + "CanDelete"; + + /// + /// Permission for all actions related to invoking a method on a resource + /// public const string CanInvokeMethod = _prefix + "CanInvokeMethod"; } } diff --git a/src/Moryx.AbstractionLayer.TestTools/DummyProductPartLink.cs b/src/Moryx.AbstractionLayer.TestTools/DummyProductPartLink.cs index 1c7cc4098..f700d5988 100644 --- a/src/Moryx.AbstractionLayer.TestTools/DummyProductPartLink.cs +++ b/src/Moryx.AbstractionLayer.TestTools/DummyProductPartLink.cs @@ -11,6 +11,7 @@ namespace Moryx.AbstractionLayer.TestTools /// public class DummyProductPartLink : ProductPartLink { + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyProductPartLink; diff --git a/src/Moryx.AbstractionLayer.TestTools/DummyProductRecipe.cs b/src/Moryx.AbstractionLayer.TestTools/DummyProductRecipe.cs index 41ce23945..0ee5ca41b 100644 --- a/src/Moryx.AbstractionLayer.TestTools/DummyProductRecipe.cs +++ b/src/Moryx.AbstractionLayer.TestTools/DummyProductRecipe.cs @@ -13,6 +13,7 @@ namespace Moryx.AbstractionLayer.TestTools /// public class DummyProductRecipe : ProductRecipe { + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyProductRecipe; @@ -27,12 +28,18 @@ public override bool Equals(object obj) } } + /// + /// Dummy implementation of a workplan recipe. + /// public class DummyProductWorkplanRecipe : DummyProductRecipe, IWorkplanRecipe { + /// public IWorkplan Workplan { get; set; } + /// public ICollection DisabledSteps { get; set; } + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyProductWorkplanRecipe; diff --git a/src/Moryx.AbstractionLayer.TestTools/DummyProductType.cs b/src/Moryx.AbstractionLayer.TestTools/DummyProductType.cs index 8ffecfaf1..54e9e029e 100644 --- a/src/Moryx.AbstractionLayer.TestTools/DummyProductType.cs +++ b/src/Moryx.AbstractionLayer.TestTools/DummyProductType.cs @@ -17,6 +17,7 @@ protected override ProductInstance Instantiate() { return new DummyProductInstance(); } +/// public override bool Equals(object obj) { @@ -51,6 +52,7 @@ protected override ProductInstance Instantiate() /// public IEnumerable ProductPartLinkEnumerable { get; set; } + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyProductTypeWithParts; @@ -86,7 +88,8 @@ protected override ProductInstance Instantiate() /// Second dummy ProductFile /// public ProductFile SecondProductFile { get; set; } - + + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyProductTypeWithFiles; diff --git a/src/Moryx.AbstractionLayer.TestTools/DummyWorkplan.cs b/src/Moryx.AbstractionLayer.TestTools/DummyWorkplan.cs index 0e131f0ab..db255b711 100644 --- a/src/Moryx.AbstractionLayer.TestTools/DummyWorkplan.cs +++ b/src/Moryx.AbstractionLayer.TestTools/DummyWorkplan.cs @@ -6,8 +6,12 @@ namespace Moryx.AbstractionLayer.TestTools { + /// + /// Dummy implementation of with overridden method for testing purposes. + /// public class DummyWorkplan : Workplan { + /// public override bool Equals(object obj) { var toCompareWith = obj as DummyWorkplan; diff --git a/src/Moryx.AbstractionLayer.TestTools/Resources/ResourceGraphMock.cs b/src/Moryx.AbstractionLayer.TestTools/Resources/ResourceGraphMock.cs index 895b3f867..8eb4b45e5 100644 --- a/src/Moryx.AbstractionLayer.TestTools/Resources/ResourceGraphMock.cs +++ b/src/Moryx.AbstractionLayer.TestTools/Resources/ResourceGraphMock.cs @@ -16,38 +16,48 @@ public class ResourceGraphMock : IResourceGraph { private IDictionary _typeMap; + /// + /// The list of resources in this graph + /// public List Graph { get; set; } + /// public Resource Get(long id) { return Graph.FirstOrDefault(r => r.Id == id); } + /// public TResource GetResource() where TResource : class, IResource { throw new NotImplementedException(); } + /// public TResource GetResource(long id) where TResource : class, IResource { throw new NotImplementedException(); } + /// public TResource GetResource(string name) where TResource : class, IResource { throw new NotImplementedException(); } + /// public TResource GetResource(Func predicate) where TResource : class, IResource { throw new NotImplementedException(); } + /// public IEnumerable GetResources() where TResource : class, IResource { throw new NotImplementedException(); } + /// public IEnumerable GetResources(Func predicate) where TResource : class, IResource { throw new NotImplementedException(); @@ -101,6 +111,7 @@ public bool Destroy(IResource resource, bool permanent) return Destroy(resource); } + /// public void Save(IResource resource) { } diff --git a/src/Moryx.AbstractionLayer/Process/ProcessBindingResolverFactory.cs b/src/Moryx.AbstractionLayer/Process/ProcessBindingResolverFactory.cs index 85ad9684a..2359bdbd7 100644 --- a/src/Moryx.AbstractionLayer/Process/ProcessBindingResolverFactory.cs +++ b/src/Moryx.AbstractionLayer/Process/ProcessBindingResolverFactory.cs @@ -127,6 +127,10 @@ public class ProductResolver : BindingResolverBase { private readonly string _fallbackProperty; + /// + /// Creates a new + /// + /// public ProductResolver(string fallbackProperty) { _fallbackProperty = fallbackProperty; diff --git a/src/Moryx.Model/Configuration/NullModelConfigurator.cs b/src/Moryx.Model/Configuration/NullModelConfigurator.cs index b6843d262..480e57aaf 100644 --- a/src/Moryx.Model/Configuration/NullModelConfigurator.cs +++ b/src/Moryx.Model/Configuration/NullModelConfigurator.cs @@ -89,6 +89,7 @@ public Task RestoreDatabase(IDatabaseConfig config, string filePath) throw new NotSupportedException("Not supported by " + nameof(NullModelConfigurator)); } + /// public DbContext CreateContext(Type contextType, DbContextOptions dbContextOptions) { throw new NotImplementedException(); diff --git a/src/Moryx.Products.Management/Implementation/Storage/FloatStrategyConfigurationAttribute.cs b/src/Moryx.Products.Management/Implementation/Storage/FloatStrategyConfigurationAttribute.cs index 0c1dcc3ae..1ef2633b8 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/FloatStrategyConfigurationAttribute.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/FloatStrategyConfigurationAttribute.cs @@ -3,8 +3,10 @@ namespace Moryx.Products.Management { + /// public class FloatStrategyConfigurationAttribute : PropertyStrategyConfigurationAttribute { + /// public FloatStrategyConfigurationAttribute() { ColumnType = typeof(double); diff --git a/src/Moryx.Products.Management/Implementation/Storage/IntegerStrategyConfigurationAttribute.cs b/src/Moryx.Products.Management/Implementation/Storage/IntegerStrategyConfigurationAttribute.cs index ec0bdc065..a477ee462 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/IntegerStrategyConfigurationAttribute.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/IntegerStrategyConfigurationAttribute.cs @@ -5,9 +5,11 @@ namespace Moryx.Products.Management { + /// [AttributeUsage(AttributeTargets.Class)] public class IntegerStrategyConfigurationAttribute : PropertyStrategyConfigurationAttribute { + /// public IntegerStrategyConfigurationAttribute() { ColumnType = typeof(long); diff --git a/src/Moryx.Products.Management/Plugins/GenericStrategies/AvailableColumnsAttribute.cs b/src/Moryx.Products.Management/Plugins/GenericStrategies/AvailableColumnsAttribute.cs index aecc62281..4c48a0638 100644 --- a/src/Moryx.Products.Management/Plugins/GenericStrategies/AvailableColumnsAttribute.cs +++ b/src/Moryx.Products.Management/Plugins/GenericStrategies/AvailableColumnsAttribute.cs @@ -34,9 +34,12 @@ public AvailableColumnsAttribute(Type columnType) _columnType = columnType; } + /// public override bool OverridesConversion => false; + /// public override bool UpdateFromPredecessor => false; + /// public override IEnumerable GetValues(IContainer container) { return typeof(IGenericColumns).GetProperties() diff --git a/src/Moryx.Products.Management/Plugins/GenericStrategies/PropertyMapper.cs b/src/Moryx.Products.Management/Plugins/GenericStrategies/PropertyMapper.cs index 84e647d4e..e289c9450 100644 --- a/src/Moryx.Products.Management/Plugins/GenericStrategies/PropertyMapper.cs +++ b/src/Moryx.Products.Management/Plugins/GenericStrategies/PropertyMapper.cs @@ -103,6 +103,7 @@ protected virtual object ToExpressionValue(object value) return Convert.ChangeType(value, Column.PropertyType); } + /// public bool HasChanged(IGenericColumns current, object updated) { var objectValue = ObjectAccessor.ReadProperty(updated); @@ -114,12 +115,14 @@ public bool HasChanged(IGenericColumns current, object updated) return !columnValue.Equals(objectValue); } + /// public void ReadValue(IGenericColumns source, object target) { var value = ColumnAccessor.ReadProperty(source); ObjectAccessor.WriteProperty(target, value); } + /// public void WriteValue(object source, IGenericColumns target) { var value = ObjectAccessor.ReadProperty(source); diff --git a/src/Moryx.Products.Model/Entities/PartLinkEntity.cs b/src/Moryx.Products.Model/Entities/PartLinkEntity.cs index ed04e9f25..28df78e67 100644 --- a/src/Moryx.Products.Model/Entities/PartLinkEntity.cs +++ b/src/Moryx.Products.Model/Entities/PartLinkEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; namespace Moryx.Products.Model diff --git a/src/Moryx.Products.Model/Entities/ProductInstanceEntity.cs b/src/Moryx.Products.Model/Entities/ProductInstanceEntity.cs index 181a38487..6ddaa092c 100644 --- a/src/Moryx.Products.Model/Entities/ProductInstanceEntity.cs +++ b/src/Moryx.Products.Model/Entities/ProductInstanceEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; using System.Collections.Generic; diff --git a/src/Moryx.Products.Model/Entities/ProductRecipeEntity.cs b/src/Moryx.Products.Model/Entities/ProductRecipeEntity.cs index eb3e24a08..a630ac279 100644 --- a/src/Moryx.Products.Model/Entities/ProductRecipeEntity.cs +++ b/src/Moryx.Products.Model/Entities/ProductRecipeEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; namespace Moryx.Products.Model diff --git a/src/Moryx.Products.Model/Entities/ProductTypeEntity.cs b/src/Moryx.Products.Model/Entities/ProductTypeEntity.cs index 0062c778a..09871f9a2 100644 --- a/src/Moryx.Products.Model/Entities/ProductTypeEntity.cs +++ b/src/Moryx.Products.Model/Entities/ProductTypeEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; using System.Collections.Generic; diff --git a/src/Moryx.Products.Model/Entities/ProductTypePropertiesEntity.cs b/src/Moryx.Products.Model/Entities/ProductTypePropertiesEntity.cs index c5c60bc5d..32c8032d9 100644 --- a/src/Moryx.Products.Model/Entities/ProductTypePropertiesEntity.cs +++ b/src/Moryx.Products.Model/Entities/ProductTypePropertiesEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; namespace Moryx.Products.Model diff --git a/src/Moryx.Products.Model/Entities/WorkplanEntity.cs b/src/Moryx.Products.Model/Entities/WorkplanEntity.cs index 51813f8e9..746028a56 100644 --- a/src/Moryx.Products.Model/Entities/WorkplanEntity.cs +++ b/src/Moryx.Products.Model/Entities/WorkplanEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; using System.Collections.Generic; diff --git a/src/Moryx.Products.Model/Entities/WorkplanOutputDescriptionEntity.cs b/src/Moryx.Products.Model/Entities/WorkplanOutputDescriptionEntity.cs index 452b8cf6a..1801ce673 100644 --- a/src/Moryx.Products.Model/Entities/WorkplanOutputDescriptionEntity.cs +++ b/src/Moryx.Products.Model/Entities/WorkplanOutputDescriptionEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; namespace Moryx.Products.Model diff --git a/src/Moryx.Products.Model/Entities/WorkplanReferenceEntity.cs b/src/Moryx.Products.Model/Entities/WorkplanReferenceEntity.cs index a465c525d..d6816e897 100644 --- a/src/Moryx.Products.Model/Entities/WorkplanReferenceEntity.cs +++ b/src/Moryx.Products.Model/Entities/WorkplanReferenceEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; namespace Moryx.Products.Model diff --git a/src/Moryx.Products.Model/Entities/WorkplanStepEntity.cs b/src/Moryx.Products.Model/Entities/WorkplanStepEntity.cs index f81653556..01e7166ee 100644 --- a/src/Moryx.Products.Model/Entities/WorkplanStepEntity.cs +++ b/src/Moryx.Products.Model/Entities/WorkplanStepEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; using System.Collections.Generic; diff --git a/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.Designer.cs b/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.Designer.cs index c16706b8f..394079c2d 100644 --- a/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.Designer.cs +++ b/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.Designer.cs @@ -1,10 +1,12 @@ -// +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moryx.Products.Model; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace Moryx.Products.Model.Migrations.Npgsql diff --git a/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.cs b/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.cs index d906a2559..b974f6fc9 100644 --- a/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.cs +++ b/src/Moryx.Products.Model/Migrations/Npgsql/20220906133824_InitialCreate.cs @@ -1,4 +1,8 @@ -using System; +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; diff --git a/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.Designer.cs b/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.Designer.cs index e84034331..d837c1f43 100644 --- a/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.Designer.cs +++ b/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.Designer.cs @@ -1,10 +1,12 @@ -// +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moryx.Products.Model; #nullable disable diff --git a/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.cs b/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.cs index 1a3aeb4ce..e999daffb 100644 --- a/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.cs +++ b/src/Moryx.Products.Model/Migrations/Sqlite/20230214165158_InitialCreate.cs @@ -1,4 +1,8 @@ -using System; +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/src/Moryx.Resources.Management/Model/Entities/ResourceEntity.cs b/src/Moryx.Resources.Management/Model/Entities/ResourceEntity.cs index 7cc5ba790..5ffc57ff2 100644 --- a/src/Moryx.Resources.Management/Model/Entities/ResourceEntity.cs +++ b/src/Moryx.Resources.Management/Model/Entities/ResourceEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; using System.Collections.Generic; diff --git a/src/Moryx.Resources.Management/Model/Entities/ResourceRelationEntity.cs b/src/Moryx.Resources.Management/Model/Entities/ResourceRelationEntity.cs index 67eeeaf5e..2f9565f4b 100644 --- a/src/Moryx.Resources.Management/Model/Entities/ResourceRelationEntity.cs +++ b/src/Moryx.Resources.Management/Model/Entities/ResourceRelationEntity.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.Model; // ReSharper disable once CheckNamespace diff --git a/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.Designer.cs b/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.Designer.cs index 83c994137..794c47f54 100644 --- a/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.Designer.cs +++ b/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.Designer.cs @@ -1,4 +1,8 @@ -// +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.cs b/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.cs index 28677526f..8a5135124 100644 --- a/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.cs +++ b/src/Moryx.Resources.Management/Model/Migrations/Npgsql/20211104134830_InitialCreate.cs @@ -1,4 +1,8 @@ -using System; +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; diff --git a/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.Designer.cs b/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.Designer.cs index 823f19fc4..f471e12b1 100644 --- a/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.Designer.cs +++ b/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.Designer.cs @@ -1,9 +1,12 @@ -// +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Moryx.Resources.Model; #nullable disable diff --git a/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.cs b/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.cs index 20a95ce26..41aaa8b06 100644 --- a/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.cs +++ b/src/Moryx.Resources.Management/Model/Migrations/Sqlite/20230215071938_InitialCreate.cs @@ -1,4 +1,8 @@ -using System; +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/src/Moryx.Resources.Management/ModuleController/ModuleConsole.cs b/src/Moryx.Resources.Management/ModuleController/ModuleConsole.cs index a031e37b3..c7f62a1ad 100644 --- a/src/Moryx.Resources.Management/ModuleController/ModuleConsole.cs +++ b/src/Moryx.Resources.Management/ModuleController/ModuleConsole.cs @@ -31,12 +31,6 @@ internal class ModuleConsole : IServerModuleConsole #endregion - #region Fields - - private IResourceInitializer[] _initializers; - - #endregion - [EntrySerialize, DisplayName("Initialize Resource"), Description("Calls the configured resource initializer")] public string CallResourceInitializer([PluginConfigs(typeof(IResourceInitializer), true)] ResourceInitializerConfig[] configs) { diff --git a/src/Moryx.Resources.Management/ModuleController/ModuleController.cs b/src/Moryx.Resources.Management/ModuleController/ModuleController.cs index 0a3611d23..2cf4f0518 100644 --- a/src/Moryx.Resources.Management/ModuleController/ModuleController.cs +++ b/src/Moryx.Resources.Management/ModuleController/ModuleController.cs @@ -33,6 +33,7 @@ public class ModuleController : ServerModuleBase, /// public IDbContextManager DbContextManager { get; } + /// public ModuleController(IModuleContainerFactory containerFactory, IConfigManager configManager, ILoggerFactory loggerFactory, IDbContextManager contextManager) : base(containerFactory, configManager, loggerFactory) { diff --git a/src/Moryx.Resources.Management/Resources/DataMemberAttributeValueProviderFilter.cs b/src/Moryx.Resources.Management/Resources/DataMemberAttributeValueProviderFilter.cs index 1027a01d3..20278dccd 100644 --- a/src/Moryx.Resources.Management/Resources/DataMemberAttributeValueProviderFilter.cs +++ b/src/Moryx.Resources.Management/Resources/DataMemberAttributeValueProviderFilter.cs @@ -16,6 +16,7 @@ public DataMemberAttributeValueProviderFilter(bool filterDataMembers) _filterDataMembers = filterDataMembers; } + /// public bool CheckProperty(PropertyInfo propertyInfo) { if(_filterDataMembers) diff --git a/src/Moryx.Resources.Samples/AssembleResource.cs b/src/Moryx.Resources.Samples/AssembleResource.cs index 3640f2587..24302c711 100644 --- a/src/Moryx.Resources.Samples/AssembleResource.cs +++ b/src/Moryx.Resources.Samples/AssembleResource.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System.ComponentModel; using System.Runtime.Serialization; using Moryx.AbstractionLayer.Resources; diff --git a/src/Moryx.Resources.Samples/BufferResource.cs b/src/Moryx.Resources.Samples/BufferResource.cs index 7202cdf96..5d82d155c 100644 --- a/src/Moryx.Resources.Samples/BufferResource.cs +++ b/src/Moryx.Resources.Samples/BufferResource.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System.ComponentModel; using System.Linq; using System.Runtime.Serialization; diff --git a/src/Moryx.Resources.Samples/Cell.cs b/src/Moryx.Resources.Samples/Cell.cs index ad4faeaf9..ac5f154e5 100644 --- a/src/Moryx.Resources.Samples/Cell.cs +++ b/src/Moryx.Resources.Samples/Cell.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System.ComponentModel; using System.Runtime.Serialization; using Moryx.AbstractionLayer.Resources; diff --git a/src/Moryx.Resources.Samples/IVisualInstructor.cs b/src/Moryx.Resources.Samples/IVisualInstructor.cs index 0a097c251..40eff2bef 100644 --- a/src/Moryx.Resources.Samples/IVisualInstructor.cs +++ b/src/Moryx.Resources.Samples/IVisualInstructor.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System.ComponentModel; using System.Runtime.Serialization; using Moryx.AbstractionLayer.Resources; diff --git a/src/Moryx.Resources.Samples/SolderingCell.cs b/src/Moryx.Resources.Samples/SolderingCell.cs index 710104d75..509f23d3a 100644 --- a/src/Moryx.Resources.Samples/SolderingCell.cs +++ b/src/Moryx.Resources.Samples/SolderingCell.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using Moryx.AbstractionLayer; using Moryx.AbstractionLayer.Resources; diff --git a/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs b/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs index 0381ef61c..6fb12aa0f 100644 --- a/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs +++ b/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs @@ -49,6 +49,7 @@ public MissingFacadeException(string moduleName, string propName, Type facadeTyp /// The System.Runtime.Serialization.StreamingContext that contains contextual /// information about the source or destination. /// The info parameter is a null reference + [Obsolete("Override of an obsolete method.")] public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/Moryx.Runtime/Modules/Management/HealthStateException.cs b/src/Moryx.Runtime/Modules/Management/HealthStateException.cs index 4446ffdb2..aa1834cee 100644 --- a/src/Moryx.Runtime/Modules/Management/HealthStateException.cs +++ b/src/Moryx.Runtime/Modules/Management/HealthStateException.cs @@ -58,6 +58,7 @@ public HealthStateException(ServerModuleState current) /// The System.Runtime.Serialization.StreamingContext that contains contextual /// information about the source or destination. /// The info parameter is a null reference + [Obsolete("Override of an obsolete method.")] public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/Moryx.Runtime/Modules/ServerModuleBase.cs b/src/Moryx.Runtime/Modules/ServerModuleBase.cs index 69f1bf98c..5a8a693e4 100644 --- a/src/Moryx.Runtime/Modules/ServerModuleBase.cs +++ b/src/Moryx.Runtime/Modules/ServerModuleBase.cs @@ -38,6 +38,9 @@ public abstract class ServerModuleBase : IServerModule, IServerModuleStat /// public ILogger Logger { get; set; } + /// + /// Shared factory to create logger in this module + /// public ILoggerFactory LoggerFactory { get; set; } /// diff --git a/src/Moryx/Configuration/IConfigManager.cs b/src/Moryx/Configuration/IConfigManager.cs index 13352c1e0..c60c1e4f1 100644 --- a/src/Moryx/Configuration/IConfigManager.cs +++ b/src/Moryx/Configuration/IConfigManager.cs @@ -24,6 +24,7 @@ public interface IConfigManager /// Save configuration using its type /// /// Configuration object + /// Name of the configuration /// Update currently active config live void SaveConfiguration(IConfig configuration, string name, bool liveUpdate); diff --git a/src/Moryx/Configuration/InvalidConfigException.cs b/src/Moryx/Configuration/InvalidConfigException.cs index bce1816f9..aa9a91b98 100644 --- a/src/Moryx/Configuration/InvalidConfigException.cs +++ b/src/Moryx/Configuration/InvalidConfigException.cs @@ -51,6 +51,7 @@ public InvalidConfigException(object faultyEntry, string propertyFailure) /// The System.Runtime.Serialization.StreamingContext that contains contextual /// information about the source or destination. /// The info parameter is a null reference + [Obsolete("Override of an obsolete method.")] public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); diff --git a/src/Moryx/Configuration/ValueProvider/ValueProviderExecutorSettings.cs b/src/Moryx/Configuration/ValueProvider/ValueProviderExecutorSettings.cs index 4481c7cc5..703dba290 100644 --- a/src/Moryx/Configuration/ValueProvider/ValueProviderExecutorSettings.cs +++ b/src/Moryx/Configuration/ValueProvider/ValueProviderExecutorSettings.cs @@ -64,7 +64,7 @@ public ValueProviderExecutorSettings AddFilter(IValueProviderFilter valueProvide } /// - /// Adds + /// Adds a /// /// public ValueProviderExecutorSettings AddDefaultValueProvider() diff --git a/src/Moryx/Serialization/EntryConvert/CollectionStrategy/ArrayIListStrategy.cs b/src/Moryx/Serialization/EntryConvert/CollectionStrategy/ArrayIListStrategy.cs index ab8385a66..fb26e7a3a 100644 --- a/src/Moryx/Serialization/EntryConvert/CollectionStrategy/ArrayIListStrategy.cs +++ b/src/Moryx/Serialization/EntryConvert/CollectionStrategy/ArrayIListStrategy.cs @@ -5,6 +5,7 @@ namespace Moryx.Serialization { + /// public class ArrayIListStrategy : ICollectionStrategy { private readonly IList _list; @@ -14,6 +15,7 @@ public class ArrayIListStrategy : ICollectionStrategy private readonly object _instance; private readonly IList _toAdd = new List(); + /// public ArrayIListStrategy(IList list, ICustomSerialization customSerialization, ICustomAttributeProvider attributeProvider, object instance) { @@ -23,6 +25,7 @@ public ArrayIListStrategy(IList list, ICustomSerialization customSerialization, _instance = instance; } + /// public IEnumerable Serialize() { var entries = new List(); @@ -34,31 +37,37 @@ public IEnumerable Serialize() return entries; } + /// public IEnumerable Keys() { return CollectionStrategyTools.GenerateKeys(_list.Count); } + /// public object ElementAt(string key) { return _list[int.Parse(key)]; } + /// public void Added(Entry entry, object addedValue) { _toAdd.Add(addedValue); } + /// public void Updated(Entry entry, object updatedValue) { _list[int.Parse(entry.Identifier)] = updatedValue; } + /// public void Removed(string key) { _toDelete.Add(_list[int.Parse(key)]); } + /// public void Flush() { diff --git a/src/Moryx/Tools/Extensions/CustomAttributeProviderExtensions.cs b/src/Moryx/Tools/Extensions/CustomAttributeProviderExtensions.cs index 47dda4bbe..63a4803b8 100644 --- a/src/Moryx/Tools/Extensions/CustomAttributeProviderExtensions.cs +++ b/src/Moryx/Tools/Extensions/CustomAttributeProviderExtensions.cs @@ -60,7 +60,7 @@ public static TAttribute[] GetCustomAttributes(this ICustomAttribute /// /// Tries to get attributes defining display names on this attribute provider. /// If no attribute was found, null will be the result. - /// The chain follows: , and + /// The chain follows: and /// /// Provider of the attributes /// The value of the display name or null. @@ -77,7 +77,7 @@ public static string GetDisplayName(this ICustomAttributeProvider attributeProvi /// /// Tries to get attributes defining a description on this attribute provider. /// If no attribute was found, null will be the result. - /// The chain follows: , and + /// The chain follows: and /// /// Provider of the attributes /// The value of the description or null. diff --git a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleManagerTests.cs b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleManagerTests.cs index 64b5c3728..37bf00a67 100644 --- a/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleManagerTests.cs +++ b/src/Tests/Moryx.Runtime.Kernel.Tests/ModuleManagerTests.cs @@ -294,7 +294,6 @@ public void CheckLifeCycleBoundActivatedCountIs1() // Act moduleManager.StartModules(); - var i = 0; WaitForTimeboxed(() => module.State == ServerModuleState.Running); // Assert diff --git a/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs b/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs index b983856b7..6a51ad7b8 100644 --- a/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs +++ b/src/Tests/Moryx.Tests/Serialization/EntryConvertInvokeMethodTests.cs @@ -13,7 +13,6 @@ namespace Moryx.Tests public class EntryConvertInvokeMethodTests { private readonly EntrySerialize_Methods _sut; - private readonly EntrySerializeSerialization _serialization; public EntryConvertInvokeMethodTests() { _sut = new EntrySerialize_Methods(); From ae0a58efac49b9ea3c22f439708ea2ead950115e Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Thu, 31 Aug 2023 06:19:30 +0200 Subject: [PATCH 30/57] Remove calls to obsolete members in Exception base claas --- docs/migrations/v6_to_v8.md | 10 +++++- .../Components/MissingFacadeException.cs | 33 ------------------- .../Management/HealthStateException.cs | 28 ---------------- .../Configuration/InvalidConfigException.cs | 31 ----------------- 4 files changed, 9 insertions(+), 93 deletions(-) diff --git a/docs/migrations/v6_to_v8.md b/docs/migrations/v6_to_v8.md index 5f5cd6bd0..349237ca9 100644 --- a/docs/migrations/v6_to_v8.md +++ b/docs/migrations/v6_to_v8.md @@ -14,4 +14,12 @@ The DI container within modules based on Castle Windsor was refactored and simpl ## ServerModuleBase -To simplify development and prepare easier integration of the Moryx.Cli we merged the `ServerModuleFacadeControllerBase` into the `ServerModuleBase`. Just replace the base type if your module is affected by this. \ No newline at end of file +To simplify development and prepare easier integration of the Moryx.Cli we merged the `ServerModuleFacadeControllerBase` into the `ServerModuleBase`. Just replace the base type if your module is affected by this. + +## GetObjectData(SerializationInfo info, StreamingContext context) + +Removed all overrides of the obsolete method `Exception.GetObjectData(SerializationInfo info, StreamingContext context)` as well as all constructors which were calling the base class constructor `Exception(SerializationInfo info, StreamingContext context)` +The following classes are affected by this change +- MissingFacadeException +- HealthStateException +- InvalidConfigException \ No newline at end of file diff --git a/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs b/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs index 6fb12aa0f..53e1ca509 100644 --- a/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs +++ b/src/Moryx.Runtime.Kernel/Modules/Components/MissingFacadeException.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0 using System; -using System.Runtime.Serialization; namespace Moryx.Runtime.Kernel { @@ -19,19 +18,6 @@ public MissingFacadeException() { } - /// - /// Initializes a new instance with serialized data. - /// - /// The SerializationInfo that holds the serialized object data about the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - public MissingFacadeException(SerializationInfo si, StreamingContext context) - : base(si, context) - { - ModuleName = (string)si.GetValue("ModuleName", typeof(string)); - PropName = (string)si.GetValue("PropName", typeof(string)); - FacadeType = (Type)si.GetValue("FacadeType", typeof(Type)); - } - public MissingFacadeException(string moduleName, string propName, Type facadeType) : base($"Found no module hosting a facade of type {facadeType.Name} which was expected by {moduleName}.{propName}") { @@ -39,24 +25,5 @@ public MissingFacadeException(string moduleName, string propName, Type facadeTyp PropName = propName; FacadeType = facadeType; } - - /// - /// When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo - /// with information about the exception. - /// - /// The System.Runtime.Serialization.SerializationInfo that holds the serialized - /// object data about the exception being thrown. - /// The System.Runtime.Serialization.StreamingContext that contains contextual - /// information about the source or destination. - /// The info parameter is a null reference - [Obsolete("Override of an obsolete method.")] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - - info.AddValue("ModuleName", ModuleName); - info.AddValue("PropName", PropName); - info.AddValue("FacadeType", FacadeType); - } } } diff --git a/src/Moryx.Runtime/Modules/Management/HealthStateException.cs b/src/Moryx.Runtime/Modules/Management/HealthStateException.cs index aa1834cee..a341004dc 100644 --- a/src/Moryx.Runtime/Modules/Management/HealthStateException.cs +++ b/src/Moryx.Runtime/Modules/Management/HealthStateException.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0 using System; -using System.Runtime.Serialization; namespace Moryx.Runtime.Modules { @@ -18,17 +17,6 @@ public HealthStateException() { } - /// - /// Initializes a new instance with serialized data. - /// - /// The SerializationInfo that holds the serialized object data about the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - public HealthStateException(SerializationInfo si, StreamingContext context) - : base(si, context) - { - Current = (ServerModuleState)si.GetValue("Current", typeof(ServerModuleState)); - } - /// /// Create a new instance of the to notify a facade user of an /// invalid operation @@ -48,21 +36,5 @@ public HealthStateException(ServerModuleState current) /// Gets a message that describes the current exception. /// public override string Message => $"Current HealthState {Current} of service does not allow requested operation."; - - /// - /// When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo - /// with information about the exception. - /// - /// The System.Runtime.Serialization.SerializationInfo that holds the serialized - /// object data about the exception being thrown. - /// The System.Runtime.Serialization.StreamingContext that contains contextual - /// information about the source or destination. - /// The info parameter is a null reference - [Obsolete("Override of an obsolete method.")] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("Current", Current); - } } } diff --git a/src/Moryx/Configuration/InvalidConfigException.cs b/src/Moryx/Configuration/InvalidConfigException.cs index aa9a91b98..70ab10fe7 100644 --- a/src/Moryx/Configuration/InvalidConfigException.cs +++ b/src/Moryx/Configuration/InvalidConfigException.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0 using System; -using System.Runtime.Serialization; namespace Moryx.Configuration { @@ -18,18 +17,6 @@ public InvalidConfigException() { } - /// - /// Initializes a new instance with serialized data. - /// - /// The SerializationInfo that holds the serialized object data about the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - public InvalidConfigException(SerializationInfo si, StreamingContext context) - : base(si, context) - { - FaultyEntry = si.GetValue("FaultyEntry", typeof(object)); - PropertyFailure = (string)si.GetValue("PropertyFailure", typeof(string)); - } - /// /// Signal an invalid value within the configuration /// @@ -42,24 +29,6 @@ public InvalidConfigException(object faultyEntry, string propertyFailure) PropertyFailure = propertyFailure; } - /// - /// When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo - /// with information about the exception. - /// - /// The System.Runtime.Serialization.SerializationInfo that holds the serialized - /// object data about the exception being thrown. - /// The System.Runtime.Serialization.StreamingContext that contains contextual - /// information about the source or destination. - /// The info parameter is a null reference - [Obsolete("Override of an obsolete method.")] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - - info.AddValue("FaultyEntry", FaultyEntry); - info.AddValue("PropertyFailure", PropertyFailure); - } - /// /// Optional subentry defining the faulty property /// From a1cc96315d93ae87301d70079c28424bdeb5761d Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Thu, 31 Aug 2023 11:11:37 +0200 Subject: [PATCH 31/57] Clean up --- .../Resources/ResourceManager.cs | 62 ++++--------------- .../Resources/ResourceProxy.cs | 12 ++-- .../TypeControllerTests.cs | 1 + 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index 6be713ea1..02e2c311d 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -1,11 +1,6 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Castle.Core.Resource; using Microsoft.Extensions.Logging; using Moryx.AbstractionLayer.Capabilities; using Moryx.AbstractionLayer.Resources; @@ -15,6 +10,10 @@ using Moryx.Modules; using Moryx.Resources.Model; using Moryx.Tools; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using IResource = Moryx.AbstractionLayer.Resources.IResource; namespace Moryx.Resources.Management @@ -99,8 +98,6 @@ private enum ResourceStartupPhase /// private readonly object _fallbackLock = new(); - private List _failedResources = new(); - #endregion #region LifeCycle @@ -122,32 +119,10 @@ public void Initialize() _startup = ResourceStartupPhase.Initializing; // initialize resources - var availableResources = Graph - .GetAll() - .Except(_failedResources) - .Select(x => x as Resource); - Parallel.ForEach(availableResources, InitializeResource); + Parallel.ForEach(Graph.GetAll(), InitializeResource); _startup = ResourceStartupPhase.Initialized; } - /// - /// Handles the failed resource by adding it to the list of failed resources - /// - /// Failed resource - /// Exception that cause this resource to fail - /// Resource failed during Initialization. default true - private void HandleResourceFailed(Resource resource, Exception e, bool failedDuringInitialization = true) - { - //populate the failed resources list for tracking - lock (_failedResources) - { - if(_failedResources.FirstOrDefault(x => x.Id == resource.Id) is null) - _failedResources.Add(resource); - } - var label = failedDuringInitialization == true ? "initialize":"start"; - Logger.Log(LogLevel.Warning, e, "Failed to {0} resource {1}-{2}", label, resource.Id, resource.Name); - } - /// /// Handles the initialization of the resource /// @@ -160,7 +135,9 @@ private void InitializeResource(Resource resource) } catch (Exception e) { - HandleResourceFailed(resource, e); + Logger.Log(LogLevel.Warning, e, "Failed to initialize resource {0}-{1}", resource.Id, resource.Name); + //remove the failed resource from the Graph + Graph.Remove(resource); } } @@ -173,11 +150,10 @@ private void StartResource(Resource resource) try { ((IPlugin)resource).Start(); - HandleResourceStarted(resource); } catch (Exception e) { - HandleResourceFailed(resource, e,false); + Logger.Log(LogLevel.Warning, e, "Failed to start resource {0}-{1}", resource.Id, resource.Name); } } @@ -200,20 +176,6 @@ private void LoadResources(ICollection allResources) RegisterEvents(resource); } - /// - /// Handles the resource started by adding it to the list of running resources and removes it from failed resources - /// - /// Started resource - private void HandleResourceStarted(IResource resource) - { - lock (_failedResources) - { - //check if the resource exist in failed resources - if (_failedResources.FirstOrDefault(x => x.Id == resource.Id) is not null) - _failedResources.Remove(resource); - } - } - /// /// Add resource to all collections and register to the event /// @@ -261,7 +223,7 @@ private void InitializeAndStart(Resource resource) InitializeResource(resource); StartResource(resource); } - + /// /// Register a resources events /// @@ -482,9 +444,7 @@ private void RaiseResourceRemoved(IResource newResource) private void RaiseCapabilitiesChanged(object originalSender, ICapabilities capabilities) { - var availableResources = Graph.GetAll().Except(_failedResources); - // Only forward events for available resources - if (availableResources.Any(x => x.Id == ((IResource)originalSender).Id)) + if (Graph.GetAll().Any(x => x.Id == ((IResource)originalSender).Id)) CapabilitiesChanged?.Invoke(originalSender, capabilities); } diff --git a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs index 7fc863e89..7748c99f9 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceProxy.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceProxy.cs @@ -19,11 +19,7 @@ internal abstract class ResourceProxy : IResource /// private IResourceTypeController _typeController; - public event EventHandler CapabilitiesChanged - { - add { Target.CapabilitiesChanged += value; } - remove { Target.CapabilitiesChanged -= value; } - } + public event EventHandler CapabilitiesChanged; /// /// Target resource of the proxy @@ -37,8 +33,10 @@ protected ResourceProxy(IResource target, IResourceTypeController typeController { Target = target; _typeController = typeController; + Target.CapabilitiesChanged += OnCapabilitiesChanged; } + /// long IResource.Id => Target.Id; @@ -62,6 +60,10 @@ public override string ToString() return Target.ToString(); } + private void OnCapabilitiesChanged(object sender, ICapabilities e) + { + CapabilitiesChanged?.Invoke(this, e); + } /// /// Convert a referenced instance to a proxy /// diff --git a/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs b/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs index 9de8553d9..912302047 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/TypeControllerTests.cs @@ -180,6 +180,7 @@ public void ForwardEventsFromProxy() Assert.NotNull(eventSender3); Assert.AreNotEqual(0, eventValue); Assert.AreEqual(proxy, eventSender); + Assert.AreEqual(proxy, eventSender3); Assert.AreEqual(NullCapabilities.Instance, capabilitiesValue); Assert.AreEqual(100, eventValue); Assert.IsTrue(finallyEven); From b2cfa768489cef35e9976be85e97b81c3614d7cf Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Thu, 31 Aug 2023 20:16:00 +0200 Subject: [PATCH 32/57] Final review and polish --- .../Resources/ResourceManager.cs | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Moryx.Resources.Management/Resources/ResourceManager.cs b/src/Moryx.Resources.Management/Resources/ResourceManager.cs index 02e2c311d..73ec82220 100644 --- a/src/Moryx.Resources.Management/Resources/ResourceManager.cs +++ b/src/Moryx.Resources.Management/Resources/ResourceManager.cs @@ -98,6 +98,11 @@ private enum ResourceStartupPhase /// private readonly object _fallbackLock = new(); + /// + /// Look-up of resources that failed during init or start and are excluded from certain calls + /// + private List _failedResources = new List(); + #endregion #region LifeCycle @@ -136,8 +141,9 @@ private void InitializeResource(Resource resource) catch (Exception e) { Logger.Log(LogLevel.Warning, e, "Failed to initialize resource {0}-{1}", resource.Id, resource.Name); - //remove the failed resource from the Graph - Graph.Remove(resource); + // Track resources as failed to exclude from future calls + lock (_failedResources) + _failedResources.Add(resource); } } @@ -163,10 +169,7 @@ private void StartResource(Resource resource) private void LoadResources(ICollection allResources) { // Create resource objects on multiple threads - var query = from template in allResources.AsParallel() - select template.Instantiate(TypeController, Graph); - foreach (var resource in query) - AddResource(resource, false); + Parallel.ForEach(allResources, InstantiateResource); // Link them to each other Parallel.ForEach(allResources, LinkReferences); @@ -176,6 +179,22 @@ private void LoadResources(ICollection allResources) RegisterEvents(resource); } + /// + /// Instantiate object from entity based template + /// + private void InstantiateResource(ResourceEntityAccessor template) + { + try + { + var resource = template.Instantiate(TypeController, Graph); + AddResource(resource, false); + } + catch (Exception e) + { + Logger.Log(LogLevel.Warning, e, "Failed to instantiate resource {0}-{1}", template.Id, template.Name); + } + } + /// /// Add resource to all collections and register to the event /// @@ -269,7 +288,7 @@ public void Start() { // start resources _startup = ResourceStartupPhase.Starting; - Parallel.ForEach(Graph.GetAll(), StartResource); + Parallel.ForEach(Graph.GetAll().Except(_failedResources), StartResource); _startup = ResourceStartupPhase.Started; } From f7f82888372b138b94bda56b5e9e8b3f745ad36d Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Thu, 31 Aug 2023 21:18:05 +0200 Subject: [PATCH 33/57] Fix container tests --- .../Moryx.Container.Tests/Local/ConfiguredComponent.cs | 6 +++--- .../Moryx.Container.Tests/Local/LocalComponent.cs | 2 +- .../Moryx.Container.Tests/Local/NamedComponents.cs | 4 ++-- src/Tests/Moryx.Container.Tests/Named/Component.cs | 10 +++++----- .../Moryx.Container.Tests/Registrator/NamedDummy.cs | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Tests/Moryx.Container.Tests/Local/ConfiguredComponent.cs b/src/Tests/Moryx.Container.Tests/Local/ConfiguredComponent.cs index c1b670b98..a721f5c65 100644 --- a/src/Tests/Moryx.Container.Tests/Local/ConfiguredComponent.cs +++ b/src/Tests/Moryx.Container.Tests/Local/ConfiguredComponent.cs @@ -6,7 +6,7 @@ namespace Moryx.Container.Tests { [Plugin(LifeCycle.Singleton, typeof(IRootClass), Name = PluginName)] - internal class RootClass : IRootClass + public class RootClass : IRootClass { internal const string PluginName = "RootClass"; @@ -33,7 +33,7 @@ public void Stop() } [Plugin(LifeCycle.Singleton, typeof(IConfiguredComponent), Name = PluginName)] - internal class ConfiguredComponentA : IConfiguredComponent + public class ConfiguredComponentA : IConfiguredComponent { internal const string PluginName = "ConfiguredA"; @@ -59,7 +59,7 @@ public void Stop() } [Plugin(LifeCycle.Singleton, typeof(IConfiguredComponent), Name = PluginName)] - internal class ConfiguredComponentB : IConfiguredComponent + public class ConfiguredComponentB : IConfiguredComponent { internal const string PluginName = "ConfiguredB"; diff --git a/src/Tests/Moryx.Container.Tests/Local/LocalComponent.cs b/src/Tests/Moryx.Container.Tests/Local/LocalComponent.cs index 3676e0e96..5c66c47ce 100644 --- a/src/Tests/Moryx.Container.Tests/Local/LocalComponent.cs +++ b/src/Tests/Moryx.Container.Tests/Local/LocalComponent.cs @@ -8,7 +8,7 @@ public interface ILocalComponent } [Plugin(LifeCycle.Transient, typeof(ILocalComponent))] - internal class LocalComponent : ILocalComponent + public class LocalComponent : ILocalComponent { } diff --git a/src/Tests/Moryx.Container.Tests/Local/NamedComponents.cs b/src/Tests/Moryx.Container.Tests/Local/NamedComponents.cs index 7456f4d45..e46a5a0cd 100644 --- a/src/Tests/Moryx.Container.Tests/Local/NamedComponents.cs +++ b/src/Tests/Moryx.Container.Tests/Local/NamedComponents.cs @@ -9,7 +9,7 @@ public interface INamedComponent } [Plugin(LifeCycle.Transient, typeof(INamedComponent), Name = ComponentName)] - internal class NamedComponentA : INamedComponent + public class NamedComponentA : INamedComponent { internal const string ComponentName = "CompA"; @@ -20,7 +20,7 @@ public string GetName() } [Plugin(LifeCycle.Transient, typeof(INamedComponent), Name = ComponentName)] - internal class NamedComponentB : INamedComponent + public class NamedComponentB : INamedComponent { internal const string ComponentName = "CompB"; diff --git a/src/Tests/Moryx.Container.Tests/Named/Component.cs b/src/Tests/Moryx.Container.Tests/Named/Component.cs index 19e62fedf..3e08800f3 100644 --- a/src/Tests/Moryx.Container.Tests/Named/Component.cs +++ b/src/Tests/Moryx.Container.Tests/Named/Component.cs @@ -4,7 +4,7 @@ namespace Moryx.Container.Tests { [Component(LifeCycle.Singleton)] - internal class Component + public class Component { public IDependency Unnamed { get; set; } @@ -15,18 +15,18 @@ internal class Component public IDependency DepB { get; set; } } - internal class Impossible + public class Impossible { [Named("DepC")] public IDependency DepC { get; set; } } - internal interface IDependency + public interface IDependency { string GetName(); } - internal class DependencyA : IDependency + public class DependencyA : IDependency { public string GetName() { @@ -34,7 +34,7 @@ public string GetName() } } - internal class DependencyB : IDependency + public class DependencyB : IDependency { public string GetName() { diff --git a/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs b/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs index f6b433b6b..7f4a2b9d2 100644 --- a/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs +++ b/src/Tests/Moryx.Container.Tests/Registrator/NamedDummy.cs @@ -4,12 +4,12 @@ namespace Moryx.Container.Tests { [Component(LifeCycle.Transient, Name = "Dummy")] - internal class NamedDummy + public class NamedDummy { } [Component(LifeCycle.Transient)] - internal class UnnamedDummy + public class UnnamedDummy { } From 7873e73ccac02f8fc5fa03a7690ed9d7fa858448 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Wed, 25 Oct 2023 10:13:28 +0200 Subject: [PATCH 34/57] Fix build --- .../Mocks/ResourceWithGenericMethod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithGenericMethod.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithGenericMethod.cs index 916dfd607..4220b98bd 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithGenericMethod.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ResourceWithGenericMethod.cs @@ -11,7 +11,7 @@ namespace Moryx.Resources.Management.Tests { - public interface IGenericMethodCall : IPublicResource + public interface IGenericMethodCall : IResource { /// /// Get channel using specialized API From 54ed3e4dac514b6f21b0f5a2fe32e247da3c094b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 07:57:24 +0000 Subject: [PATCH 35/57] Bump Microsoft.SourceLink.GitHub from 1.1.1 to 8.0.0 Bumps [Microsoft.SourceLink.GitHub](https://github.com/dotnet/sourcelink) from 1.1.1 to 8.0.0. - [Release notes](https://github.com/dotnet/sourcelink/releases) - [Commits](https://github.com/dotnet/sourcelink/commits) --- updated-dependencies: - dependency-name: Microsoft.SourceLink.GitHub dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index dbfeec834..583fb3d20 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -12,7 +12,7 @@ - + From ae13d0e9eea886e8b0be4195932423ac2d46c411 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Mon, 20 Nov 2023 09:33:06 +0100 Subject: [PATCH 36/57] Fix Build Pipeline --- src/Moryx/Moryx.csproj | 2 +- .../Moryx.Runtime.Endpoints.IntegrationTests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Moryx/Moryx.csproj b/src/Moryx/Moryx.csproj index 59b1d245f..e511c0dc0 100644 --- a/src/Moryx/Moryx.csproj +++ b/src/Moryx/Moryx.csproj @@ -8,7 +8,7 @@ MORYX;Serialization;Configuration;Logging;Core;Modules;Workplans - + HAVE_TCP_KEEPALIVE diff --git a/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj b/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj index a52c61b87..0d646c6b2 100644 --- a/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj +++ b/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable false From 8a416532b1bc066e10e237311192df720786ed2b Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Mon, 20 Nov 2023 07:59:40 +0100 Subject: [PATCH 37/57] Add authentication to modules endpoint To prevent unauthorized users to start and stop modules we added the previously missing authentication attribute to the ModulesEndpoint --- .../Modules/Endpoint/ModulesController.cs | 13 ++++++++++++ .../RuntimePermissions.cs | 9 +++++++++ ....Runtime.Endpoints.IntegrationTests.csproj | 20 ++++++++----------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs b/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs index 29ef4fbd6..9d8b03114 100644 --- a/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs +++ b/src/Moryx.Runtime.Endpoints/Modules/Endpoint/ModulesController.cs @@ -15,6 +15,7 @@ using Moryx.Runtime.Endpoints.Modules.Endpoint.Request; using Moryx.Runtime.Endpoints.Modules.Serialization; using Moryx.Threading; +using Microsoft.AspNetCore.Authorization; namespace Moryx.Runtime.Endpoints.Modules.Endpoint { @@ -39,6 +40,7 @@ public ActionResult GetDependencyEvaluation() [HttpGet] + [Authorize(Policy = RuntimePermissions.ModulesCanView)] public ActionResult> GetAll() { var models = new List(_moduleManager.AllModules.Count()); @@ -71,6 +73,7 @@ public ActionResult> GetAll() } [HttpGet("{moduleName}/healthstate")] + [Authorize(Policy = RuntimePermissions.ModulesCanView)] public ActionResult HealthState([FromRoute] string moduleName) { var module = _moduleManager.AllModules.FirstOrDefault(m => m.Name == moduleName); @@ -81,6 +84,7 @@ public ActionResult HealthState([FromRoute] string moduleName } [HttpGet("{moduleName}/notifications")] + [Authorize(Policy = RuntimePermissions.ModulesCanView)] public ActionResult> Notifications([FromRoute] string moduleName) { var module = _moduleManager.AllModules.FirstOrDefault(m => m.Name == moduleName); @@ -91,6 +95,7 @@ public ActionResult> Notifications([FromRou } [HttpPost("{moduleName}/start")] + [Authorize(Policy = RuntimePermissions.ModulesCanControl)] public ActionResult Start([FromRoute] string moduleName) { var module = GetModuleFromManager(moduleName); @@ -102,6 +107,7 @@ public ActionResult Start([FromRoute] string moduleName) } [HttpPost("{moduleName}/stop")] + [Authorize(Policy = RuntimePermissions.ModulesCanControl)] public ActionResult Stop([FromRoute] string moduleName) { var module = GetModuleFromManager(moduleName); @@ -113,6 +119,7 @@ public ActionResult Stop([FromRoute] string moduleName) } [HttpPost("{moduleName}/reincarnate")] + [Authorize(Policy = RuntimePermissions.ModulesCanControl)] public ActionResult Reincarnate([FromRoute] string moduleName) { var module = GetModuleFromManager(moduleName); @@ -124,6 +131,7 @@ public ActionResult Reincarnate([FromRoute] string moduleName) } [HttpPost("{moduleName}")] + [Authorize(Policy = RuntimePermissions.ModulesCanConfigure)] public ActionResult Update([FromRoute] string moduleName, [FromBody] ServerModuleModel module) { if (module == null) @@ -145,6 +153,7 @@ public ActionResult Update([FromRoute] string moduleName, [FromBody] ServerModul } [HttpPost("{moduleName}/confirm")] + [Authorize(Policy = RuntimePermissions.ModulesCanConfirmNotifications)] public ActionResult ConfirmWarning([FromRoute] string moduleName) { var module = GetModuleFromManager(moduleName); @@ -160,6 +169,7 @@ public ActionResult ConfirmWarning([FromRoute] string moduleName) } [HttpGet("{moduleName}/config")] + [Authorize(Policy = RuntimePermissions.ModulesCanViewConfiguration)] public ActionResult GetConfig([FromRoute] string moduleName) { try @@ -184,6 +194,7 @@ public ActionResult GetConfig([FromRoute] string moduleName) } [HttpPost("{moduleName}/config")] + [Authorize(Policy = RuntimePermissions.ModulesCanConfigure)] public ActionResult SetConfig([FromRoute] string moduleName, [FromBody] SaveConfigRequest request) { if (request.Config == null) @@ -212,6 +223,7 @@ public ActionResult SetConfig([FromRoute] string moduleName, [FromBody] SaveConf } [HttpGet("{moduleName}/console")] + [Authorize(Policy = RuntimePermissions.ModulesCanViewMethods)] public ActionResult> GetMethods([FromRoute] string moduleName) { var methods = Enumerable.Empty(); @@ -226,6 +238,7 @@ public ActionResult> GetMethods([FromRoute] string modu } [HttpPost("{moduleName}/console")] + [Authorize(Policy = RuntimePermissions.ModulesCanInvoke)] public ActionResult InvokeMethod([FromRoute] string moduleName, [FromBody] MethodEntry method) { if (method == null) diff --git a/src/Moryx.Runtime.Endpoints/RuntimePermissions.cs b/src/Moryx.Runtime.Endpoints/RuntimePermissions.cs index e8e80447b..d021fef4d 100644 --- a/src/Moryx.Runtime.Endpoints/RuntimePermissions.cs +++ b/src/Moryx.Runtime.Endpoints/RuntimePermissions.cs @@ -5,6 +5,7 @@ public static class RuntimePermissions private const string _prefix = "Moryx.Runtime."; private const string _databasePrefix = _prefix + "Database."; private const string _commonPrefix = _prefix + "Common."; + private const string _modulesPrefix = _prefix + "Modules."; public const string DatabaseCanView = _databasePrefix + "CanView"; public const string DatabaseCanSetAndTestConfig = _databasePrefix + "CanSetAndTestConfig"; public const string DatabaseCanCreate = _databasePrefix + "CanCreate"; @@ -13,5 +14,13 @@ public static class RuntimePermissions public const string DatabaseCanMigrateModel = _databasePrefix + "CanMigrateModel"; public const string DatabaseCanSetup = _databasePrefix + "CanSetup"; public const string CanGetGeneralInformation = _commonPrefix + "CanGetGeneralInformation"; + + public const string ModulesCanView = _modulesPrefix + "CanView"; + public const string ModulesCanViewConfiguration = _modulesPrefix + "CanViewConfiguration"; + public const string ModulesCanViewMethods = _modulesPrefix + "CanViewMethods"; + public const string ModulesCanControl = _modulesPrefix + "CanControl"; + public const string ModulesCanConfigure = _modulesPrefix + "CanConfigure"; + public const string ModulesCanConfirmNotifications = _modulesPrefix + "CanConfirmNotifications"; + public const string ModulesCanInvoke = _modulesPrefix + "CanInvoke"; } } diff --git a/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj b/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj index 0d646c6b2..5e5f646f0 100644 --- a/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj +++ b/src/Tests/Moryx.Runtime.Endpoints.IntegrationTests/Moryx.Runtime.Endpoints.IntegrationTests.csproj @@ -9,18 +9,14 @@ - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + From 2c8cb616c02e16d6c2ec1ee0103571af2306afa3 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus <37485711+1nf0rmagician@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:22:07 +0100 Subject: [PATCH 38/57] Update tools branch used for github workflow --- .github/workflows/build-and-test.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index edf6da4d2..b12fd9d00 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,7 +14,7 @@ on: - future env: - dotnet_sdk_version: '8.0.100-preview.7.23376.3' + dotnet_sdk_version: '8.0.100' REPOSITORY_NAME: ${{ github.event.repository.name }} MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package' MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json' @@ -40,34 +40,34 @@ jobs: Build: needs: [EnvVar] - uses: phoenixcontact/tools/.github/workflows/build-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/build-tool.yml@main with: dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} UnitTests: needs: [EnvVar, Build] - uses: phoenixcontact/tools/.github/workflows/unittest-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/unittest-tool.yml@main with: dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} IntegrationTests: needs: [EnvVar, Build] - uses: phoenixcontact/tools/.github/workflows/integrationtest-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/integrationtest-tool.yml@main with: dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} ReportGenerator: needs: [EnvVar, UnitTests, IntegrationTests] - uses: phoenixcontact/tools/.github/workflows/reportgenerator-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/reportgenerator-tool.yml@main with: REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} Publish-Test-Coverage: needs: [EnvVar, ReportGenerator] - uses: phoenixcontact/tools/.github/workflows/publish-test-coverage-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/publish-test-coverage-tool.yml@main with: REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} secrets: @@ -77,13 +77,13 @@ jobs: # currently not working # Documentation: # needs: [EnvVar, UnitTests] - # uses: phoenixcontact/tools/.github/workflows/documentation-tool.yml@future + # uses: phoenixcontact/tools/.github/workflows/documentation-tool.yml@main # with: # REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} Publish: needs: [EnvVar, UnitTests] - uses: phoenixcontact/tools/.github/workflows/publish-tool.yml@future + uses: phoenixcontact/tools/.github/workflows/publish-tool.yml@main with: dotnet_sdk_version: ${{ needs.EnvVar.outputs.dotnet_sdk_version }} REPOSITORY_NAME: ${{ needs.EnvVar.outputs.REPOSITORY_NAME }} @@ -95,4 +95,4 @@ jobs: MORYX_PACKAGE_TARGET_V3_RELEASE: ${{ needs.EnvVar.outputs.MORYX_PACKAGE_TARGET_V3_RELEASE }} secrets: MYGET_TOKEN: ${{secrets.MYGET_TOKEN}} - NUGET_TOKEN: ${{secrets.NUGET_TOKEN}} \ No newline at end of file + NUGET_TOKEN: ${{secrets.NUGET_TOKEN}} From 07cb7a0ad9e13916da67dec985e961e88e198a39 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Tue, 21 Nov 2023 17:33:28 +0100 Subject: [PATCH 39/57] Update packages --- Directory.Build.targets | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index dbfeec834..96a7b0e68 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -4,8 +4,8 @@ - 8.0.0-preview.* - 8.0.0-preview.* + 8.0.0 + 8.0.0 latest @@ -18,9 +18,9 @@ - + - + all From aedd751d03052f40c0af92fd1fb57d4d2487de82 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Thu, 23 Nov 2023 06:17:10 +0100 Subject: [PATCH 40/57] Bump version to 8.0.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ae9a76b92..cd1d2e94f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.0 +8.0.1 From 6ac67853262a7f4f949469bf183e7ae1847a77e4 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Tue, 28 Nov 2023 06:20:36 +0100 Subject: [PATCH 41/57] Update migration guide --- docs/migrations/v6_to_v8.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/migrations/v6_to_v8.md b/docs/migrations/v6_to_v8.md index 349237ca9..7212ddae1 100644 --- a/docs/migrations/v6_to_v8.md +++ b/docs/migrations/v6_to_v8.md @@ -22,4 +22,8 @@ Removed all overrides of the obsolete method `Exception.GetObjectData(Serializat The following classes are affected by this change - MissingFacadeException - HealthStateException -- InvalidConfigException \ No newline at end of file +- InvalidConfigException + +## Merged IPublicResource into IResource + +`IPublicResource` and `IResource` were merged into `IResource`, since the differentiaten between those was hard to understand for some and barely had any real world advantages. Now literally "Everything is a resource". \ No newline at end of file From f63bce0f9e34e6f80910111da527c5316f64a528 Mon Sep 17 00:00:00 2001 From: Matho Camara Date: Fri, 2 Feb 2024 09:37:49 +0100 Subject: [PATCH 42/57] Bump version 8.0.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cd1d2e94f..8b22a322d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.1 +8.0.2 From af1bea343534dd8f8e4ca487ff4a2da5aab9a1d7 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Wed, 21 Feb 2024 06:06:09 +0100 Subject: [PATCH 43/57] Bump version to 8.0.3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8b22a322d..215aacb45 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.2 +8.0.3 From 970ea7a8275e12670349419d79bbdf4aa7b3938b Mon Sep 17 00:00:00 2001 From: Christian Siewert Date: Tue, 23 Apr 2024 16:19:14 +0200 Subject: [PATCH 44/57] Update package feed urls --- .github/workflows/build-and-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b12fd9d00..fde8ac4b0 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -16,10 +16,10 @@ on: env: dotnet_sdk_version: '8.0.100' REPOSITORY_NAME: ${{ github.event.repository.name }} - MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package' - MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json' - MORYX_PACKAGE_TARGET_FUTURE: 'https://www.myget.org/F/moryx-future/api/v2/package' - MORYX_PACKAGE_TARGET_V3_FUTURE: 'https://www.myget.org/F/moryx-future/api/v3/index.json' + MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx-oss-ci/api/v2/package' + MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx-oss-ci/api/v3/index.json' + MORYX_PACKAGE_TARGET_FUTURE: 'https://www.myget.org/F/moryx-oss-ci/api/v2/package' + MORYX_PACKAGE_TARGET_V3_FUTURE: 'https://www.myget.org/F/moryx-oss-ci/api/v3/index.json' MORYX_PACKAGE_TARGET_RELEASE: 'https://api.nuget.org/v3/index.json' MORYX_PACKAGE_TARGET_V3_RELEASE: 'https://api.nuget.org/v3/index.json' From 1704101b5f2429f240ce0de7d8bb4c0814ac5dcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 13:09:20 +0000 Subject: [PATCH 45/57] Bump react from 18.2.0 to 18.3.1 in /src/Moryx.CommandCenter.Web Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 18.2.0 to 18.3.1. - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v18.3.1/packages/react) --- updated-dependencies: - dependency-name: react dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Moryx.CommandCenter.Web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.CommandCenter.Web/package.json b/src/Moryx.CommandCenter.Web/package.json index e5441ec98..4dc454a9d 100644 --- a/src/Moryx.CommandCenter.Web/package.json +++ b/src/Moryx.CommandCenter.Web/package.json @@ -24,7 +24,7 @@ "moment": "^2.30.1", "path-scurry": "^1.10.2", "query-string": "^9.0.0", - "react": "18.2.0", + "react": "18.3.1", "react-dom": "18.2.0", "react-redux": "^9.1.0", "react-router": "^6.22.0", From 0b520d278b0fe0dd551dcfb433a400648c6b576c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 13:11:20 +0000 Subject: [PATCH 46/57] Bump style-loader from 3.3.4 to 4.0.0 in /src/Moryx.CommandCenter.Web Bumps [style-loader](https://github.com/webpack-contrib/style-loader) from 3.3.4 to 4.0.0. - [Release notes](https://github.com/webpack-contrib/style-loader/releases) - [Changelog](https://github.com/webpack-contrib/style-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/style-loader/compare/v3.3.4...v4.0.0) --- updated-dependencies: - dependency-name: style-loader dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- src/Moryx.CommandCenter.Web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.CommandCenter.Web/package.json b/src/Moryx.CommandCenter.Web/package.json index e5441ec98..71ec2a04b 100644 --- a/src/Moryx.CommandCenter.Web/package.json +++ b/src/Moryx.CommandCenter.Web/package.json @@ -45,7 +45,7 @@ "sass": "^1.72.0", "sass-loader": "^14.1.0", "source-map-loader": "^5.0.0", - "style-loader": "^3.3.4", + "style-loader": "^4.0.0", "tslint": "^6.1.3", "tslint-loader": "^3.5.4", "tslint-react": "^5.0.0", From deedfb17a536e45b75b69b96aa2e10acb5552379 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Wed, 8 May 2024 13:24:57 +0200 Subject: [PATCH 47/57] Bump version to 8.0.4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 215aacb45..50c496d20 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.3 +8.0.4 From 2bd3e054cd16861d87eb3e3f4ee3903cee528b3f Mon Sep 17 00:00:00 2001 From: Christian Siewert Date: Thu, 16 May 2024 09:50:55 +0200 Subject: [PATCH 48/57] Use renamed `IsPackable` flag instead of `CreatePackage` This fixes, among other things, that the MORYX logo gets included in packages. --- Directory.Build.targets | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 1fb1912e2..d12d3f6bd 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,7 +1,7 @@ - + 8.0.0 @@ -10,8 +10,8 @@ latest - - + + From 3f22821169fe98f1b6fc2811e9b0c039fe45fc1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 06:37:45 +0000 Subject: [PATCH 49/57] Bump rimraf from 5.0.5 to 5.0.7 in /src/Moryx.CommandCenter.Web Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.5 to 5.0.7. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.5...v5.0.7) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- src/Moryx.CommandCenter.Web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.CommandCenter.Web/package.json b/src/Moryx.CommandCenter.Web/package.json index e5441ec98..420245622 100644 --- a/src/Moryx.CommandCenter.Web/package.json +++ b/src/Moryx.CommandCenter.Web/package.json @@ -41,7 +41,7 @@ "@types/react-router-redux": "^5.0.27", "css-loader": "^6.10.0", "html-webpack-plugin": "^5.6.0", - "rimraf": "5.0.5", + "rimraf": "5.0.7", "sass": "^1.72.0", "sass-loader": "^14.1.0", "source-map-loader": "^5.0.0", From 7684fcbb74e4b1eb02adeeab507f8e057ceb7774 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Thu, 4 Jul 2024 12:53:21 +0200 Subject: [PATCH 50/57] Bump version to 8.0.5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 50c496d20..904be6d4e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.4 +8.0.5 From 9e3e2ed0cd4be46160a119ef5b00d9c3046fba50 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Tue, 27 Aug 2024 10:13:43 +0200 Subject: [PATCH 51/57] Bump version to 8.0.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0b2eb36f5..68d92dd66 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.2 +8.0.6 From bae19109432ed56fec592d77e900e33ec3b57c99 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Wed, 28 Aug 2024 08:29:15 +0200 Subject: [PATCH 52/57] Bump version to 8.1.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index dc0208aba..8104cabd3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.3.1 +8.1.0 From c7909588fa89bed53f412598574a6f6a3ff7bef5 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Wed, 4 Sep 2024 11:24:59 +0200 Subject: [PATCH 53/57] Port NUnit test tools to release 8 --- src/Moryx.TestTools.NUnit/Moryx.TestTools.NUnit.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.TestTools.NUnit/Moryx.TestTools.NUnit.csproj b/src/Moryx.TestTools.NUnit/Moryx.TestTools.NUnit.csproj index 06fb36032..7fea020cc 100644 --- a/src/Moryx.TestTools.NUnit/Moryx.TestTools.NUnit.csproj +++ b/src/Moryx.TestTools.NUnit/Moryx.TestTools.NUnit.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable From 28c2346df11098fae01f009f2a4b58abab5cc453 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 06:32:29 +0000 Subject: [PATCH 54/57] Bump @mui/material from 5.16.7 to 6.1.1 in /src/Moryx.CommandCenter.Web Bumps [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material) from 5.16.7 to 6.1.1. - [Release notes](https://github.com/mui/material-ui/releases) - [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md) - [Commits](https://github.com/mui/material-ui/commits/v6.1.1/packages/mui-material) --- updated-dependencies: - dependency-name: "@mui/material" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- src/Moryx.CommandCenter.Web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.CommandCenter.Web/package.json b/src/Moryx.CommandCenter.Web/package.json index 1d5efcddd..c3c71c3f3 100644 --- a/src/Moryx.CommandCenter.Web/package.json +++ b/src/Moryx.CommandCenter.Web/package.json @@ -16,7 +16,7 @@ "@emotion/styled": "^11.11.5", "@mdi/js": "^7.4.47", "@mdi/react": "^1.6.1", - "@mui/material": "^5.15.15", + "@mui/material": "^6.1.1", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@types/react-redux": "^7.1.33", From d096c9367a5d6be5be67b558453d46e2e8fa0133 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:22:24 +0000 Subject: [PATCH 55/57] Bump react-dom from 18.2.0 to 18.3.1 in /src/Moryx.CommandCenter.Web Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 18.2.0 to 18.3.1. - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v18.3.1/packages/react-dom) --- updated-dependencies: - dependency-name: react-dom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Moryx.CommandCenter.Web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Moryx.CommandCenter.Web/package.json b/src/Moryx.CommandCenter.Web/package.json index c3c71c3f3..19dba0c84 100644 --- a/src/Moryx.CommandCenter.Web/package.json +++ b/src/Moryx.CommandCenter.Web/package.json @@ -25,7 +25,7 @@ "path-scurry": "^1.10.2", "query-string": "^9.0.0", "react": "18.3.1", - "react-dom": "18.2.0", + "react-dom": "18.3.1", "react-redux": "^9.1.0", "react-router": "^6.22.0", "react-router-dom": "^6.22.0", From e767bdf4baf55ae7a81f69356984778211ce6416 Mon Sep 17 00:00:00 2001 From: Thomas Fuchs Date: Wed, 23 Oct 2024 08:38:06 +0200 Subject: [PATCH 56/57] Fix build with adjusted namespace and increment version --- VERSION | 2 +- .../ProductManagementController.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 8104cabd3..fbb9ea12d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.1.0 +8.2.0 diff --git a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs index 963731e65..5f41351e3 100644 --- a/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs +++ b/src/Moryx.AbstractionLayer.Products.Endpoints/ProductManagementController.cs @@ -18,7 +18,6 @@ using Moryx.AbstractionLayer.Resources; using Moryx.Runtime.Modules; using System.ComponentModel; -using Moryx.Runtime.Container; namespace Moryx.AbstractionLayer.Products.Endpoints { @@ -39,8 +38,7 @@ public ProductManagementController(IProductManagement productManagement, _productManagement = productManagement; var module = moduleManager.AllModules.FirstOrDefault(module => module is IFacadeContainer); - var host = (IContainerHost)module; - _productConverter = new ProductConverter(_productManagement, host.Container, serviceProvider); + _productConverter = new ProductConverter(_productManagement, module.Container, serviceProvider); } #region importers From dfa2bd440a20c695fdc8b7f244fe21590506cd8d Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Thu, 21 Nov 2024 14:27:44 +0100 Subject: [PATCH 57/57] Port: Fix exception on creating a bidirectional link to a new resource to release 8 --- .../Mocks/ReferenceResource.cs | 2 +- .../Moryx.Resources.Management.Tests/ResourceLinkerTests.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs index 50e0dc9c8..8ce461631 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/Mocks/ReferenceResource.cs @@ -111,7 +111,7 @@ public void SetMany(IReadOnlyList references) public event EventHandler SomeChanged; } - public class BidirectionalReferenceResource : PublicResource + public class BidirectionalReferenceResource : Resource { [ResourceReference(ResourceRelationType.Extension, ResourceReferenceRole.Source, nameof(SourceReference))] public ReferenceResource SourceReference { get; set; } diff --git a/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs b/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs index 2a0e580c7..c068bf9ee 100644 --- a/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs +++ b/src/Tests/Moryx.Resources.Management.Tests/ResourceLinkerTests.cs @@ -141,9 +141,9 @@ public void SaveBidirectionalReferences() var newCollectionResource = new SimpleResource() { Name = "newCollectionResource" }; ResourceReferenceTools.InitializeCollections(newCollectionResource); // Fill graph - _graph[1] = new ResourceWrapper(instance); - _graph[2] = new ResourceWrapper(resource); - _graph[3] = new ResourceWrapper(collectionResource); + _graph[1] = instance; + _graph[2] = resource; + _graph[3] = collectionResource; // Set single references instance.TargetReference = resource; // The bidirectional reference is created with an existing resource instance.NewTargetReference = newResource; // The bidirectional reference is created with a new resource