-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flattening changes to nested objects #41
Comments
Hey! May you give your desired output? I believe I understand the issue but, anyways, give me that detail. Thank you in advance! |
Hey! Thanks for the quick reply. If an object in a collection was added or removed, I probably need to do a custom serialization of that object - which shouldn't be too bad. I would probably just override the ToString method on If an object has changed in these collections of objects, I'm not quite sure how to dig into that. I'd like to have access to the name of the changed property and the before/after values just as I do with non-collection properties of the original, 'parent' object. Does that make sense? I'm not sure if I'm explaining this very well. |
I'll try to reproduce your case to answer your question. Anyway, if I'm not mistaken, TrackerDog should be able to give you property changes from any association, even from tracked collections, but I want to confirm this myself. |
Thank you very much! If I can assist further in any way, or answer further questions, please let me know. I appreciate the help. |
@rtroberts No problem! So I've coded this sample: public class A
{
public virtual IList<B> B { get; set; }
}
public class B
{
public virtual string Text { get; set; }
}
class Program
{
static void Main(string[] args)
{
var config = ObjectChangeTracking.CreateConfiguration();
config.TrackThisType<A>();
config.TrackThisType<B>();
var trackableObjectFactory = config.CreateTrackableObjectFactory();
var a = trackableObjectFactory.CreateOf<A>();
var b = new B { Text = "hello world" };
a.B.Add(b);
b = a.B[0];
b.Text = "byeeeeeeee";
// Has 1 property changed: B because we added an instance of A
var changeTrackerA = a.GetChangeTracker();
// Has 1 property changed: Text because we changed its value
var changeTrackerB = b.GetChangeTracker();
}
} And you want that both Believe or not, but I thought that it was behaving that way but I was absolutely mistaken about that. Please confirm if this is the problem so I can work on implementing the change. It shouldn't hard to implement since I see that |
That's exactly correct, yes. I expected |
@rtroberts Ok! I'll take a look. I expect to give you a new TrackerDog version with this feature very soon (few days, give me 2-3 days)! Thank you for identifying this problem ;) |
Hey, I'll try to address it this weekend. I couldn't find a room to implement the fix during this week. Sorry. |
@rtroberts I've located the line on which I can fix the problem: CollectionPropertyInterceptor (line 37) When an item is being added to a given collection the whole item isn't turned into a change trackable object using collection parent object's change tracker. I believe that changing that line to call another existing overload giving the whole existing change tracker will give the desired output. |
How interesting! Thanks so much for finding this so quickly! You're a rockstar. |
@rtroberts No problem! And not a rockstar: I'm the author :D I can easily identify issues. Anyway, thank you again. I need to solve another issue: I'm on Linux since some months and, anyway, even when I was on Windows full time, I was developing in a Win10 VM. When I wanted to run that VM I found that it's broken (Win10 is in the "automatic repair loop"). I'll try to fix this problem today so tomorrow I can run VS2017 since TrackerDog is distributed for .NET 4.5 and .NET Standard. |
@rtroberts No way: I can't fix the VM. I believe that since full .NET Framework can use .NET Standard libraries, maybe it's time to distribute TrackerDog as just a .NET Standard library. That is, I could continue improving it using VSCode either in Windows or Linux. It shouldn't be an issue since the project has a .NET Standard build already. Sorry for the delay, is this urgent? |
@rtroberts I've already migrated the entire project to just build a .NET Standard library and now it's a VSCode workspace. Definitively, I expect this week to provide the fix to your issue. |
Nice! Yeah, I'm personally on .NET Core, so moving to .NET Standard makes sense to me. I appreciate your help on this! Thank you. |
@rtroberts Ok! I'm still on this issue, I'm having troubles to find room to invest in it, but I hope I'll be able to give you the fix this week...! |
@rtroberts For now, I've been able to implement the change for this case:
I need to fix the thing in yet another case: when a collection already contains items and they're converted into change-trackable objects. In that case, I've found that change tracker isn't being shared. Let's see if this weekend I can share with you an assembly here so you may test the fix in your own project. If it works as you expect, we publish a new TrackerDog version! ;-) |
@rtroberts Argh. I believe that right now should work but I've encountered a side-effect when implementing the solution. Say you've a class Currently, What happens with that above described case? Only one property of one instance gets tracked, because when TrackerDog adds a tracking to say I need to find a way to store trackings of same property of many different instances of the same type. It shouldn't be hard... I believe that this is the last frontier! |
Sorry I've been out of touch! It's been crazy busy these past couple weeks. What can I do to help? |
@rtroberts Hey, are you in Gitter? So we can discuss some points in real time. |
I am not, but I could sign up if it would help! |
@rtroberts Yes, please! :) |
Say I have a tracked class with a few untracked properties, a few tracked properties, and a few tracked collections of objects - which are themselves trackable:
Multiple tracked fields, additions or subtractions to tracked collections, or changes to objects within tracked collections can occur at one time. I'm trying to flatten all these changes to the simplest representation possible, and add them to the
IList<DocumentChange>
you see here.Right now, I'm just iterating through each value in
document.GetChangeTracker().ChangedProperties
and getting theOldValue
andCurrentValue
properties - and calling ToString() on them. This is fairly naive but works great for the simple properties (like strings). Of course, it fails on tracked collections (literally printing outCastle.IListProxy
or whatever).Therefore I hacked in something like,
if (changedProperty.CurrentValue is IReadOnlyChangeTrackableCollection) { *make up a lame value, like "Collection Changed"* }
.I think I could check the
ChangedProperties
against each concrete type I care about, like:if (changedProperty.GetType() == typeof(IList<Comment>))
, and then cast theCurrentValue
to the type I need, so I have access to all the TrackerDog collection methods. But that could quickly get out of hand for very large tracked objects.Does TrackerDog support the kind of reflection I'd need to get at the changed values within nested, trackable objects? If I wanted to know that the Document object changed, and specifically that a property changed on a single
MemberAttribute
above, for example, would TrackerDog be able to get that information?The text was updated successfully, but these errors were encountered: