Skip to content

Latest commit

 

History

History
172 lines (117 loc) · 4.05 KB

README.md

File metadata and controls

172 lines (117 loc) · 4.05 KB

Legislator

Legislator is a simple .NET interface authoring tool written in PowerShell

Background

I've heard a number of powershell users ask for the ability to define .NET interfaces at runtime, rather than just implementing them using the Classes feature introduced in PowerShell v5. I'm not sure how scalable this approach is for DSC, but other interesting use cases might exist.

Installation

From PowerShell Gallery

Legislator is listed on PowerShell Gallery and can be installed with a single command:

Install-Module Legislator

Manual installation

Copy the contents of src to a folder called Legislator in your module directory, e.g.:

$modulePath = "C:\Program Files\WindowsPowerShell\Modules"
mkdir "$modulePath\Legislator"
Copy-Item .\src\* -Destination "$modulePath\Legislator\" -Recurse

Import using Import-Module as you would any other module:

Import-Module Legislator

Syntax

The chosen syntax attempts to balance the simplicity of interface definitions found in C#, including the type signature layout found in that language and the need to easily parse the syntactical elements as PowerShell functions (hence the property/method prefix keywords).

Commands

interface

A Legislator-generated interface starts with the interface command. It takes two positional mandatory parameters - a name and a scriptblock containing the interface declaration:

interface IName {

}

property

Property declarations in Legislator look like implicit properties in C#, prefixed with keyword property. Thus, the following interface definition in Legislator:

interface IPoint {
    property int X
    property int Y
}

is equivalent to the following interface definition in C#:

interface IPoint 
{
    int X
    {
        get;
        set;
    }
    int Y
    {
        get;
        set;
    }
}

method

This example:

interface IWell {
    method void DropCoin([Coin])
}

is equivalent to the following in C#:

interface IWell
{
    void DropCoin(Coin c);
}

event

The following event declaration in Legislator:

interface ICar {
    event EventHandler[EventArgs] EngineStarted
}

is equivalent of C#:

interface ICar
{
    event EventHandler<EventArgs> EngineStarted;
}

Multiple interface

Legislator also supports chaining multiple interfaces, via the Implements parameter.

The following interface declaration in Legislator:

interface ICrappyCar {
    event EventHandler[EventArgs] EngineBroke
} -Implements IDisposable

is equivalent to the following in C#:

interface ICrappyCar : IDisposable {
    event EventHandler<EventArgs> EngineBroke
}

Syntax notes

Legislator currently supports method, property and event members. No plans to supporting index accessor syntax.

Due to limited usefulness, access modifiers are also not supported, all generated interfaces default to Public.

Parameter naming for methods is also not currently support.

The property definition supports a ReadOnly option that omits declaration of a property setter:

interface ITest {
    property int MyProperty -Option ReadOnly
}

is equivalent to the following C# with an explicit getter but no setter:

interface ITest {
    int MyProperty
    {
        get;
    }
}

Example Usage

The following example defines a (very) rudimentary Calculator interface, and uses it for flexible dependency injection:

See also this strategy pattern example implementing a Legislator-defined interface:

Contributing

If you'd like to submit a bug or otherwise contribute to the development of Legislator (or just say hi) feel free to raise an issue or contact me on Twitter