Last active
May 31, 2017 19:27
-
-
Save jtheisen/f6de30d6dfbd8355194b9469eb18e3be to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
namespace AssemblyToProcess | |
{ | |
#region The interfaces we need to define our implementations with. | |
// See sample below for an explanation of the type parameters. | |
public interface IPropertyImplementation<ValueInterface, ContainerInterface, Value, Container, MixIn> | |
where Value : ValueInterface | |
where Container : ContainerInterface | |
where MixIn : struct | |
{ | |
Value Get(Container self, ref MixIn mixIn); | |
void Set(Container self, ref MixIn mixIn, Value value); | |
} | |
public interface IPreviousPropertyImplementation<Value> | |
{ | |
String GetPropertyName(); | |
Value Get(); | |
void Set(Value value); | |
} | |
#endregion | |
#region The sample implementation: Implementing INotifyPropertyChanged! | |
/// <summary> | |
/// Our property implementations need a common mix in that implements the event. | |
/// </summary> | |
/// <typeparam name="Container"></typeparam> | |
public struct MyMixIn<Container> : INotifyPropertyChanged | |
{ | |
public event PropertyChangedEventHandler PropertyChanged; | |
public void Fire(Container self, String propertyName) | |
{ | |
PropertyChanged?.Invoke(self, new PropertyChangedEventArgs(propertyName)); | |
} | |
} | |
/// <summary> | |
/// We have an example property implementation that will fire a PropertyChanged event on setting. | |
/// </summary> | |
/// <typeparam name="Value">The type of the property (Decimal or Int32 in our sample).</typeparam> | |
/// <typeparam name="Container">The type of the object we have the properties on.</typeparam> | |
/// <typeparam name="OriginalImplementation">Made by the weaver to allow for access to the previous properties.</typeparam> | |
public struct MyPropertyImplementation<Value, Container, OriginalImplementation> | |
: IPropertyImplementation<IComparable<Value>, Object, Value, Container, MyMixIn<Container>> | |
where Value : IComparable<Value> | |
where OriginalImplementation : IPreviousPropertyImplementation<Value> | |
{ | |
public OriginalImplementation originalImplementation; | |
public Value Get(Container self, ref MyMixIn<Container> mixIn) | |
{ | |
return originalImplementation.Get(); | |
} | |
public void Set(Container self, ref MyMixIn<Container> mixIn, Value value) | |
{ | |
originalImplementation.Set(value); | |
mixIn.Fire(self, originalImplementation.GetPropertyName()); | |
} | |
} | |
/// <summary> | |
/// This is our sample class to be rewoven. It can actually really live in the | |
/// same assembly as the property implementation above. | |
/// </summary> | |
public class ClassToHaveItsPropertiesModified | |
{ | |
public Decimal Decimal { get; set; } | |
public Int32 Int32 { | |
get { | |
return (Int32)Decimal; | |
} | |
set { | |
Decimal = Int32; | |
} | |
} | |
} | |
#endregion | |
#region The produced wool. | |
// These two accessors will be (properly) implemented by the weaver and delegate to | |
// the original setter and getter. (As well as giving access to the name. Well, we need it | |
// and it has to go somewhere.) | |
public struct TheImplementationWrappingDecimalAccessors : IPreviousPropertyImplementation<Decimal> | |
{ | |
public String GetPropertyName() => throw new NotImplementedException(); | |
public Decimal Get() => throw new NotImplementedException(); | |
public void Set(Decimal value) => throw new NotImplementedException(); | |
} | |
public struct TheImplementationWrappingInt32Accessors : IPreviousPropertyImplementation<Int32> | |
{ | |
public String GetPropertyName() => throw new NotImplementedException(); | |
public Int32 Get() => throw new NotImplementedException(); | |
public void Set(Int32 value) => throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// The final class the weaver would produce. It's INotifyPropertyChanged since | |
/// the mix in is. | |
/// </summary> | |
public class ClassThatHadItsPropertiesModified | |
: INotifyPropertyChanged | |
{ | |
#region Delegating INotifyPropertyChanged to the mix in. | |
MyMixIn<ClassThatHadItsPropertiesModified> myMixIn; | |
public event PropertyChangedEventHandler PropertyChanged { | |
add { | |
myMixIn.PropertyChanged += value; | |
} | |
remove { | |
myMixIn.PropertyChanged -= value; | |
} | |
} | |
#endregion | |
#region Decimal | |
TheImplementationWrappingDecimalAccessors decimalAccessors; | |
public MyPropertyImplementation< | |
Decimal, | |
ClassThatHadItsPropertiesModified, | |
TheImplementationWrappingDecimalAccessors | |
> | |
decimalImplementation; | |
public ClassThatHadItsPropertiesModified() | |
{ | |
decimalImplementation.originalImplementation = decimalAccessors; | |
} | |
public Decimal Decimal { | |
get { | |
return decimalImplementation.Get(this, ref myMixIn); | |
} | |
set { | |
decimalImplementation.Set(this, ref myMixIn, value); | |
} | |
} | |
#endregion | |
#region Int32 | |
TheImplementationWrappingDecimalAccessors int32Accessors; | |
public MyPropertyImplementation< | |
Int32, | |
ClassThatHadItsPropertiesModified, | |
TheImplementationWrappingInt32Accessors | |
> | |
int32Implementation; | |
public Int32 Int32 { | |
get { | |
return int32Implementation.Get(this, ref myMixIn); | |
} | |
set { | |
int32Implementation.Set(this, ref myMixIn, value); | |
} | |
} | |
#endregion | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment