-
Notifications
You must be signed in to change notification settings - Fork 33
DittoView: Enhancement to support unwrapping & downcasting view-models #219
Conversation
f30305b
to
93569b0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of comments
if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(DittoViewModel<>)) | ||
{ | ||
var viewProperty = modelType.GetProperty("View", Ditto.MappablePropertiesBindingFlags); | ||
model = FastPropertyAccessor.GetValue(viewProperty, model); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there needs to be some checks here to ensure it's actually castable to expected view model type before assigning it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, I had included an IsAssignableFrom
check in there, but then thought that the as
casting further down would handle that...
var typedModel = model as TViewModel;
as it would cast as null
if it wasn't castable, (which is how it currently works).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh good point, I didn't look past the change. Happy to leave as is then.
var baseDittoViewModel = model as BaseDittoViewModel; | ||
if (baseDittoViewModel != null) | ||
{ | ||
content = baseDittoViewModel.Content ?? content; | ||
culture = baseDittoViewModel.CurrentCulture ?? culture; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not saying this is bad, but whats the reason for this addition? When would this be different? (can't really recall)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I couldn't think of how they'd be different. I guess it's just because they were available on the BaseDittoViewModel
?
I'm happy to remove that part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it passes all the tests, I'm not against it as it probably does make sense. I was just querying the change. I can't think it through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't overly happy with the ??
null-coalescing operator here. I'm airing on the side of removing those 2 lines now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dunno. I can't think of a time they would be different, but I do think reusing them make sense given we will be in an inner context by then. I say leave it.
@mattbrailsford - re: unit-test - I couldn't figure out how to unit-test the |
Merging in. We can look at the unit-test later. Thanks for the quick turnaround @mattbrailsford #h5yr |
Yea, that's when it starts to get confusing to me as your start bringing in web contexts etc |
@mattbrailsford - I'd found an scenario a while back where if a
DittoView<T>
page referenced anotherDittoView<T>
page, but the view-model was castable, the code wouldn't cast it and Ditto would recreate the object.That might sound like a mouthful, but I'll try to explain...
Say you've got these POCOs...
If you had
DittoView<OtherModel>
on a page template, andDittoView<MasterModel>
on the layout template, the DittoView code would be creating the object twice, rather than downcasting it to the inherited type.This PR adds in a check to see if the model object is a
DittoViewModel<>
and to unwrap the inner view-model, so it can be reused.Hopefully this makes sense? (and is backwards compatible / a non-breaking change)