I am trying to implement a very simple and more importantly optional object tracking system similar to how entity framework tracks object changes (How change tracking works in Entity Framework).
I have a base class that all other objects inherit from. This class has 1 boolean field called modified. The explicit solution to this is to update every setter on all properties of other classes to set modified = true when the setter is triggered. This solution has been presented in detail here Create an event to watch for a change of variable.
I want a more implicit solution to this. I have a lot of objects and a LOT of properties. Updating the setter is incredibly messy. I don't want to directly mimmic how entity framework does things because it is too expensive for my current requirements. I want a list of objects that i can loop to check of modified == true. This allows me to optionally track object and quickly check if they have changed without having to trigger an update for each individual object. Is there a way that i can set some sort of listener on all of the property getter and setters implicitly?
I know this code doesnt exist, but does .NET have a way to monitor the object to see if it has changed.
[OnChange=ObjectChanged()] //maybe this way
public class MyClass
{
bool modified {get; set;}
public MyClass() : OnChange(ObjectChanged) //or this way
{
}
private void ObjectChanged()
{
modified = true;
}
}
As i mentioned, i dont want to update every setter or copy what entity framework does.
There's nothing built-in in the .NET framework for this, but there are third-party tools to do exactly that.
One such option would be Fody/PropertyChanged, which injects OnPropertyChanged calls into all automatic property setters of your classes. You can subscribe to the PropertyChanged event and update your Boolean flag. As an additional bonus, (a) you get the name of the property that changed and (b) other classes (e.g. your UI framework) can subscribe to the event as well.
Related
Considering a class with a large number of properties, I want to implement a Dirty flag (in order to know if I should update the value in the database).
Is there any way to raise PropertyChanged on All the properties without having to manually go through and pluck it in the setter?
Edit to clear up some things: I did go through the thread that was linked here, and found some things, but unfortunately they do not suit my need. I don't really need to send an event, I just need to flip a flag. Also, that thread is quite old, and I hoped that maybe with C# 7 something came out which would help with it, that I missed in the changelog.
Why don't I just go and do it manually? Well, I might have to. But I'd have to declare the "hidden" variables, manage the code myself, I hoped MS would've done something to help, maybe something like was suggested in the other topic
public Type Name {get; set; notify { () => IsDirty = true; }}
that would help a lot (ignoring the fact it would ask me to declare the get and set anyways because they're abstract.
Add a method that looks like this:
public void Test()
{
if(PropertyChanged != null)
PropertyChanged(new PropertyChangedEventArgs(null));
}
Passing a null or empty string as the property name tells consumers that all properties have been changed.
https://msdn.microsoft.com/en-us/library/system.componentmodel.propertychangedeventargs.propertyname(v=vs.110).aspx
You can but its also a lot of work. Make an Attribute and use it on those properties. in the base class of your ViewModel,
which will implement INotifyPropertyChanged,
You register in its Constructor to the PropertyChanged event and check via reflection if the property that changed has your attribute on it,
and then set IsDirty accordingly.
First off, I have read through a list of postings on this topic and I don't feel I have grasped properties because of what I had come to understand about encapsulation and field modifiers (private, public..ect).
One of the main aspects of C# that I have come to learn is the importance of data protection within your code by the use of encapsulation. I 'thought' I understood that to be because of the ability of the use of the modifiers (private, public, internal, protected). However, after learning about properties I am sort of torn in understanding not only properties uses, but the overall importance/ability of data protection (what I understood as encapsulation) within C#.
To be more specific, everything I have read when I got to properties in C# is that you should try to use them in place of fields when you can because of:
1) they allow you to change the data type when you can't when directly accessing the field directly.
2) they add a level of protection to data access
However, from what I 'thought' I had come to know about the use of field modifiers did #2, it seemed to me that properties just generated additional code unless you had some reason to change the type (#1) - because you are (more or less) creating hidden methods to access fields as opposed to directly.
Then there is the whole modifiers being able to be added to Properties which further complicates my understanding for the need of properties to access data.
I have read a number of chapters from different writers on "properties" and none have really explained a good understanding of properties vs. fields vs. encapsulation (and good programming methods).
Can someone explain:
1) why I would want to use properties instead of fields (especially when it appears I am just adding additional code
2) any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
3) Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Thanks and sorry for the long post - I didn't want to just ask a question that has been asked 100x without explaining why I am asking it again.
1) why I would want to use properties
instead of fields (especially when it
appears I am just adding additional
code
You should always use properties where possible. They abstract direct access to the field (which is created for you if you don't create one). Even if the property does nothing other than setting a value, it can protect you later on. Changing a field to a property later is a breaking change, so if you have a public field and want to change it to a public property, you have to recompile all code which originally accessed that field.
2) any tips on recognizing the use of
properties and not seeing them as
simply methods (with the exception of
the get;set being apparent) when
tracing other peoples code?
I'm not totally certain what you are asking, but when tracing over someone else's code, you should always assume that the property is doing something other than just getting and setting a value. Although it's accepted practice to not put large amounts of code in getters and setter, you can't just assume that since it's a property it will behave quickly.
3) Any general rules of thumb when it
comes to good programming methods in
relation to when to use what?
I always use properties to get and set methods where possible. That way I can add code later if I need to check that the value is within certain bounds, not null etc. Without using properties, I have to go back and put those checks in every place I directly accessed the field.
One of the nice things about Properties is that the getter and the setter can have different levels of access. Consider this:
public class MyClass {
public string MyString { get; private set; }
//...other code
}
This property can only be changed from within, say in a constructor. Have a read up on Dependency Injection. Constructor injection and Property injection both deal with setting properties from some form of external configuration. There are many frameworks out there. If you delve into some of these you will get a good feel for properties and their use. Dependency injection will also help you with your 3rd question about good practice.
When looking at other people's code, you can tell whether something is a method or a property because their icons are different. Also, in Intellisence, the first part of a property's summary is the word Property.
You should not worry about the extra code needed for accessing fields via properties, it will be "optimized" away by the JIT compiler (by inlining the code). Except when it is too large to be inlined, but then you needed the extra code anyway.
And the extra code for defining simple properties is also minimal:
public int MyProp { get; set; } // use auto generated field.
When you need to customize you can alway define your own field later.
So you are left with the extra layer of encapsulation / data protection, and that is a good thing.
My rule: expose fields always through properties
While I absolutely dislike directly exposing fields to the public, there's another thing: Fields can't be exposed through Interfaces; Properties can.
There are several reasons why you might want to use Properties over Fields, here are just a couple:
a. By having the following
public string MyProperty { get; private set; }
you are making the property "read only". No one using your code can modify it's value. There are cases where this isn't strictly true (if your property is a list), but these are known and have solutions.
b. If you decide you need to increase the safety of your code use properties:
public string MyProperty
{
get { return _myField; }
set
{
if (!string.IsNullOrEmpty(value))
{
_myField = value;
}
}
}
You can tell they're properties because they don't have (). The compiler will tell you if you try to add brackets.
It's considered good practise to always use properties.
There are many scenarios where using a simple field would not cause damage, but
a Property can be changed more easily later, i.e. if you want to add an event whenever the value changes or want to perform some value/range checking.
Also, If you have several projects that depend on each other you have to recompile all that depend on the one where a field was changed to a property.
Using fields is usually practiced in private classes that is not intended to share data with other classes, When we want our data to be accessible by other classes we use properties which has the ability to share data with other classes through get and set which are access methods called Auto Properties that have access to data in private classes, also you can use both with access modifiers Full Property in the same class allowing the class to use data privately as data field and in the same time link the private field to a property that makes the data accessible to other classes as well, see this simple example:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
The private string _name is used by the class only, while the Name property is accessible by other classes in the same namespace.
why I would want to use properties instead of fields (especially when it appears I am just adding additional code
You want to use properties over fields becuase, when you use properties you can use events with them, so in a case when you want to do some action when a property changes, you can bind some handlers to PropertyChanging or PropertyChanged events. In case of fields this is not possible. Fields can either be public or private or protected, in case of props you can make them read-only publicly but writable privately.
any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
A method should be used when the return value is expected to be dynamic every-time you call, a property should be used when the return value is not that greatly dynamic.
Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Yes, I strongly recommend to read Framework Design guidelines for best practices of good programming.
Properties are the preferred way to cover fields to enforce encapsulation. However, they are functional in that you can expose a property that is of a different type and marshal the casting; you can change access modifiers; they are used in WinForms data binding; they allow you to embed lightweight per-property logic such as change notifications; etc.
When looking at other peoples code, properties have different intellisense icons to methods.
If you think properties are just extra code, I would argue sticking with them anyway but make your life easier by auto-generating the property from the field (right-click -> Refactor -> Encapsulate Field...)
Properties allow you to do things other than set or get a value when you use them. Most notably, they allow you to do validation logic.
A Best Practice is to make anything exposed to the public a Property. That way, if you change the set/get logic at a later time, you only have to recompile your class, not every class linked against it.
One caveat is that things like "Threading.Interlocked.Increment" can work with fields, but cannot work with properties. If two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerField, the value will get increased by two even if there is no other locking. By contrast, if two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerProperty, the value of that property might get incremented by two, or by one, or by -4,294,967,295, or who knows what other values (the property could be written to use locking prevent values other than one or two in that scenario, but it could not be written to ensure the correct increment by two).
I was going to say Properties (setters) are a great place to raise events like NotifyPropertyChanged, but someone else beat me to it.
Another good reason to consider Properties: let's say you use a factory to construct some object that has a default constructor, and you prepare the object via its Properties.
new foo(){Prop1 = "bar", Prop2 = 33, ...};
But if outside users new up your object, maybe there are some properties that you want them to see as read-only and not be able to set (only the factory should be able to set them)? You can make the setters internal - this only works, of course, if the object's class is in the same assembly as the factory.
There are other ways to achieve this goal but using Properties and varying accessor visibility is a good one to consider if you're doing interface-based development, or if you expose libraries to others, etc.
I am using Entity Framework and Code First approach in a WPF MVVM application backed by a SQL CE database. I am trying to design a model class that can simply update one of its property values in response to another one of its property values changing. Basically, I am looking for a way to define a poco that is "self-tracking" after the instance is initialized by EF. If the answer involves abandoning Code First, then maybe that is the only viable route (not sure). A basic example:
class ThingModel
{
public int Id { get; set; }
public bool OutsideDbNeedsUpdate { get; set; }
private string _foo;
public string Foo
{
get { return _foo; }
set
{
if (_foo != value)
{
_foo = value;
OutsideDbNeedsUpdate = true;
}
}
}
}
However, the problem with the above is that whenever DbContext is initializing an instance at runtime and setting the fields, my class is prematurely setting the dependent field in response. In other words, I am searching for a simple pattern that would allow my poco class to ONLY do this special change tracking after EF has finished initializing the fields on an instance.
I realize I could do something like the solution here
but my business case requires that this special change tracking be decoupled from the EF change tracking, in other words, I require the ability to SaveChanges regardless of the state of the HasChanges property above. This is because I would like to be able to periodically check the HasChanges property on my entities and in turn update dependent values in an outside database (not the same one backing the EF DbContext) and many changes/saves may happen to the EF DB between pushes to the outside DB. Hence the reason I was hoping to just persist the flag with the record in my DB and reset it to false when the periodic update to the outside DB occurs.
After your edit I think you can use the ObjectMaterialized event.
This event is raised after all scalar, complex, and reference properties have been set on an object, but before collections are loaded.
Put this in the constructor of your DbContext:
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
HandleObjectMaterialized;
And the method:
private void HandleObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{ }
Now the question is, what to put in the method body? Probably the easiest solution is to define an interface
interface IChangeTracker
{
bool Materialized { get; set; }
bool OutsideDbNeedsUpdate { get; }
}
and let the classes you want to track implement this interface.
Then, in HandleObjectMaterialized you can do:
var entity = e.Entity as IChangeTracker;
if (entity != null)
{
entity.Materialized = true;
}
After this you know when you can set OutsideDbNeedsUpdate internally.
Original text
Generally it is not recommended to have properties with side effects (well, more exact, with more side effects than changing the state the represent). Maybe there are exceptions to this rule, but most of the time it is just not a good idea to have dependencies between properties.
I have to guess a bit what you can do best, because I don't know what your real code is about, but it might be possible to put the logic in the getter. Just an example:
public State State
{
get { return this.EndDate.HasValue ? MyState.Completed : this._state; }
set { this._state = value; }
}
This does not remove the mutual dependencies, but it defers the moment of effect to the time the property is accessed. Which in your case may be not sooner than SaveChanges().
Another strategy is making a method that sets both properties at once. Methods are expected to have side effects, especially when their names clearly indicate it. You could have a method like SetMasterAndDependent (string master).
Now methods are not convenient in data binding scenarios. In that case you better let the view model set both properties or call the method as above.
I'm looking for a clean and elegant solution to handle the INotifyPropertyChanged event of nested (child) objects. Example code:
public class Person : INotifyPropertyChanged {
private string _firstName;
private int _age;
private Person _bestFriend;
public string FirstName {
get { return _firstName; }
set {
// Short implementation for simplicity reasons
_firstName = value;
RaisePropertyChanged("FirstName");
}
}
public int Age {
get { return _age; }
set {
// Short implementation for simplicity reasons
_age = value;
RaisePropertyChanged("Age");
}
}
public Person BestFriend {
get { return _bestFriend; }
set {
// - Unsubscribe from _bestFriend's INotifyPropertyChanged Event
// if not null
_bestFriend = value;
RaisePropertyChanged("BestFriend");
// - Subscribe to _bestFriend's INotifyPropertyChanged Event if not null
// - When _bestFriend's INotifyPropertyChanged Event is fired, i'd like
// to have the RaisePropertyChanged("BestFriend") method invoked
// - Also, I guess some kind of *weak* event handler is required
// if a Person instance i beeing destroyed
}
}
// **INotifyPropertyChanged implementation**
// Implementation of RaisePropertyChanged method
}
Focus on the BestFriend Property and it's value setter. Now I know that I could do this manually, implementing all steps described in the comments. But this is going to be a lot of code, especially when I'm planning to have many child properties implementing INotifyPropertyChanged like this. Of course they are not going to be always of same Type, the only thing they have in common is the INotifyPropertyChanged interface.
The reason is, that in my real scenario, I have a complex "Item" (in cart) object which has nested object properties over several layers (Item is having a "License" object, which can itself have child objects again) and I need to get notified about any single change of the "Item" to be able to recalculate the price.
Do you some good tips or even some
implementation to help me to solve
this?
Unfortunately, I'm not able/allowed to use post-build steps like PostSharp to accomplish my goal.
since I wasn't able to find a ready-to-use solution, I've done a custom implementation based on Pieters (and Marks) suggestions (thanks!).
Using the classes, you will be notified about any change in a deep object tree, this works for any INotifyPropertyChanged implementing Types and INotifyCollectionChanged* implementing collections (Obviously, I'm using the ObservableCollection for that).
I hope this turned out to be a quite clean and elegant solution, it's not fully tested though and there is room for enhancements. It's pretty easy to use, just create an instance of ChangeListener using it's static Create method and passing your INotifyPropertyChanged:
var listener = ChangeListener.Create(myViewModel);
listener.PropertyChanged +=
new PropertyChangedEventHandler(listener_PropertyChanged);
the PropertyChangedEventArgs provide a PropertyName which will be always the full "path" of your Objects. For example, if you change your Persons's "BestFriend" Name, the PropertyName will be "BestFriend.Name", if the BestFriend has a collection of Children and you change it's Age, the value will be "BestFriend.Children[].Age" and so on. Don't forget to Dispose when your object is destroyed, then it will (hopefully) completely unsubscribe from all event listeners.
It compiles in .NET (Tested in 4) and Silverlight (Tested in 4). Because the code in seperated in three classes, I've posted the code to gist 705450 where you can grab it all: https://gist.github.com/705450 **
*) One reason that the code is working is that the ObservableCollection also implements INotifyPropertyChanged, else it wouldn't work as desired, this is a known caveat
**) Use for free, released under MIT License
I think what you're looking for is something like WPF binding.
How INotifyPropertyChanged works is that the RaisePropertyChanged("BestFriend"); must only be fored when the property BestFriend changes. Not when anything on the object itself changes.
How you would implement this is by a two step INotifyPropertyChanged event handler. Your listener would register on the changed event of the Person. When the BestFriend gets set/changed, you register on the changed event of the BestFriend Person. Then, you start listening on changed events of that object.
This is exactly how WPF binding implements this. The listening to changes of nested objects is done through that system.
The reason this is not going to work when you implement it in Person is that the levels can become very deep and the changed event of BestFriend does not mean anything anymore ("what has changed?"). This problem gets larger when you have circular relations where e.g. the best friend of your monther is the mother of your best fiend. Then, when one of the properties change, you get a stack overflow.
So, how you would solve this is to create a class with which you can build listeners. You would for example build a listener on BestFriend.FirstName. That class would then put an event handler on the changed event of Person and listen to changes on BestFriend. Then, when that changes, it puts a listener on BestFriend and listens for changes of FirstName. Then, when that changes, it sends raises an event and you can then listen to that. That's basically how WPF binding works.
See http://msdn.microsoft.com/en-us/library/ms750413.aspx for more information on WPF binding.
Interesting solution Thomas.
I found another solution. It's called Propagator design pattern. You can find more on the web (e.g. on CodeProject: Propagator in C# - An Alternative to the Observer Design Pattern).
Basically, it's a pattern for updating objects in a dependency network. It is very useful when state changes need to be pushed through a network of objects. A state change is represented by an object itself which travels through the network of Propagators. By encapsulating the state change as an object, the Propagators become loosely coupled.
A class diagram of the re-usable Propagator classes:
Read more on CodeProject.
I have been Searching the Web for one day now and I found another nice solution from Sacha Barber:
http://www.codeproject.com/Articles/166530/A-Chained-Property-Observer
He created weak references within a Chained Property Observer. Checkout the Article if you want to see another great way to implement this feature.
And I also want to mention a nice implementation with the Reactive Extensions #
http://www.rowanbeach.com/rowan-beach-blog/a-system-reactive-property-change-observer/
This Solution work only for one Level of Observer, not a full Chain of Observers.
I wrote an easy helper to do this. You just call BubblePropertyChanged(x => x.BestFriend) in your parent view model. n.b. there is an assumption you have a method called NotifyPropertyChagned in your parent, but you can adapt that.
/// <summary>
/// Bubbles up property changed events from a child viewmodel that implements {INotifyPropertyChanged} to the parent keeping
/// the naming hierarchy in place.
/// This is useful for nested view models.
/// </summary>
/// <param name="property">Child property that is a viewmodel implementing INotifyPropertyChanged.</param>
/// <returns></returns>
public IDisposable BubblePropertyChanged(Expression<Func<INotifyPropertyChanged>> property)
{
// This step is relatively expensive but only called once during setup.
MemberExpression body = (MemberExpression)property.Body;
var prefix = body.Member.Name + ".";
INotifyPropertyChanged child = property.Compile().Invoke();
PropertyChangedEventHandler handler = (sender, e) =>
{
this.NotifyPropertyChanged(prefix + e.PropertyName);
};
child.PropertyChanged += handler;
return Disposable.Create(() => { child.PropertyChanged -= handler; });
}
Check-out my solution on CodeProject:
http://www.codeproject.com/Articles/775831/INotifyPropertyChanged-propagator
It does exactly what you need - helps to propagate (in elegant way) dependent properties when relevant dependencies in this or any nested view models change:
public decimal ExchTotalPrice
{
get
{
RaiseMeWhen(this, has => has.Changed(_ => _.TotalPrice));
RaiseMeWhen(ExchangeRate, has => has.Changed(_ => _.Rate));
return TotalPrice * ExchangeRate.Rate;
}
}
Please take a look at EverCodo.ChangesMonitoring. This is a framework to handle PropertyChanged and CollectionChanged events on arbitrary hierarchy of nested objects and collections.
Create a monitor to handle all change events of the object tree:
_ChangesMonitor = ChangesMonitor.Create(Root);
_ChangesMonitor.Changed += ChangesMonitor_Changed;
Do arbitrary modifications on the object tree (all of them will be handled):
Root.Children[5].Children[3].Children[1].Metadata.Tags.Add("Some tag");
Root.Children[5].Children[3].Metadata = new Metadata();
Root.Children[5].Children[3].Metadata.Description = "Some description";
Root.Children[5].Name = "Some name";
Root.Children[5].Children = new ObservableCollection<Entity>();
Handle all events in one place:
private void ChangesMonitor_Changed(object sender, MonitoredObjectChangedEventArgs args)
{
// inspect args parameter for detailed information about the event
}
I have some objects which have been created automatically by linq2SQL.
I would like to write some code which should be run whenever the properties on these objects are read or changed.
Can I use typical get { //code } and set {//code } in my partial class file to add this functionality? Currently I get an error about this member already being defined.
This all makes sense.
Is it correct that I will have to create a method to function as the entry point for this functionality, as I cannot redefine the get and set methods for this property.
I was hoping to just update the get and set, as this would mean I wouldn't have to change all the reference points in my app. But I think I may just have to update it everywhere.
Not sure about read, but you could track changes of your objects. E.g. there is PropertyChangedEventHandler on auto generated entities.
So what have you do is to white a partial class (let's assuming you have a Person entity):
public partial class Person
{
public Person()
{
this.PropertyChanged +=
new PropertyChangedEventHandler(Person_PropertyChanged);
}
protected void Person_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// your code here
}
}
What I did when I wanted to do this was make the property private/inaccessible (since this can be done as part of the DBML definition without editing the generated code), and give it a different name than the property I want to expose. Then I implemented a public wrapper property in a partial class, using the name I wanted to expose. Then (if you want to be really fancy) implement a LINQ provider that can convert queries that refer to the wrapper properties to queries that refer to the underlying properties. I have done all this and it's been working well, but the custom LINQ provider was tricky.
Unless you modify the generated code that was made, and then add additional code to the setter (such as using the pattern like in WPF, with INotifyPropertyChanged), then this would be impossible.