PostSharp은 여러분의 .NET 코드의 라인수를 줄이고, 논리적은 관계를 분리시켜 코드를 작성할 수 있도록 해줍니다.
쉽게 얘기하면 일반화할 수 있는 코드를 Attribute로 작성할 수 있습니다.
몇가지 예를 들겠습니다.
(1) Trace : 트래이스할 수 있는 사용자 정의 Attribute
public class TraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionEventArgs eventArgs)
{ Trace.TraceInformation("Entering {0}.", eventArgs.Method); }
public override void OnExit( MethodExecutionEventArgs eventArgs)
{ Trace.TraceInformation("Leaving {0}.", eventArgs.Method); }
}
(2) Async : 특정 함수를 비동기로 만드는 사용자 정의 Attribute
public class AsyncAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
ThreadPool.QueueUserWorkItem(delegate { eventArgs.Proceed(); });
}
}
(3) GUI Dispatch : 특정 함수를 GUI 쓰레드에서 실행하게 하는 사용자 정의 Attribute
public class GuiThreadAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
DispatcherObject dispatcherObject = (DispatcherObject)eventArgs.Delegate.Target;
if (dispatcherObject.CheckAccess())
eventArgs.Proceed();
else
dispatcherObject.Dispatcher.Invoke( DispatcherPriority.Normal,
new Action(() => eventArgs.Proceed()));
}
}
(4) Exception : 예외를 처리하는 사용자 정의 Attribute
public class ExceptionDialogAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
string message = eventArgs.Exception.Message;
Window window = Window.GetWindow((DependencyObject) eventArgs.Instance);
MessageBox.Show(window, message, "Exception");
eventArgs.FlowBehavior = FlowBehavior.Continue;
}
}
(5) Cache : 캐쉬를 하는 사용자 정의 Attribute
public class CacheAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
object value;
string key = // Compute the cache key (details omitted).
if (!cache.TryGetValue(key, out value))
{
lock ( this )
{
if (!cache.TryGetValue(key, out value))
{
eventArgs.Proceed();
value = eventArgs.ReturnValue;
cache.Add(key, value);
return;
}
}
}
eventArgs.ReturnValue = value;
}
}
저는 실제로 INotifyPropertyChanged를 구현할때 일일히 속성을 정의하는게 귀찮아서
어떻게 Attribute로 할 수 없을까 구글로 검색했는데 PostSharp를 사용하면 쉽게 할수 있었습니다.
http://code.google.com/p/propfu/
윈래 이런 코드가
public class PersonLame : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (value == _name)
return;
_name = value;
OnPropertyChanged("Name");
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
if (value == _age)
return;
_age = value;
OnPropertyChanged("Age");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
다음 코드로 정리 됩니다.
[NotifyPropertyChanged]
public class PersonAwesome : INotifyPropertyChanged
{
public string Name { get; set; }
public int Age { get; set; }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
[OnPropertyChanged]
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
