-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
It seems like certain things can only be defined once per PowerShell session. Public enums named in calls to Add-Type are one such example. In the repro below, a .Net enum of a particular name could only be defined once even though the two definitions are in separate modules. Working around such naming collisions amongst unrelated modules is usually a one-time event. However, the same problem manifests when more than one version of the same module is required to exist in a single session. This occurs every time a .Net type in a low-level module changes and the mid-level modules aren't updated simultaneously. I've been running into this problem in PowerShell with increasing frequency as I incorporate more third-party libraries and as my code has become more modular.
As far as I've read this problem is called "the diamond dependency problem" (video). The repro below demonstrates the canonical scenario described in the video in PowerShell.
There seems to be some signs that C# projects can load multiple versions of the same assembly thereby averting the diamond dependency problem (e.g. stackoverflow question). Is there a similar strategy that works in PowerShell?
Steps to reproduce
New-Module libutil_v1 {
Add-Type -TypeDefinition 'public enum E {a,b,c}'
function f {
param
(
[e]
$E
)
}
} | Import-Module
New-Module libutil_v2 {
Add-Type -TypeDefinition 'public enum E {a,b,c,d}'
function f {
param
(
[e]
$E
)
}
} | Import-Module
New-Module liba {
Get-Module libutil_v1 | Import-Module
function g_a {
f -E c
}
} | Import-Module
New-Module libb {
Get-Module libutil_v2 | Import-Module
function g_b {
f -E d
}
} | Import-Module
g_a
g_bExpected behavior
No exception thrown.
Actual behavior
Add-Type : Cannot add type. The type name 'E' already exists.
At C:\users\un1\Desktop\test.ps1:13 char:5
+ Add-Type -TypeDefinition 'public enum E {a,b,c,d}'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (E:String) [Add-Type], Excepti
on
+ FullyQualifiedErrorId : TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Command
s.AddTypeCommand
f : Cannot process argument transformation on parameter 'E'. Cannot convert
value "d" to type "E". Error: "Unable to match the identifier name d to a
valid enumerator name. Specify one of the following enumerator names and try
again:
a, b, c"
At C:\users\un1\Desktop\test.ps1:35 char:14
+ f -E d
+ ~
+ CategoryInfo : InvalidData: (:) [f], ParameterBindingArgumentTr
ansformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,f
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.0-beta.8
PSEdition Core
GitCommitId v6.0.0-beta.8
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0