调用静态方法时使用特定 type/assembly - Powershell

Use specific type/assembly when calling a static method - Powershell

我正在使用静态方法:

[Microsoft.AnalysisServices.Tabular.JsonSerializer]::DeserializeDatabase($filePath)

通过我多年支持此代码,我学会了加载显式程序集,并且 喜欢:

Add-Type -AssemblyName "Microsoft.AnalysisServices, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

New-Object -TypeName "Microsoft.AnalysisServices.Tabular.Server, Microsoft.AnalysisServices.Tabular, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

因为 sqlserver PowerShell 模块包含它们自己版本的程序集,这些版本与我们 运行 的 SSAS 版本不兼容,所以我们陷入了“localapp”版本之间的 dll 地狱模块和我已明确加载到 GAC 中的版本。

具体来说,sqlserver 模块正在加载 Microsoft.AnalysisServices, Version=Version=18.2.2.0,并且因为它没有与所有 TOM 程序集捆绑在一起,所以期望 GAC 中存在相同版本的 Microsoft.AnalysisServices.Tabular.Json (它没有)。我可以通过找到我需要的程序集的 v18 版本并将它们安装到 GAC(尽管我发现较新的版本与我 运行ning 的 SSAS 版本不兼容)或通过删除来自 sqlserver 模块的程序集,因此仅使用我在 GAC 中安装的程序集。

我的问题是,当我从 static class 调用静态方法时,是否有类似的方法让我说出我想使用哪种特定 assembly/loaded 类型 version/token这个特定方法的调用方式与我使用 New-Object 和完全限定名称时的类似方式调用,以便明确告诉 Powershell 使用哪个 assembly/type 以便它不会尝试加载较新的版本?

好消息!

具体类型是否标记为 static 并不重要 - 类型文字语法保持不变,因此您应该能够在正确的程序集中解析该方法:

[Microsoft.AnalysisServices.Tabular.JsonSerializer, Microsoft.AnalysisServices.Tabular, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91]::DeserializeDatabase($filePath)

或:

$typeName = 'Microsoft.AnalysisServices.Tabular.JsonSerializer, Microsoft.AnalysisServices.Tabular, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'

$($typeName -as [type])::DeserializeDatabase($filePath)

奖金提示!

由于程序集限定的类型名称在通读代码时可能会变得很长且让人分心,您可能希望将所需的类型引用存储在一个或多个变量中:

# Create hashtable
$ASTabularV14 = @{}

# Use existing public type to obtain assembly reference and populate our hashtable
$type = [Microsoft.AnalysisServices.Tabular.JsonSerializer, Microsoft.AnalysisServices.Tabular, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91]
$publicTabularTypes = $type.Assembly.GetTypes().Where({
  $_.IsPublic -and -not $_.IsAbstract -and $_.Namespace -eq 'Microsoft.AnalysisServices.Tabular'
}).ForEach({ $ASTabularV14[$_.Name] = $_ })

现在我们有了自己的小“类固醇类型加速器”,我们可以稍后在脚本中重用它:

# ... later on in your script

$deserializedDatabase = $ASTabularV14['Serializer']::DeserializeDatabase($dbData)
$resultOfSomeServerOperation = $ASTabularV14['Server']::DoStuff()