Skip to content

Instantly share code, notes, and snippets.

@AlbertoMonteiro
Created March 11, 2012 17:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlbertoMonteiro/2017142 to your computer and use it in GitHub Desktop.
Save AlbertoMonteiro/2017142 to your computer and use it in GitHub Desktop.
Auto Implement INotifyPropertyChanged
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using FluentIL.Cecil;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MethodAttributes = Mono.Cecil.MethodAttributes;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
var writeLine = typeof(Console).GetMethod("WriteLine", new List<Type>() { typeof(string) }.ToArray());
var myAssembly = Assembly.GetExecutingAssembly();
var assembly = AssemblyDefinition.ReadAssembly(myAssembly.CodeBase.Remove(0, 8), new ReaderParameters(ReadingMode.Immediate));
var typeDefinitions = assembly.Modules.SelectMany(x => x.Types).ToList();
var types = typeDefinitions.Where(ImplementaINotifyPropertyChanged);
foreach (var typeDefinition in types)
{
typeDefinition
.NewMethod("OnPropertyChanged", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(void), assembly)
.Ldstr("Funfo")
.Call(writeLine)
.Nop()
.Ret();
var onPropertyChanged = typeDefinition.Methods.First(m => m.Name == "OnPropertyChanged");
foreach (var propertyDefinition in typeDefinition.Properties)
{
//Carrego o metodo get da propriedade
var methodDefinition = propertyDefinition.GetMethod;
//Insiro na segunda posicao pq a primeira é o carregamento do this e o método é de instancia, então preciso do this
methodDefinition.Body.Instructions.Insert(2, Instruction.Create(OpCodes.Call, onPropertyChanged));
//Carrego o this novamente para continuar com a execucao normal do método
methodDefinition.Body.Instructions.Insert(3, Instruction.Create(OpCodes.Ldarg_0));
}
}
var path = Environment.CurrentDirectory + @"\ExeDeTeste.exe";
assembly.Write(path, new WriterParameters() { WriteSymbols = true });
Process.Start(path, "abc");
}
var t = new Teste { Nome = "Alberto", Teste2 = 21 };
Console.WriteLine(t.Nome);
Console.WriteLine(t.Teste2);
Console.ReadLine();
}
static bool ImplementaINotifyPropertyChanged(TypeDefinition type)
{
return type.Interfaces.Any(@interface => @interface.Name == "INotifyPropertyChanged");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment