Skip to content
This repository has been archived by the owner on Dec 13, 2021. It is now read-only.

DittoView: Enhancement to support unwrapping & downcasting view-models #219

Merged
merged 3 commits into from
Jul 27, 2017

Conversation

leekelleher
Copy link
Collaborator

@mattbrailsford - I'd found an scenario a while back where if a DittoView<T> page referenced another DittoView<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...

public class MasterModel
{
  public string Something { get; set; }
}

public class OtherModel : MasterModel
{
  public string Whatever { get; set; }
}

If you had DittoView<OtherModel> on a page template, and DittoView<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)

@leekelleher leekelleher added this to the 0.11.0 milestone Jul 27, 2017
@leekelleher leekelleher self-assigned this Jul 27, 2017
@leekelleher leekelleher force-pushed the devx/dittoview-enhancements branch from f30305b to 93569b0 Compare July 27, 2017 16:12
Copy link
Collaborator

@mattbrailsford mattbrailsford left a 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);
Copy link
Collaborator

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

Copy link
Collaborator Author

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).

Copy link
Collaborator

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;
Copy link
Collaborator

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)

Copy link
Collaborator Author

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.

Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator

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.

@leekelleher
Copy link
Collaborator Author

@mattbrailsford - re: unit-test - I couldn't figure out how to unit-test the DittoView class - guessing you hit the same problem (since there aren't any existing tests for it)?

@leekelleher leekelleher merged commit 8a89119 into develop Jul 27, 2017
@leekelleher leekelleher deleted the devx/dittoview-enhancements branch July 27, 2017 16:46
@leekelleher
Copy link
Collaborator Author

Merging in. We can look at the unit-test later. Thanks for the quick turnaround @mattbrailsford #h5yr

@mattbrailsford
Copy link
Collaborator

Yea, that's when it starts to get confusing to me as your start bringing in web contexts etc

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging this pull request may close these issues.

2 participants