Используйте атрибуты для проверки доступа к методу - PullRequest
4 голосов
/ 21 декабря 2009

У меня есть метод, который доступен только в том случае, если соблюдены определенные критерии, в противном случае метод не будет выполнен. В настоящее время, вот как я кодирую вещь:

public void CanAccessDatabase()
{
   if(StaticClass.IsEligible())
   {
      return;
   }
   // do the logic
}

Теперь, этот код уродлив, потому что нет нигде такого условия if(StaticClass.IsEligible()), которое не имеет отношения к вопросу о методе.

Итак, я думаю о том, чтобы добавить в атрибут метод IsEligible, чтобы мой код выглядел следующим образом. Если условие не выполнено, этот метод просто вернется без выполнения приведенной ниже логики.

[IsEligibleCheck]
public void CanAccessDatabase()
{
   // do the logic
}

Приемлемость - это решение во время выполнения, конечно.

Есть идеи, как кодировать логику для IsEligibleCheck? Спасибо

Редактировать: Я знаю, что PostSharp может сделать это, но я смотрю на что-то, что работает из коробки, не завися от какой-либо сторонней библиотеки.

Ответы [ 6 ]

3 голосов
/ 21 декабря 2009

Есть идеи о том, как кодировать логику для IsEligibleCheck?

Это идеальное место для АОП.

Редактировать: я знаю, что PostSharp может сделать это, но я смотрю на что-то, что работает из коробки, не завися от какой-либо сторонней библиотеки.

Считается ли Microsoft сторонней компанией? Если нет, вы можете посмотреть на Unity из их команды Patterns & Practices . Посмотрите на механизм Interceptor в Unity.

В противном случае вам фактически придется развернуть собственную реализацию, используя отражение. По сути, вам нужно обернуть ваши объекты в прокси, в котором прокси использует отражение, чтобы проверить атрибуты и интерпретировать их соответствующим образом. Если IsEligibleCheck завершается успешно, то прокси вызывает метод для обернутого объекта. На самом деле, проще просто использовать уже существующую реализацию.

Мой совет - просто используйте Unity (или другое решение AOP).

2 голосов
/ 21 декабря 2009

К сожалению, атрибуты не выполняются во время выполнения. Несколько встроенных атрибутов изменяют код, который компилируется, как атрибуты MethodImpl и тому подобное, но все пользовательские атрибуты - это просто метаданные. Если никакой код не ищет метаданные, он будет сидеть там и вообще не повлиять на выполнение вашей программы.

Другими словами, вам нужно это if-выражение где-то .

Если вы не можете использовать такой инструмент, как PostSharp , вы не сможете сделать это в готовом .NET, без явной проверки атрибутов.

2 голосов
/ 21 декабря 2009

Пользовательские атрибуты идут рука об руку с отражением.

Вам потребуется создать другой класс, который будет отвечать за вызов методов в вашем классе CanAccessDatabase ().

Используя отражение, этот новый класс будет определять атрибуты для каждого метода. Если атрибут IsElptableCheck найден, он выполнит проверку StatiClass.IsElitable () и вызовет CanAccessDatabase (), только если проверка пройдена.

Вот введение в MSDN. Он вращается вокруг использования метода MemberInfo.GetCustomAttributes ().

Вот псевдокод:

Get the Type of the CanAccessDatabase() class
Using this type, get all methods in this class (optionally filtering public, private etc).
Loop through the list of methods
    Call GetCustomAttributes() on the current method.
    Loop through the list of custom attributes
        If the IsEligibleCheck attribute is found
            If StaticClass.IsEligible is true
                Call the current method (using MethodInfo.Invoke())
            End If
        End If
    End Loop
End Loop
2 голосов
/ 21 декабря 2009

Это выглядит как идеальный кандидат для AOP . В двух словах, это означает, что логика CanAccessDatabase будет жить в «аспекте» или «перехватчике», то есть отделяет от бизнес-логики, таким образом достигая разделения интересов (аспект отвечает только за безопасность, бизнес-код отвечает только за деловые вещи).

В C # двумя популярными вариантами выполнения AOP являются Castle.DynamicProxy и PostSharp . У каждого есть свои плюсы и минусы. Этот вопрос подводит итог их различий.

Вот другие варианты для выполнения AOP в .Net, некоторые из них могут быть выполнены без сторонних библиотек. Я все еще рекомендую использовать DynamicProxy, PostSharp, LinFu, Spring.AOP или Unity, другие решения не так гибки.

1 голос
/ 19 марта 2011

Я знаю, что это старая тема ...

Вы можете использовать условный атрибут: http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx

"Указывает компиляторам, что вызов метода или атрибут следует игнорировать, если не указан определенный символ условной компиляции."

#define IsEligibleCheck // or define elsewhere 

[Conditional("IsEligibleCheck")]
public void CanAccessDatabase()
{
   // do the logic
}
0 голосов
/ 31 декабря 2012

отметьте AOP, который вам очень поможет в этом, один из мощных компонентов на рынке - PostSharp

...