In question about usefulness of IoC Container, the winning submitter mentioned that with an IoC container you can take this:
public class UglyCustomer : INotifyPropertyChanged { private string _firstName; public string FirstName { get { return _firstName; } set { string oldValue = _firstName; _firstName = value; if(oldValue != value) OnPropertyChanged("FirstName"); } } private string _lastName; public string LastName { get { return _lastName; } set { string oldValue = value; _lastName = value; if(oldValue != value) OnPropertyChanged("LastName"); } } }
to this:
var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper());
Questions:
For your second code snippet to work, NotifyPropertyChangedWrapper
would certainly have to use reflection (or dynamic
) to generate a class that provides an interface compatible with Customer
and implements the automatic property notification. There shouldn't be any data binding issues, but there would be a little overhead.
An simplified implementation that uses a dynamic object could look something like this:
public class NotifyPropertyChangedWrapper<T> : DynamicObject, INotifyPropertyChanged { private T _obj; public NotifyPropertyChangedWrapper(T obj) { _obj = obj; } public override bool TryGetMember( GetMemberBinder binder, out object result) { result = typeof(T).GetProperty(binder.Name).GetValue(_obj); return true; } // If you try to set a value of a property that is // not defined in the class, this method is called. public override bool TrySetMember( SetMemberBinder binder, object value) { typeof(T).GetProperty(binder.Name).SetValue(_obj, value); OnPropertyChanged(binder.Name); return true; } // Implement OnPropertyChanged... }
Obviously, any code that consumes one of these objects would lose any static type safety. The other option is to generate a class implementing the same interface as the class being wrapped. There are lots of examples for this on the web. The main requirement is that your Customer
would have to either be an interface
or it would need all of its properties to be virtual.
To do this in a generic way (i.e. a single piece of code implementing INotifyPropertyChanged for any class) use a proxy. There are lots of implementations around to do this with Castle.DynamicProxy or LinFu or Unity. These proxy libraries have good support in IoC containers, for example DynamicProxy has good integration with Castle Windsor and Unity interception (or whatever it's called) has obviously good integration with the Unity container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With