4

I want to use in my powershell a interface from my custom .net library, but i got always this error:

class Logger : Systems.SysBiz.BaseTransversal.ILoggerBl
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [Systems.SysBiz.BaseTransversal.ILoggerBl].

If I use for example the IComparable interface from the system namespace it works fine.

[System.Reflection.Assembly]::LoadFile('MyPath\BaseTransversal.dll')

class Logger : Systems.SysBiz.BaseTransversal.ILoggerBl
{

    [bool] $SendMailException = $false;

    Logger()
    {

    }

    [void] LogFatal([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [void] LogException([System.Exception] $ex, [string] $message, [object[]] $args)
    {
        Write-Host $this.FormatException($ex);            
    }

    [void] LogError([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [void] LogWarning([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [void] LogInfo([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [void] LogTrace([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [void] LogDebug([string] $message, [object[]] $args)
    {
        Write-Host $message;
    }

    [string] FormatException([System.Exception] $ex)
    {
        if (!$ex)
        {
            return "";
        }

        return "<br/><b>" + $ex.Message + "</b><p>" + $ex.StackTrace + "</p><br/>" + $this.FormatException($ex.InnerException);
    }
}

Here my .net interface

namespace Systems.SysBiz.BaseTransversal
{
    public interface ILoggerBl
    {
        bool SendMailException { get; }
        void LogFatal(string message, params object[] args);
        void LogException(Exception ex, string message, params object[] args);

        void LogError(string message, params object[] args);

        void LogWarning(string message, params object[] args);

        void LogInfo(string message, params object[] args);

        void LogTrace(string message, params object[] args);

        void LogDebug(string message, params object[] args);

        string FormatException(Exception ex);
    }
}

UPDATE: Added full class powershell code I have also tried with a empty interface in my .net code but looks like the i can't see/use my interfaces even they are public. Did I miss something

UPDATE 2: Added exact error

2
  • Did you load your assembly? You question seems to be a debugging question and seems to be missing some crucial information to help us solve your issue. Commented Dec 7, 2018 at 12:56
  • Yes i load the dll with [System.Reflection.Assembly]::LoadFile('C:\Projects\SysBiz-New\SysBizClientTester\src\powershell\libs\BaseTransversal.dll'). Commented Dec 7, 2018 at 13:24

1 Answer 1

2

I've had the same problem. PowerShell classes are processed before the evaluation of the script starts. So your first line does NOT run before the class tries to inherit from it, and so the type is not defined. A solution to that is moving the classes and the loading into two separate scripts. Then dot-source them in a third script that forms your entry point. Load the script that defines external types firs. Then load the script that defines your classes, that way the types are imported before the second script starts evaluating.

# in file typeLoad.ps1
Add-Type -TypeDefinition "
public interface IHaveName {
    string Name { get; set; }
}"

# in file classes.ps1
class B : IHaveName {

}

# in file main.ps1
. $PSScriptRoot\typeLoad.ps1
. $PSScriptRoot\classes.ps1
Sign up to request clarification or add additional context in comments.

3 Comments

oh yes it works. but now if I use the this objects seems that does not implement the interface because on this call [Systems.SysBiz.BaseTransversal.ILoggerBl]$logger = [Logger]::new() $authentication = New-Object Systems.SysBiz.AuthenticationTransversal.Internal.AuthenticationBl "MYHOST" $logger I got this error: A positional parameter cannot be found that accepts argument 'Logger'.
oh found it. was a missing , in the argumentlist
Looks like you can also use a script block, . { Add-Type blah blah } to add the interface directly in main.ps1. I think what is happening here is defining the interface like this adds it to the same context that will be used to parse the class code. If the class code is in the same file, the parsing of the class code occurs too early. If you use Import-Module to import the classes, it uses a different context so the interface isn't there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.