如何在其他Add-Type类型定义中访问Add-Type定义的类型?

时间:2013-12-23 13:25:05

标签: powershell

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

在下面的代码示例中,尽管名称空间相同,但编译器找不到UserCode类型。

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?)

2 个答案:

答案 0 :(得分:10)

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

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

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

  1. 动态编译新的.NET程序集到磁盘
  2. 导入引用磁盘上其他程序集的动态程序集
  3. 第1部分 - 装配#1

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

    $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);
    

    第2部分 - 大会#2

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

    # 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;
    

答案 1 :(得分:1)

动态程序集(默认情况下,如果未指定其他参数,则无法生成)。

您可以使用Add-Type生成dll并稍后引用它们,例如:

Add-Type -OutputAssembly foo1.dll ...
Add-Type -ReferencedAssemblies foo1.dll ...

应该有用。