Legislator is a simple .NET interface authoring tool written in PowerShell
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.
Legislator is listed on PowerShell Gallery and can be installed with a single command:
Install-Module Legislator
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
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).
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 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;
}
}
This example:
interface IWell {
method void DropCoin([Coin])
}
is equivalent to the following in C#:
interface IWell
{
void DropCoin(Coin c);
}
The following event declaration in Legislator:
interface ICar {
event EventHandler[EventArgs] EngineStarted
}
is equivalent of C#:
interface ICar
{
event EventHandler<EventArgs> EngineStarted;
}
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
}
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;
}
}
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:
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