Использование атрибутов для вызова методов
У меня есть разные индивидуальные методы, которые все должны выполнять одни и те же функции, прежде чем продолжать свою собственную реализацию. Теперь я мог реализовать эти функции в каждом методе, но мне было интересно, есть ли способ использовать attributes
для этого? В качестве очень простого примера все сетевые вызовы должны проверять сетевое соединение.
public void GetPage(string url)
{
if(IsNetworkConnected())
...
else
...
}
Это сработает, но мне нужно будет вызвать метод IsNetworkConnected
для каждого метода, который использует сеть и обрабатывает ее по отдельности. Вместо этого я хотел бы сделать это
[NetworkCall]
public void GetPage(string url)
{
...
}
Если сеть недоступна, вместо нее вызывается метод ошибки, а GetPage
игнорируется, в противном случае вызывается GetPage
.
Это очень похоже на Ориентированное на Аспект программирование, но я не хочу реализовывать целую структуру для нескольких вызовов. Это скорее учебное упражнение, чем реализация, поэтому мне было любопытно, как лучше всего это сделать.
Ответы
Ответ 1
Вы можете использовать PostSharp, это аспектно-ориентированная среда для .NET, кажется довольно прост в использовании:
static void Main(string[] args)
{
Foo();
}
[IgnoreMethod(IsIgnored=true)]
public static void Foo()
{
Console.WriteLine("Executing Foo()...");
}
[Serializable]
public class IgnoreMethodAttribute : PostSharp.Aspects.MethodInterceptionAspect
{
public bool IsIgnored { get; set; }
public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args)
{
if (IsIgnored)
{
return;
}
base.OnInvoke(args);
}
}
Аспекты уровня метода доступны в версии бесплатно: http://www.sharpcrafters.com/purchase/compare
Производительность во время выполнения:
Поскольку PostSharp - это технология компилятора, большая часть дорогостоящей работы выполняется во время сборки, поэтому приложения запускаются быстро и быстро выполняются. При генерации кода PostSharp принимает предположение, что вызов виртуального метода или получение статического поля является дорогостоящей операцией. Вопреки слухам, PostSharp не использует System.Reflection во время выполнения. http://www.sharpcrafters.com/postsharp/performance
Ответ 2
Я не думаю, что вы можете сделать это только с помощью attributes
, потому что они не исполняются во время выполнения, если вы с ними не занимаетесь. Легкий подход будет Ninject с расширением перехватов, это фреймворк, но очень тонкий, и тот, который вы, возможно, уже используете для DI,
Другой вариант, но немного более привлекательный, может быть основан на MEF, а затем вы можете использовать атрибуты и делать что-то во время активации.
Ответ 3
Вы правы, это звучит очень похоже на AOP.
Что вы слышите, как компиляция во времени? То есть атрибут превращается в дополнительный код компилятором.
Вы можете посмотреть, как реализовать это...
Создание дополнительного кода через пользовательский атрибут
http://www.cs.columbia.edu/~eaddy/wicca/ &
http://www.sharpcrafters.com/aop.net/compiletime-weaving
все они относятся к инструментам и методам для этого.
Или вы можете использовать структуру AOP. ИМХО, вы должны посмотреть на рамки AOP.