Skip to content
| Marketplace
Sign in
Visual Studio>Tools>Kind Of Magic
Kind Of Magic

Kind Of Magic

Alexey Lavnikov

|
3,190 installs
| (4) | Free
Effortless INotifyPropertyChanged
Download

Update 06/3/2013

Aligned with current Mono.Cecil version

Update 21/5/2012

Update to Release 1.2.1 (Portable Class Libraries support)

Update 21/5/2012

Update to Release 1.2 (WinRT + .NET 4 fixes)

Update 6/4/2012

Update to Release 1.1 (VS11 support)

Update 7/3/2012

Update to Release 1.0.0.9

Mixed FX references fixed  

Update 13/10/2011

Update to Release 1.0.0.8

SL5 RC & various bug fixes

Update 08/03/2011

Update to Release 1.0.0.5

Nullable types fix

Update 04/03/2011

Update to Release 1.0.0.4

Magic in generic classes  (Please, reinstall KindOfMagic extension)

Update 03/03/2011

Update to Release 1.0.0.3

Silverlight, .NET Framework 3.5, 3.0, 2.0 supported  (Please, reinstall KindOfMagic extension)

Update 27/01/2011

Update to Release 1.0 (1.0.0.2) (Please, re-enable KindOfMagic in Project menu for your projects)

Project home

http://kindofmagic.codeplex.com

Project Description
MSBuild task to simplify implementation of INotifyPropertyChanged interface.

Injects supporting code in property setters: raising PropertyChanged event when value changed.


What is it?
Take a look at this painfully familar code:
 

C#
Edit|Remove
csharp
public string Name {  get   {     return _name;   }  set   {     if (_name != value)    {      _name = value;      RaisePropertyChanged("Name");    }  }} 
public string Name  {   get    {      return _name;    }   set    {      if (_name != value)     {       _name = value;       RaisePropertyChanged("Name");     }   } }   

and now imagine, that you just need to write only this:

C#
Edit|Remove
csharp
[Magic]public string Name { get; set; }
[Magic] public string Name { get; set; }  
If you need your private field, you may also write like this:
C#
Edit|Remove
csharp
[Magic]public string Name { get { return _name; } set { _name = value; } }string _name;
[Magic] public string Name { get { return _name; } set { _name = value; } } string _name;   

Or you may apply Magic attribute to a class, and all public properties (including all derived classes) will be transformed.

C#
Edit|Remove
csharp
[Magic]public class MyViewModel: INotifyPropertyChanged{  public string Name { get; set; }  public string LastName { get; set; }  .....}
[Magic] public class MyViewModel: INotifyPropertyChanged {   public string Name { get; set; }   public string LastName { get; set; }   ..... }  

To disable transformation, apply NoMagic attribute to a class or property:

C#
Edit|Remove
csharp
[NoMagic] // explicit stop of implicit property transformationpublic class MyExplicitViewModel: MyViewModel{  public long Age { get; set; } // will not be transformed implicitly  [Magic] // explicit transformation  public string FirstName { get; set; }  .....}
[NoMagic] // explicit stop of implicit property transformation public class MyExplicitViewModel: MyViewModel {   public long Age { get; set; } // will not be transformed implicitly   [Magic] // explicit transformation   public string FirstName { get; set; }   ..... }  

That's exacly what Kind Of Magic does! No more, no less.

How to use?

0) Enable your project: after installation of this VS2010 package, you'll find Enable/Disable KindOfMagic menu items in Project menu.

1) Define somewhere in your project MagicAttribute and NoMagicAttribute (optional) class, derived from Attribute. Neither visibility nor namespace are relevant. Here is an example, just two lines of code:

 
C#
Edit|Remove
csharp
class MagicAttribute: Attribute { }class NoMagicAttribute: Attribute { }
class MagicAttribute: Attribute { } class NoMagicAttribute: Attribute { }  

2) Apply Magic attribute to public properties in your ViewModel classes, implementing INotifyPropertyChanged. Your class must have accessible void RaisePropertyChanged(string) method.

3) Apply Magic attribute to ViewModel class if you want all public properties to raise PropertyChanged event. To exclude some of them, apply NoMagic attribute to these properties.

How it works
1) KindOfMagic build task runs just after compilation.
2) Looks for both MagicAttribute and NoMagicAttribute in building assembly and all referenced user assemblies.
3) Only classes, implementing INotifyPropertyChanged, and their descendants are inspected.
4) Looks for void RaisePropertyChanged(string) method.
5) Transforms all available setters of public properties with MagicAttribute explicitly or implicitly applied.
6) Injects supporting code using Mono.Cecil. Corresponding PDB file is also updated if any. Assembly will be resigned if signing is turned on. Use Reflector to see, what KindOfMagic does for you.

Beacon method call

Sometimes, when property setter code is relative complex, you may see this warning produced by KindOfMagic:

Property MyViewModel.MyProperty setter is too complex. Use beacon method (static void Raise()) to indicate point of RaisePropertyChanged injection.

Usually, this could be seen in setters like this:

C#
Edit|Remove
csharp
public object MyProperty {  get { return _field; }  set   {     _field = value;     if (value != null)       DoSomething();  }}
public object MyProperty  {   get { return _field; }   set    {      _field = value;       if (value != null)        DoSomething();   } }  

This happens because in IL, produced by C# compiler, it is not more possible to distinguish normal return (with keyword return) from conditional return. In this case, KindOfMagic redirects all returns to injected RaisePropertyChanged section of the setter, so all returns will raise property changed event. This gives you, as a programer, less control over your code. To solve this issue, I came up with the Beacon method idea.

Define somewhere a static void method Raise without any parameters. Here is an example:

C#
Edit|Remove
csharp
public class MyViewModel : INotifyPropertyChanged{  ...  [MethodImpl(MethodImplOptions.NoInlining)] // to preserve method call   protected static void Raise() { }}
public class MyViewModel : INotifyPropertyChanged {   ...   [MethodImpl(MethodImplOptions.NoInlining)] // to preserve method call    protected static void Raise() { } }  

In every problematic setter, place a call to this method just before the last curly brace of your setter. Here is an example:

C#
Edit|Remove
csharp
public object MyProperty {  get { return _field; }  set   {     _field = value;     if (value != null)       DoSomething();     Raise();  }}
public object MyProperty  {   get { return _field; }   set    {      _field = value;       if (value != null)        DoSomething();       Raise();   } }  

KindOfMagic will automagically replace Raise method call with RaisePropertyChanged section instead. No return statement will be remapped and no warning message will be emitted.

Customization
If for some reason you don't like magic, here are some customization hints for you. You may parameterise names of Magic, NoMagic and RaisePropertyChanged identifiers.

In KindOfMagic.targets file, locate MagicTask xml element and add following attributes:

XML
Edit|Remove
xml
<MagicTask ....  MagicAttribute="NotifyAttribute" NoMagicAttribute="StopNotifyAttribute" RaiseMethod="OnPropertyChanged"/>
<MagicTask ....  MagicAttribute="NotifyAttribute" NoMagicAttribute="StopNotifyAttribute" RaiseMethod="OnPropertyChanged"/>  
This will use Notify/StopNotify instead of Magic/NoMagic attributes and OnPropertyChanged instead of RaisePropertyChanged method during transformation.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft