Модуль Powershell: динамические обязательные иерархические параметры
Итак, что я действительно хочу, так это несколько полезное завершение вкладок в модуле PS. ValidateSet, кажется, путь сюда.
К сожалению, мои данные являются динамическими, поэтому я не могу аннотировать параметр всеми допустимыми значениями заранее. DynamicParameters / IDynamicParameters, кажется, решение длятот проблема.
Объединяя эти вещи (и сводя мою неудачу к простому тестовому случаю), мы получаем:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;
namespace PSDummy
{
[Cmdlet(VerbsCommon.Get, "BookDetails")]
public class GetBookDetails : Cmdlet, IDynamicParameters
{
IDictionary<string, string[]> m_dummyData = new Dictionary<string, string[]> {
{"Terry Pratchett", new [] {"Small Gods", "Mort", "Eric"}},
{"Douglas Adams", new [] {"Hitchhiker's Guide", "The Meaning of Liff"}}
};
private RuntimeDefinedParameter m_authorParameter;
private RuntimeDefinedParameter m_bookParameter;
protected override void ProcessRecord()
{
// Do stuff here..
}
public object GetDynamicParameters()
{
var parameters = new RuntimeDefinedParameterDictionary();
m_authorParameter = CreateAuthorParameter();
m_bookParameter = CreateBookParameter();
parameters.Add(m_authorParameter.Name, m_authorParameter);
parameters.Add(m_bookParameter.Name, m_bookParameter);
return parameters;
}
private RuntimeDefinedParameter CreateAuthorParameter()
{
var p = new RuntimeDefinedParameter(
"Author",
typeof(string),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 0,
Mandatory = true
},
new ValidateSetAttribute(m_dummyData.Keys.ToArray()),
new ValidateNotNullOrEmptyAttribute()
});
// Actually this is always mandatory, but sometimes I can fall back to a default
// value. How? p.Value = mydefault?
return p;
}
private RuntimeDefinedParameter CreateBookParameter()
{
// How to define a ValidateSet based on the parameter value for
// author?
var p = new RuntimeDefinedParameter(
"Book",
typeof(string),
new Collection<Attribute>
{
new ParameterAttribute {
ParameterSetName = "BookStuff",
Position = 1,
Mandatory = true
},
new ValidateSetAttribute(new string[1] { string.Empty }/* cannot fill this, because I cannot access the author */),
new ValidateNotNullOrEmptyAttribute()
});
return p;
}
}
}
К сожалению, этот крошечный фрагмент уже вызывает много проблем. Заказано по убыванию:
Я не вижу, как я могу создать связь между параметрами. Если вы выберете автора, вы сможете выбрать только ту книгу, которая соответствует автору. До сих порGetDynamicParameters()
хотя всегда кажется, что без состояния: я не вижу способа получить доступ к значению другого / более раннего динамического параметра. Пробовал держать его в поле, пытался искатьMyInvocation
- неудачно. Это вообще возможно?
Как вы определяете значение по умолчанию для обязательного параметра? Не подходит для глупого примера, но, допустим, вы можете хранить своего любимого автора. Отныне я хочу использовать этого автора по умолчанию, но указатель на автора все еще является обязательным. Либо вы дали мне значение по умолчанию (и все еще можете указать что-то еще), либо вам нужно быть явным.
Завершение табуляции для строк с пробелами кажется странным / сломанным / ограниченным - потому что оно не заключает значение в кавычки (как, например, cmd.exe, если вы наберетеdir C:\Program <tab>
). Итак, завершение вкладки на самом делебрейки вызов (если вышеуказанные проблемы будут решены,Get-BookDetails Ter<tab>
будет / будет расширяться доGet-BookDetails Terry Pratchett
который помещает фамилию в положение параметра 1 или «книга».
Не должно быть так сложно, наверняка кто-то уже делал нечто подобное?
Обновление: После еще одного хорошего дня возиться и дурачиться я не вижу способа сделать эту работу. Командлет не имеет состояния и будет создаваться снова и снова. В тот момент, когда яМожно определить динамические параметры (GetDynamicParameters) Я не могу получить доступ к их (текущим) значениям / посмотреть, к чему они будут привязаны - например, MyInvocation.BoundParameters равен нулю. Я оставлю вопрос открытым, но кажется, что это просто не поддерживается. Все примеры, которые я вижу, добавляют динамический параметр, основанный на значении статического - и это не имеет значения здесь. Мудак.