å æ¥ã¼ãã£ã¨Twitterã«åããã¨æã£ããã¨ãBlogã«æ¸ããç¨åº¦ã®ã¨ã³ããªã¼ã®INotifyPropertyChangedとかを簡単に実装できるようにしてほしいよねã§ããã³ã¡ã³ãããã ãã¾ãããPostSharpã¨ãUnity使ã£ãAOPã§ã®å®è£ ã¨ãã¯ãåã«ãè¦ããã¨ãã£ãã®ã§ãããä»åãNotifyPropertyWeaverã¨ããç¥ããªãååã®ãã®ããã£ãã®ã§è©¦ãã¦ã¿ã¾ããã
ã¤ã³ã¹ãã¼ã«
ã¤ã³ã¹ãã¼ã«ã¨ãã£ã¦ãã½ãªã¥ã¼ã·ã§ã³ãã©ã«ãã«é©å½ãªãã©ã«ããç½®ãã¦NotifyPropertyWeaverMsBuildTask.dllãã³ãã¼ããã ãã§å®äºãããã§ã¯Libsã¨ãããã©ã«ããä½ã£ã¦ããã®ä¸ã«ã³ãã¼ãã¾ããã
ããã¸ã§ã¯ããã¡ã¤ã«ã®æ¸ãæã
使ç¨ããã¢ã»ã³ããªåããããããããã«ãããã¤ã¯MSBuildã®ã¿ã¹ã¯ãªã®ã§ããã¸ã§ã¯ããã¡ã¤ã«ãæåã§æ¸ãæãã¾ããMSBuildã®æ¸ãæããVisual Studio 2010ä¸ã§ã¹ã ã¼ãºã«ããã«ã¯ãããã¸ã§ã¯ããå³ã¯ãªãã¯ãã¦ããã¸ã§ã¯ãã®ã¢ã³ãã¼ããé¸æãã¦ããã¸ã§ã¯ããéããã¦ããªãç¶æ
ã«ãã¾ãã
ããããã¨ãå³ã¯ãªãã¯ã¡ãã¥ã¼ããããã¸ã§ã¯ããã¡ã¤ã«ãç·¨éã§ããããã«ãªãã¾ãã
ããã¦ãProjectã¿ã°ã®ä¸ã«NotifyPropertyWeaverã®ã¿ã¹ã¯ãå®è¡ããããããªè¨è¿°ã追è¨ãã¾ãã
<Project ... > ...... <!-- ã¿ã¹ã¯ã®èªã¿è¾¼ã¿ --> <UsingTask TaskName="NotifyPropertyWeaverMsBuildTask.WeavingTask" AssemblyFile="$(SolutionDir)Libs\NotifyPropertyWeaverMsBuildTask.dll" /> <Target Name="AfterBuild"> <!-- INotifyPropertyChangedãå®è£ ãã¦ããå ¨ã¦ã®åã«å¯¾ã㦠RaisePropertyChangedã®å¼ã³åºãã追å ããããã«è©¦ã¿ãã EventInvokerNameãæå®ããªãã£ããããã©ã§OnPropertyChangedã«ãªã --> <NotifyPropertyWeaverMsBuildTask.WeavingTask TargetPath="$(TargetPath)" TryToWeaveAllTypes="true" EventInvokerName="RaisePropertyChanged" /> </Target> </Project>
ããã°ã©ã æ¸ãã¦ã¿ã
ããã§æºåå®äºãªã®ã§ãç°¡åã«ããã°ã©ã ãæ¸ãã¦ã¿ã¾ãããã
namespace ConsoleApplication21 { using System; using System.ComponentModel; // INotifyPropertyChangedã®åç´å®è£ public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void RaisePropertyChanged(string name) { var h = this.PropertyChanged; if (h != null) { h(this, new PropertyChangedEventArgs(name)); } } } // èªåããããã£ãå®ç¾©ããã ã public class Person : ViewModelBase { public int Age { get; set; } public string Name { get; set; } } class Program { static void Main(string[] args) { var p = new Person(); // å¤æ´ããã£ãããããã£åãåºåããããã«ä»è¾¼ã㧠p.PropertyChanged += (s, e) => { Console.WriteLine(e.PropertyName); }; // é©å½ã«å¤ãä»£å ¥ãã¦ã¿ã p.Age = 10; p.Age = 100; p.Name = "ãã"; p.Name = "ãã"; } } }
ä½ã®ã²ããããªãåç´ãªããã°ã©ã ã§ããPropertyChangedãå¼ã°ããã®ã¯Ageã«10ã¨100ãå ¥ããã¨ãã¨ãNameã«"ãã"ãæåã«ä»£å ¥ããã¨ãã®3åã®ã¯ãã§ãã2åç®ã®"ãã"ã®ä»£å ¥ã¯åãå¤ã®ä»£å ¥ãªã®ã§PropertyChangedã¯å¼ã°ããªãã¯ãã§ãã
ã¨ãããã¨ã§ãæ¬å½ã«ããã§PropertyChangedã¤ãã³ããæå¾
éãçºè¡ãããã®ãå®è¡ãã¦ã¿ã¾ããå®è¡ããã¨ã»ã»ã»ã
ã¡ããã¨å®è¡ãã¦ãã¿ããã§ãã
ãã®ä»ã®æ©è½
ä¸å¿ãä»å使ã£ãMSBuildã®ã¿ã¹ã¯ä»¥å¤ã«ãNotifyPropertyWeaver.dllã¨ããã¢ã»ã³ããªãæä¾ããã¦ãã¦ãããã¤ã使ãã¨é¢é£ããããããã£ã®å¤æ´ã¤ãã³ããåæã«çºè¡åºæ¥ããããã®ããããã£ã«å¯¾ãã¦ã¯PropertyChangedã¤ãã³ãçºè¡ããªãããã«ã¨ãç´°ããæå®ãåºæ¥ãã¿ããã§ãã
ä»åã¯ãå
¨ã¯ã©ã¹ãèªåã§PropertyChangedçæã®å¯¾è±¡ã«ãã¾ããããNotifyPropertyå±æ§ã§æå®ãããã®ã ãçæããããã¨ãåºæ¥ã¾ãã
ä»çµã¿ã¯ã»ã»ã»ï¼
ã¡ãã£ã¨ããã³ã¼ããè¦ã¦ã¾ããããMono.Cecilã使ã£ã¦ããããã®ã§ãã³ã³ãã¤ã«å¾ã®ã¢ã»ã³ããªãæ¸ãæãã¦ãã¨ããã¨ã¦ãé»éè¡çãªãã¨ããã¦ããããã§ãã
Mono.Cecilã«ã¤ãã¦ã¯ããã¡ããè¦ã¦ãã ããã
ææ³
PostSharpã¯ããã¼ã ã§ä½¿ããã¨æãã¨æãã¨å
¨å¡ã«ã¤ã³ã¹ãã¼ã«ãå¿
è¦ã§ãããä»å試ããNotifyPropertyWeaverã¯ã½ãªã¥ã¼ã·ã§ã³ã«ä»è¾¼ãã§ãã¾ãã°ããã¨ã¯ãã¼ã å
ã§å
±æãã¦ãã¾ãã°ä½¿ãã¦ãã¾ããæ軽ããããä¸ã«ãILãæ¸ãæããã®ã§AOPã¿ãããªå®è¡æã®ãªã¼ãã¼ãããããªãã®ã§ç´ æµã ã¨æãã¾ãã
æãã¾ãããé»éè¡ã使ã£ã¦ãã®ã§ã³ã¼ãã®è¦ãç®ã¨å®éã®åä½ãç°ãªãã¨ããããåã®å£ã§ãããã¾ãã使ãã¨ããã[NotifyProperty]å±æ§ãã¤ããããããã£ã ã対象ã«ããã¿ãããªä½¿ãæ¹ã®ã»ããããããããã¾ããã
ãã ãå®ç¸¾ããªãã¨ã¡ãã£ã¨æãã£ã¡ããæãã§ããã