Как сделать объект .NET более дружественным к PowerShell? - PullRequest
1 голос
/ 03 марта 2011

У меня есть класс .NET, который я хочу использовать как в C #, так и в PowerShell. Сократите до гола, это что-то вроде этого:

class Record
{
    Dictionary<string, string> _fields = new Dictionary<string, string>();
    public IDictionary<string, string> Fields { get { return _fields; } }
    //...other stuff...
}

Итак, я откуда-то получаю запись, и я могу сделать запись. Поля ["foo"] = "bar" для изменения / добавления полей из C # или PowerShell. Прекрасно работает.

Но я бы хотел сделать его немного более дружественным к PowerShell. Я хочу сделать record.foo = "bar" и заставить его вызывать соответствующие методы получения и установки. (Я хотел бы сделать то же самое с C # в какой-то момент, возможно, с использованием динамического, но это отдельный забавный проект). Похоже, мне нужен класс прокси-сервера.

Я знаю об add-member, но я беспокоюсь, что он будет медленным и использует много памяти при работе с десятками тысяч записей. Я также не знаю, как заставить его обрабатывать record.somenewvalue = "abc".

Я предполагаю, что хочу создать свой прокси-класс в C #, используя средства System.Management.Automation или Microsoft.PowerShell, но не знаю, с чего начать. Может ли кто-нибудь помочь направить меня в правильном направлении?

Ответы [ 2 ]

2 голосов
/ 04 апреля 2011

Я нашел один способ сделать это.Просто сделайте запись самим словарем.Вот пример кода:

$source = @"
    using System.Collections.Generic;
    public class Record : Dictionary<string, object>
    {
    }
"@

add-type -typedefinition $source

$x = new-object record
$x.add('abc', '1') # add
$x['def'] = '2'    # indexer
$x.ghi = 3         # "member"

$x

Вывод:

Key     Value                                                       
---     -----                                                       
abc     1                                                           
def     2                                                           
ghi     3                                                           
0 голосов
/ 06 марта 2011

Вот некоторый код, иллюстрирующий три предложения:

public class Record: IEnumerable<KeyValuePair<string, string>>
{
    public Record() {}

    public Record (Hashtable ht)
    {
        foreach (var key in ht.Keys)
        {
            this[key.ToString()] = ht[key].ToString();
        }
    }

    Dictionary<string, string> _fields = new Dictionary<string, string>();
    public IDictionary<string, string> Fields { get { return _fields; } }
    public string this[string fieldName] {
        get {
            return _fields[fieldName];
        }
        set { _fields[fieldName] = value; }
    }
    //...other stuff...
    public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
    {
        return _fields.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
  1. Реализация этих индексаторов
  2. Реализация IEnumerable> для улучшения того, как powershell печатает вывод
  3. AКонструктор, принимающий в качестве параметра одну хеш-таблицу, позволяет использовать нотацию @ {} при начальном присваивании.

Теперь приведем несколько PowerShell, иллюстрирующих улучшенное использование:

Add-Type -Path 'C:\Users\zippy\Documents\Visual Studio 2010\Projects\ConsoleApplication1\ClassLibrary1\bin\Debug\ClassLibrary1.dll'

[ClassLibrary1.Record] $foo = New-Object ClassLibrary1.Record;
$foo["bar"]
$foo["bar"] = "value";
$foo["bar"]

[ClassLibrary1.Record] $foo2 = @{
    "bar"= "value";
    "something"= "to talk about";
}; 

$foo2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...