如何在其他 Add-Type 类型定义中访问 Add-Type 定义的类型? [英] How to access Add-Type defined type in other Add-Type type definition?

查看:62
本文介绍了如何在其他 Add-Type 类型定义中访问 Add-Type 定义的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在另一个Add-Type -TypeDefinition "..."中访问Add-Type -TypeDefinition "..."定义的类型?

在下面的代码示例中,尽管命名空间相同,但编译器无法找到 UserCode 类型.

Add-Type -TypeDefinition @"命名空间示例代码 {公共结构用户代码{公共字符串名称;公共字符串 ID;}}"@#.... 做一点事 ....添加类型 -TypeDefinition @"命名空间示例代码 {公共结构用户信息{公共用户代码用户;公共字符串注意;}}"@# =>错误...添加类型:<临时源路径>(3):类型或命名空间名称# 找不到UserCode"(您是否缺少 using 指令或程序集# 参考?)

解决方案

为了从第二个 .NET 程序集引用第一个 .NET 程序集,您需要将第一个 .NET 程序集持久化到磁盘.完成此操作后,您可以使用 Add-Type cmdlet 的 -ReferencedAssemblies 参数从第二个 .NET 程序集引用第一个 .NET 程序集.

重要事项:如果您在两个不同的 C# 代码块中使用两个不同的命名空间,请确保在第二个代码块中正确声明您的 using 语句.

这是一个示例,向您展示如何:

  1. 将新的 .NET 程序集动态编译到磁盘
  2. 导入引用磁盘上另一个程序集的动态程序集

第 1 部分 - 组装 #1

第一个 .NET 程序集必须输出到磁盘,以便我们可以引用它.因此,我们将使用 Add-Type cmdlet 的 -OutputAssembly-OutputType 参数来创建它.

$Csharp = @"使用系统;使用 System.Reflection;命名空间小部件{公共类用户代码{公共静态 int GetValue() {返回2;}}}"@# 定义新的 .NET 程序集的输出路径$OutputAssembly = '{0}\Widget.dll' -f $env:USERPROFILE;# 编译代码并输出一个新的.NET程序集添加类型 -TypeDefinition $Csharp -OutputAssembly $OutputAssembly -OutputType 库;# 加载 .NET 程序集[System.Reflection.Assembly]::LoadFile($OutputAssembly);

第 2 部分 - 组装 #2

我们不必担心将第二个 .NET 程序集编译到磁盘,因为我们没有从任何其他程序集引用它.因此,我们可以简单地使用 Add-Type cmdlet 将其编译为一个临时的内存程序集.我们必须确保使用 -ReferencedAssemblies 参数来引用我们在第 1 部分中编译的 .NET 程序集.

# 现在我们有了一个编译好的 .NET 程序集,我们需要编写我们的新代码# 引用它(确保包含所有适当的 C#using"语句)#定义第二组C#代码$CsharpCode2 = @"使用小工具;命名空间 NASA {公共班班车{公共整数助推器;公共班车(){this.Boosters = UserCode.GetValue();}}}"@;# 尝试编译新代码,但是等等,我们得到一个错误...# ... 因为此代码依赖于包含在# 小部件组装$Assembly2 = 添加类型 -TypeDefinition $CsharpCode2 -PassThru;# 我们必须引用定义 UserCode 类型的 .NET 程序集$Assembly2 = Add-Type -TypeDefinition $CsharpCode2 -ReferencedAssemblies $OutputAssembly -PassThru;# 现在我们可以成功创建 NASA.Shuttle 对象了;$Shuttle = New-Object -TypeName NASA.Shuttle;# 查看 Shuttle 实例拥有的 boosters 数量写主机 -Object $Shuttle.Boosters;

How to access a type defined by Add-Type -TypeDefinition "..." in another Add-Type -TypeDefinition "..."?

In the following code example, in spite of the same namespace, a compiler cannot find the UserCode type.

Add-Type -TypeDefinition @"
namespace SampleCode {
    public struct UserCode {
         public string Name;
         public string Id;
    }
}
"@

#.... do something ....

Add-Type -TypeDefinition @"
namespace SampleCode {
    public struct UserInformation {
        public UserCode User;
        public string Note;
    }
}
"@
# => Error ... Add-Type : <temporary source path>(3) : The type or namespace name
# 'UserCode' could not be found (are you missing a using directive or an assembly
# reference?)

解决方案

In order to reference the first .NET assembly from the second .NET assembly, you need to persist the first .NET assembly to disk. Once you've done this, you can reference the first .NET assembly from the second .NET assembly using the -ReferencedAssemblies parameter of the Add-Type cmdlet.

IMPORTANT: If you use two different namespaces in your two different C# code blocks, make sure that you declare your using statements appropriately in the second code block.

Here is an example, showing you how to:

  1. Dynamically compile a new .NET assembly to disk
  2. Import a dynamic assembly that references another assembly on-disk

Part 1 - Assembly #1

The first .NET Assembly must be output to disk so that we can reference it. Therefore, we will use the -OutputAssembly and -OutputType parameters of the Add-Type cmdlet to create it.

$Csharp = @"
using System;
using System.Reflection;

namespace Widget {
    public class UserCode {
        public static int GetValue() {
            return 2;
        }
    }
}
"@

# Define the output path for the new .NET Assembly
$OutputAssembly = '{0}\Widget.dll' -f $env:USERPROFILE;

# Compile the code and output a new .NET assembly
Add-Type -TypeDefinition $Csharp -OutputAssembly $OutputAssembly -OutputType Library;

# Load the .NET Assembly 
[System.Reflection.Assembly]::LoadFile($OutputAssembly);

Part 2 - Assembly #2

We don't have to worry about compiling the second .NET assembly to disk, because we are not referencing it from any other assemblies. Therefore, we can simply use the Add-Type cmdlet to compile it into a temporary, in-memory assembly. We must make sure that we use the -ReferencedAssemblies parameter to reference the .NET Assembly that we compiled in Part 1.

# Now that we have a compiled .NET Assembly, we need to write our new code
# that references it (make sure to include all appropriate C# "using" statements)

# Define the second set of C# code
$CsharpCode2 = @"
using Widget;

namespace NASA {
    public class Shuttle {
        public int Boosters;
        public Shuttle() {
            this.Boosters = UserCode.GetValue();
        }
    }
}
"@;

# Try to compile the new code, but wait, we get an error ...
# ... because this code is dependent on the code contained in the
# Widget assembly
$Assembly2 = Add-Type -TypeDefinition $CsharpCode2 -PassThru;

# We have to reference the .NET Assembly that defines the UserCode type
$Assembly2 = Add-Type -TypeDefinition $CsharpCode2 -ReferencedAssemblies $OutputAssembly -PassThru;

# Now we can successfully create the NASA.Shuttle object;
$Shuttle = New-Object -TypeName NASA.Shuttle;

# View the number of boosters the Shuttle instance has
Write-Host -Object $Shuttle.Boosters;

这篇关于如何在其他 Add-Type 类型定义中访问 Add-Type 定义的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆