Я рассматриваю возможность использования инфраструктуры Postsharp для облегчения бремени регистрации методов приложения. Это в основном позволяет мне украшать методы с атрибутом logging, а во время компиляции вводит код регистрации, необходимый в il. Мне нравится это решение, так как оно удерживает шум от окружающей среды временного кода. Любые мысли, опыт или лучшие альтернативы?
PostSharp - il weaving - мысли
Ответ 1
Я применяю ведение журнала с помощью АОП с использованием DynamicProxies Castle Windsor. Я уже использовал замок для контейнера IoC, поэтому использование его для АОП было для меня наименьшим сопротивлением. Если вам нужна дополнительная информация, дайте мне знать, я в процессе подбора кода для его выпуска в виде сообщения в блоге.
Изменить
Хорошо, здесь базовый код Intercepter, провальный, но он делает все, что мне нужно. Есть два перехватчика, один журнал каждый, а другой позволяет вам определять имена методов, чтобы обеспечить более мелкозернистую регистрацию. Это решение не зависит от Castle Windsor
Абстрактный базовый класс
namespace Tools.CastleWindsor.Interceptors
{
using System;
using System.Text;
using Castle.Core.Interceptor;
using Castle.Core.Logging;
public abstract class AbstractLoggingInterceptor : IInterceptor
{
protected readonly ILoggerFactory logFactory;
protected AbstractLoggingInterceptor(ILoggerFactory logFactory)
{
this.logFactory = logFactory;
}
public virtual void Intercept(IInvocation invocation)
{
ILogger logger = logFactory.Create(invocation.TargetType);
try
{
StringBuilder sb = null;
if (logger.IsDebugEnabled)
{
sb = new StringBuilder(invocation.TargetType.FullName).AppendFormat(".{0}(", invocation.Method);
for (int i = 0; i < invocation.Arguments.Length; i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(invocation.Arguments[i]);
}
sb.Append(")");
logger.Debug(sb.ToString());
}
invocation.Proceed();
if (logger.IsDebugEnabled && invocation.ReturnValue != null)
{
logger.Debug("Result of " + sb + " is: " + invocation.ReturnValue);
}
}
catch (Exception e)
{
logger.Error(string.Empty, e);
throw;
}
}
}
}
Полное управление протоколированием
namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Logging;
public class LoggingInterceptor : AbstractLoggingInterceptor
{
public LoggingInterceptor(ILoggerFactory logFactory) : base(logFactory)
{
}
}
}
Регистрация протоколов
namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Interceptor;
using Castle.Core.Logging;
using System.Linq;
public class MethodLoggingInterceptor : AbstractLoggingInterceptor
{
private readonly string[] methodNames;
public MethodLoggingInterceptor(string[] methodNames, ILoggerFactory logFactory) : base(logFactory)
{
this.methodNames = methodNames;
}
public override void Intercept(IInvocation invocation)
{
if ( methodNames.Contains(invocation.Method.Name) )
base.Intercept(invocation);
}
}
}
Ответ 2
+1 на postsharp. Используют для нескольких вещей (включая некоторые попытки добавить предварительные условия и постусловия к С# -коду) и не знают, как бы я сделал это без него...
Ответ 3
Это зависит от того, как долго вы будете развивать и поддерживать проект. Конечно, IL-переплетение - хорошая технология, но что произойдет, если формат метаданных IL и/или сборки снова изменится (как и между 1.1 и 2.0), и эти изменения делают инструмент несовместимым с новым форматом.
Если вы зависите от инструмента, это не позволяет вам обновлять технологию до тех пор, пока инструмент не поддержит ее. Без каких-либо гарантий относительно этого (или даже эта разработка будет продолжаться, хотя это кажется вероятным), тогда я бы очень настороженно относился к ее использованию в долгосрочном проекте.
Короче говоря, проблем нет.
Ответ 4
Использовали это, чтобы сделать именно это. Прекрасно работает! Я очень рекомендую!