Skip to content

Commit d7c5fbe

Browse files
authored
BREAKING: V2 candidate, add caching of properties not in desired state (#39)
1 parent cc95910 commit d7c5fbe

File tree

4 files changed

+204
-670
lines changed

4 files changed

+204
-670
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- `azure-pipelines.yml`
1111
- Remove `windows-2019` images fixes [#43](https://github.com/dsccommunity/DscResource.Base/issues/43)
1212
- Move individual tasks to `windows-latest`.
13+
- `ResourceBase`
14+
- Cache properties not in desired state.
15+
- Make `Set()` call `Test()` and `Test()` call `Get()`.
16+
17+
### Removed
18+
19+
- `ResourceBase`
20+
- Remove `Compare()` method as not used.
21+
- Removed feature flags and alternate behavior.
1322

1423
## [1.4.0] - 2025-05-24
1524

source/Classes/010.ResourceBase.ps1

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ class ResourceBase
1919
# Property for derived class to set properties that should not be enforced.
2020
hidden [System.String[]] $ExcludeDscProperties = @()
2121

22-
# Property for derived class to enable Enums to be used as optional properties. The usable Enum values should start at value 1.
23-
hidden [System.Boolean] $FeatureOptionalEnums = $false
22+
# Property for holding the properties that are not in desired state.
23+
hidden [System.Collections.Hashtable[]] $PropertiesNotInDesiredState = @()
24+
25+
# Property for holding the desired state.
26+
hidden [System.Collections.Hashtable] $CachedDesiredState = $null
27+
28+
# Property for holding the key properties.
29+
hidden [System.Collections.Hashtable] $CachedKeyProperties = $null
2430

2531
# Default constructor
2632
ResourceBase()
@@ -58,16 +64,17 @@ class ResourceBase
5864

5965
[ResourceBase] Get()
6066
{
67+
$this.SetCachedKeyProperties()
68+
69+
$this.CachedDesiredState = $this.GetDesiredState()
70+
6171
$this.Normalize()
6272

6373
$this.Assert()
6474

65-
# Get all key properties.
66-
$keyProperty = $this | Get-DscProperty -Attribute 'Key'
67-
68-
Write-Verbose -Message ($this.localizedData.GetCurrentState -f $this.GetType().Name, ($keyProperty | ConvertTo-Json -Compress))
75+
Write-Verbose -Message ($this.localizedData.GetCurrentState -f $this.GetType().Name, ($this.CachedKeyProperties | ConvertTo-Json -Compress))
6976

70-
$getCurrentStateResult = $this.GetCurrentState($keyProperty)
77+
$getCurrentStateResult = $this.GetCurrentState($this.CachedKeyProperties)
7178

7279
$dscResourceObject = [System.Activator]::CreateInstance($this.GetType())
7380

@@ -83,12 +90,13 @@ class ResourceBase
8390
$keyPropertyAddedToCurrentState = $false
8491

8592
# Set key property values unless it was returned from the derived class' GetCurrentState().
86-
foreach ($propertyName in $keyProperty.Keys)
93+
foreach ($propertyName in $this.CachedKeyProperties.Keys)
8794
{
8895
if ($propertyName -notin @($getCurrentStateResult.Keys))
8996
{
9097
# Add the key value to the instance to be returned.
9198
$dscResourceObject.$propertyName = $this.$propertyName
99+
$getCurrentStateResult.$propertyName = $this.$propertyName
92100

93101
$keyPropertyAddedToCurrentState = $true
94102
}
@@ -117,7 +125,7 @@ class ResourceBase
117125
Returns all enforced properties not in desired state, or $null if
118126
all enforced properties are in desired state.
119127
#>
120-
$propertiesNotInDesiredState = $this.Compare($getCurrentStateResult, @())
128+
$this.PropertiesNotInDesiredState = $this.Compare($getCurrentStateResult, @())
121129

122130
<#
123131
Return the correct values for Reasons property if the derived DSC resource
@@ -126,7 +134,7 @@ class ResourceBase
126134
if (($this | Test-DscProperty -Name 'Reasons') -and -not $getCurrentStateResult.ContainsKey('Reasons'))
127135
{
128136
# Always return an empty array if all properties are in desired state.
129-
$dscResourceObject.Reasons = $propertiesNotInDesiredState |
137+
$dscResourceObject.Reasons = $this.PropertiesNotInDesiredState |
130138
Resolve-Reason -ResourceName $this.GetType().Name |
131139
ConvertFrom-Reason
132140
}
@@ -137,53 +145,38 @@ class ResourceBase
137145

138146
[void] Set()
139147
{
140-
# Get all key properties.
141-
$keyProperty = $this | Get-DscProperty -Attribute 'Key'
142-
143-
Write-Verbose -Message ($this.localizedData.SetDesiredState -f $this.GetType().Name, ($keyProperty | ConvertTo-Json -Compress))
148+
Write-Verbose -Message ($this.localizedData.SetDesiredState -f $this.GetType().Name)
144149

145-
<#
146-
Returns all enforced properties not in desires state, or $null if
147-
all enforced properties are in desired state.
148-
#>
149-
$propertiesNotInDesiredState = $this.Compare()
150-
151-
if ($propertiesNotInDesiredState)
152-
{
153-
$propertiesToModify = $propertiesNotInDesiredState | ConvertFrom-CompareResult
154-
155-
$propertiesToModify.Keys |
156-
ForEach-Object -Process {
157-
Write-Verbose -Message ($this.localizedData.SetProperty -f $_, $propertiesToModify.$_)
158-
}
159-
160-
<#
161-
Call the Modify() method with the properties that should be enforced
162-
and are not in desired state.
163-
#>
164-
$this.Modify($propertiesToModify)
165-
}
166-
else
150+
if ($this.Test())
167151
{
168152
Write-Verbose -Message $this.localizedData.NoPropertiesToSet
153+
return
169154
}
170-
}
171155

172-
[System.Boolean] Test()
173-
{
174-
# Get all key properties.
175-
$keyProperty = $this | Get-DscProperty -Attribute 'Key'
156+
# $this.PropertiesNotInDesiredState was set by the Get() method.
157+
# The Get() method is called by Test().
158+
$propertiesToModify = $this.PropertiesNotInDesiredState | ConvertFrom-CompareResult
176159

177-
Write-Verbose -Message ($this.localizedData.TestDesiredState -f $this.GetType().Name, ($keyProperty | ConvertTo-Json -Compress))
160+
$propertiesToModify.Keys |
161+
ForEach-Object -Process {
162+
Write-Verbose -Message ($this.localizedData.SetProperty -f $_, $propertiesToModify.$_)
163+
}
178164

179165
<#
180-
Returns all enforced properties not in desired state, or $null if
181-
all enforced properties are in desired state.
182-
Will call Get().
166+
Call the Modify() method with the properties that should be enforced
167+
and are not in desired state.
183168
#>
184-
$propertiesNotInDesiredState = $this.Compare()
169+
$this.Modify($propertiesToModify)
170+
}
185171

186-
if ($propertiesNotInDesiredState)
172+
[System.Boolean] Test()
173+
{
174+
Write-Verbose -Message ($this.localizedData.TestDesiredState -f $this.GetType().Name)
175+
176+
$null = $this.Get()
177+
178+
# $this.PropertiesNotInDesiredState was set by the Get() method.
179+
if ($this.PropertiesNotInDesiredState)
187180
{
188181
Write-Verbose -Message $this.localizedData.NotInDesiredState
189182
return $false
@@ -199,30 +192,16 @@ class ResourceBase
199192
desired state.
200193
201194
This method should normally not be overridden.
202-
#>
203-
hidden [System.Collections.Hashtable[]] Compare()
204-
{
205-
# Get the current state, all properties except Read properties .
206-
$currentState = $this.Get() | Get-DscProperty -Attribute @('Key', 'Mandatory', 'Optional')
207-
208-
return $this.Compare($currentState, @())
209-
}
210-
211-
<#
212-
Returns a hashtable containing all properties that should be enforced and
213-
are not in desired state, or $null if all enforced properties are in
214-
desired state.
215195
216-
This method should normally not be overridden.
196+
This method is only used by Get().
217197
#>
218198
hidden [System.Collections.Hashtable[]] Compare([System.Collections.Hashtable] $currentState, [System.String[]] $excludeProperties)
219199
{
220-
$desiredState = $this.GetDesiredState()
221-
200+
# $this.CachedDesiredState was set by the Get() method.
222201
$CompareDscParameterState = @{
223202
CurrentValues = $currentState
224-
DesiredValues = $desiredState
225-
Properties = $desiredState.Keys
203+
DesiredValues = $this.CachedDesiredState
204+
Properties = $this.CachedDesiredState.Keys
226205
ExcludeProperties = ($excludeProperties + $this.ExcludeDscProperties) | Select-Object -Unique
227206
IncludeValue = $true
228207
# This is needed to sort complex types.
@@ -239,30 +218,26 @@ class ResourceBase
239218
# This method should normally not be overridden.
240219
hidden [void] Assert()
241220
{
242-
$this.AssertProperties($this.GetDesiredState())
221+
$this.AssertProperties($this.CachedDesiredState)
243222
}
244223

245224
# This method should normally not be overridden.
246225
hidden [void] Normalize()
247226
{
248-
$this.NormalizeProperties($this.GetDesiredState())
227+
$this.NormalizeProperties($this.CachedDesiredState)
249228
}
250229

251230
# This is a private method and should normally not be overridden.
252231
hidden [System.Collections.Hashtable] GetDesiredState()
253232
{
254233
$getDscPropertyParameters = @{
255-
Attribute = @(
234+
Attribute = @(
256235
'Key'
257236
'Mandatory'
258237
'Optional'
259238
)
260-
HasValue = $true
261-
}
262-
263-
if ($this.FeatureOptionalEnums)
264-
{
265-
$getDscPropertyParameters.IgnoreZeroEnumValue = $true
239+
HasValue = $true
240+
IgnoreZeroEnumValue = $true
266241
}
267242

268243
# Get the properties that has a non-null value and is not of type Read.
@@ -271,6 +246,13 @@ class ResourceBase
271246
return $desiredState
272247
}
273248

249+
# This is a private method and should normally not be overridden.
250+
hidden [void] SetCachedKeyProperties()
251+
{
252+
# Sets the key properties of the resource.
253+
$this.CachedKeyProperties = $this | Get-DscProperty -Attribute 'Key'
254+
}
255+
274256
<#
275257
This method can be overridden if resource specific property asserts are
276258
needed. The parameter properties will contain the properties that are

source/en-US/ResourceBase.strings.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
ConvertFrom-StringData @'
88
GetCurrentState = Getting the current state for resource '{0}' using the key property '{1}'. (RB0001)
9-
TestDesiredState = Determining the current state for resource '{0}' using the key property '{1}'. (RB0002)
10-
SetDesiredState = Setting the desired state for resource '{0}' using the key property '{1}'. (RB0003)
9+
TestDesiredState = Determining the current state for resource '{0}'. (RB0002)
10+
SetDesiredState = Setting the desired state for resource '{0}'. (RB0003)
1111
NotInDesiredState = The current state is not the desired state. (RB0004)
1212
InDesiredState = The current state is the desired state. (RB0005)
1313
SetProperty = The property '{0}' will be set to '{1}'. (RB0006)

0 commit comments

Comments
 (0)