PowerShell / PowerShellStandard

MIT License
158 stars 23 forks source link

Attributes don't retain their values #62

Closed matteo-prosperi closed 5 years ago

matteo-prosperi commented 5 years ago

Hello, I have this sample code which uses either PowerShellStandard.Library 5.1 or 3.0.0-preview-02.

        static void Main(string[] args)
        {
            var cmdletAttribute = new CmdletAttribute("aaa", "bbb");
            Console.WriteLine($"{cmdletAttribute.VerbName}-{cmdletAttribute.NounName}");
        }

Running this code shows that VerbName and NounName are null instead of retaining the values passed in the constructor.

The real application I am having problems with is using reflection Assembly.LoadFrom and GetCustomAttributes to retrieve information about cmdlets defined in a PowerShell module. I am able to get the CmdletAttribute and the OutputTypeAttribute but they don't have any property set.

SeeminglyScience commented 5 years ago

@matteo-prosperi PowerShell Standard is a reference-only library. Every method/property returns default, it's just metadata.

You need to reference the Microsoft.PowerShell.SDK package instead (see Host PowerShell Core in .NET Core Applications for more details)

matteo-prosperi commented 5 years ago

@SeeminglyScience Thanks. That seem to be working and saved me some very ugly code!

I will leave some constructive feedback here:

SeeminglyScience commented 5 years ago

having to reference Microsoft.PowerShell.SDK in order to reflect on a library that targets PowerShellStandard.Library could be presented more prominently in the docs.

Yeah I agree, the only place it's mentioned in the README is pretty far into Via Visual Studio.

/cc @JamesWTruher @TylerLeonhardt.

I was doing reflection from a NetStandard 2.0 library and I cannot reference Microsoft.PowerShell.SDK from there (Microsoft.PowerShell.SDK is a netcoreapp2.1 library). I was able to change my library to also target netcoreapp2.1, so no problem there for me. But it is not so clear to me how I would have solved the problem if I were not in a position where I could do it.

PowerShell is a bit heavy to be pulling in as a dependency. It's a little bit like pulling in all of ASP.NET. That absolutely can be worth it, but it mostly makes sense in these two scenarios:

  1. PowerShell is already loaded. In this case the library is likely in a powershell.exe/pwsh process, most likely for a PowerShell module.
  2. As the host application. In this scenario you won't be targeting netstandard, and would instead need to target the SDK or the Windows PowerShell System.Management.Automation from the GAC depending on what your target framework is.

If you know of some compelling use cases for netstandard libs hosting PowerShell, I think you'd get the most luck out of opening an issue to detail them on https://github.com/PowerShell/PowerShell.

matteo-prosperi commented 5 years ago

@SeeminglyScience I don't have a terribly valuable use case for having to reference Microsoft.PowerShell.SDK/System.Management.Automation from a .Net Standard library. In our case we reflect over the main assembly of the PowerShell module (which targets PowerShellStandard.Library) in order to do backward compatibility checks before release and to generate documentation. As I said before, it was not a problem to convert the code from nestandard2.0 to netcoreapp2.1. I usually try to have the bulk of my code in a library target netstandard2.0 for reusability, but it was not a strong requirement.