2016-03-25 9 views
2

Я нашел this question - это очень похоже на то, что я пытаюсь. Однако мой вариант использования немного отличается.Может ли атрибут C# добавить параметр к методу?

У нас есть необходимость хранить историю аудита для бизнес-услуг. Однако мы должны иметь возможность вручную вызывать контрольные точки аудита во время вызова метода, а не только до и после.

Мы используем Castle.Core в нашем проекте. Для этого я планирую создать настраиваемый атрибут с именем AuditContext для использования в наших методах обслуживания (для аудита бизнес-логики и т. Д.). Я планирую использовать Castle DynamicProxy для создания прокси-сервера регистрации, который создаст новый объект контекста на основе метаданных аргументы в объекте атрибута. То, что я хотел бы сделать, это вставить этот объект в мой метод как аргумент метода, но без указания параметра AuditContext для каждого создаваемого нами метода службы.

По существу, вместо этого:

[AuditContext(someStaticMetadata) 
public BusinessObject BusinessMethod (AuditContext context, ...arguments) { 
    // ...some logic... 
    context.checkpoint(someAuditData); 
} 

Я хочу быть в состоянии сделать это:

[AuditContext(someStaticMetadata) 
public BusinessObject BusinessMethod (...arguments) { // We do not have to specify the context object for every business method... 
    // ...some logic... 
    context.checkpoint(someAuditData); // ...but the object is still available, as the parameter has been added by the argument. 
} 

Или, чтобы сделать гораздо более общий пример, я хочу, чтобы написать это:

[ProvidesParam2] 
public Object myFunc (param1) { } 

... и в конечном итоге с помощью этой функции:

public Object myFunc (param1, param2) { } 

Дистиллированный вопрос: может ли атрибут C# добавить параметр к методу, который он украшает, эффективно изменяя подпись метода во время разработки?

Спасибо!

+0

Единственная разница, которую я вижу между тем, что вы просите, и ответом на связанный с вами вопрос является то, что 'AuditContext' принимает некоторые статические метаданные, тогда как ответ в связанном вопросе принимает интерфейс. В любом случае вы должны использовать отражение для создания объекта. Если вы не сможете объяснить мне, как то, что вы просите, отличается от связанного вопроса, я склонен голосовать, чтобы закрыть его как дубликат. –

+0

@JimMischel Основное различие между тем, что он делает и чем я занимаюсь, заключается в том, что я пытаюсь использовать атрибут для изменения сигнатуры метода. Фактически, я только задал этот вопрос, чтобы показать, что это не дубликат. Мой прецедент связан с его, но основная проблема другая. См. Примеры кода, которые я предоставил. –

+0

Единственный способ получить 'someAuditData', не передавая его в качестве параметра, - использовать отражение, чтобы найти атрибут AuditContext, а затем' Activator.CreateInstance' для его создания, точно так же, как ответ на связанный вопрос говорит. Вы не можете просто получить к нему доступ, как если бы это был параметр. –

ответ

2

Короткий ответ: нет. Атрибуты действительно изменяют то, что вы могли бы интерпретировать как подпись в особых случаях (например, соглашение о вызове), но они определенно не могут изменять список аргументов. Вы можете добиться того, чего хотите, с помощью пользовательского переписывающего ИИ; что-то вроде PostSharp может помочь (отказ от ответственности: у меня нет опыта вообще с помощью PostSharp).