So, how do you go about dealing with multiple levels of child content? Lets say you have this sequence of components deriving from each other:
Modal -> DialogBox -> MyPersonalDialogBox
So DialogBox wants to put the child content of MyPersonalDialogBox inside a DIV, with a title bar on top and buttons on the bottom. Modal wants to put DialogBox's content inside himself so that he can present that content modally.
Obviously we can use containment instead of derivation, and have that working fine, so DialogBox USES a modal component, and my dialog box USES a DialogBox component. But ultimately that's not how OO should work. My dialog box 'is a' dialog box which 'is a' modal component, and we want to have virtual methods that can be called from baser classes up to more derived classes, and helper methods that can accept any modal component or any dialog box and so forth.
But I can't figure out how to deal with the layered child content when doing it this way. No matter what I do, the content ends up not rendered within the parent class' embrace but outside of it, or I end up with one ChildContent hiding the other and so forth. It's probably something so utterly obvious I can't see it.
Is there any specific reason why you want to use inheritance for this scenario? The containment model seems pretty clean:
Modal.cshtml
<div>
@ChildContent
</div>
Dialog.cshtml
<Modal>
<h2>Dialog</h2>
@ChildContent
</Modal>
MyDialog.cshtml
<Dialog>
<button>Super OK!</button>
</Dialog>
If you need to treat these components generically you could just implement an interface.
It's for the reasons I indicated. There is a clear inheritance relationship, and without that, you lose a lot of the reasons that inheritance was invented: the ability to create virtual interfaces that derived classes can implement and to pass the derived class to something that takes the base class, with all of the myriad advantages that that entails. It's pretty basic OO reasoning, it seems to me.
We already have the containment version working. But if that's the only way to do it in Blazor, then I'd argue that Blazor is missing some massive benefits of OO programming.
without that, you lose a lot of the reasons that inheritance was invented: the ability to create virtual interfaces that derived classes can implement and to pass the derived class to something that takes the base class
Yes, I understand all that. I was just interested if you had specific use cases where you planned to leverage the is-a relationship established by inheritance. Instead of having a generic inheritance vs composition argument I find it helps to talk about concrete scenarios.
We do have some, but I think that the basic argument is the important one. I'm sure we could hack together something to do what we really to do, so we don't need help with that. The issue is whether Blazor is an OO component model, or not? I think it obviously needs to be.
Otherwise the argument would have to be not whether we have a specific application at the moment, but whether Blazor is going to deny application of those benefits of inheritance to all its users. And I don't think it needs to be debated how powerful those benefits are this many decades down the OO line, right? That's ultimately the issue at hand. If it's not going to support component inheritance, then that's sort of the position that, tacitly or otherwise, is being taken.
@DeanRoddey There is a strong argument for composition over inheritance. Maybe this is something you can look into. Composition over inheritance - WIKI
It is something I personally am a big fan of. It reduces coupling in a big way.
I just reject that article's premise on fundamentals. It's not like people have been hallucinating for 50 years. OO principles of inheritance and polymorphism are powerful and proven. They are at the core of most of the serious software that exists today. Of course, these days, everyone seems to be trying to push the next big thing. I'm holding out for nutmeg based programming myself.
And obviously implementing these capabilities doesn't in any way prevent you from using composition slash containment where that is most effective. If Blazor only implemented inheritance and not containment/composition, and I was arguing with you that inheritance is all you need and I prefer that, I doubt you'd accept that as a good answer. It's hard for me to see an argument for not supporting one of the most widely used and profoundly impactful software techniques of the last half century.
@DeanRoddey Go language creators at Google and it's users would probably disagree without you :) Also from what I've read about WPF it doesn't provide inheritance either and people seem to create UIs just fine with it.
But... Is the issue where what can one do given a stick? Or is it, how could maybe Blazor be better than WPF, a UI framework from back when one wrote software by rubbing sticks together?
@DeanRoddey Lot of UI component systems in this space like one of the lead component systems React, doesn't use inheritance. Blazor/Razor Components team doesn't have unlimited resources, so you have to come up with use case where inheritance has clear advantage over composition like @danroth27 said. Use case where something is extremely hard to create with composition and easy to create with inheritance. Look into Angular 2.3+, I read they added inheritance for their components in 2016.
I just feel like lot of cases, like this component system, inheritance makes things more complex and less maintainable without added benefits.
Lots of stuff in the browser UI world has sucked tremendously from the beginning because it's been a toy system. But everyone (to my dismay) seems intent on trying to use it to write real applications (or at least as realer-like as any browser app can be, which leaves a lot to be desired.) If that's the case, then much more serious component libraries are going to need to be created.
I've created multiple serious UI frameworks in the desktop world, and I couldn't imagine that anyone would question the value of being able to get or set the checked state of any variation of a family of checkable controls, to get/set the caption text of any in a family of text display controls, to manipulate the list items in any of a family of list based controls, to manage the image in any of a family of image display controls, that any variation of a family of menu types can be manipulated generically, and on and on.
In some cases that's not an issue currently with Blazor, because there's not always a need for multiple layers of child content to do some of that. But as soon as you hit a need to have nested child contents, then that new control is no longer part of that derivation chain and it becomes non-interchangeable with its breathren, despite clearly conceptually being one. Manually recreating methods and delegating doesn't help because you need the common base classes to have generic manipulation.
That that would be questioned in this day and age wobbles my mind. It's at the core of being able to create reusable content.
And the thing is, I don't think it's that huge a deal. There is already a class derivation involved. It just needs a way for each layer in the chain to manage its own child content. That's all that's missing, it seems to me.
Anyway, that's all I'm going to say. I'm not going to get into an endless debate on the subject. I'd just say that, if Blazor doesn't, something else that comes afterwards probably will; and, other things being equal, it would have a substantial architectural advantage. It's not just about the resources of the Blazor team, it's also about the resources of the (many, many more) teams that use these systems and which ones make their development lives the least burdensome.
So, anyhoo, they can make of that what they will.
Before I leave it, I'll give you a very clear example, which maybe some folks here aren't considering because they look at this purely from the standpoint of someone writing applications, not someone creating tools.
At some point, presumably, someone is going to make some tools for visually building blazor based screens. This is VASTLY easier to do if there is a clear inheritance chain for related families of components, because it allows the tool to ask for configuration data in a generic way and present it without having to get into all kinds of component specific stuff, or pushing any configuration logic into the components themselves. It also allows components along the chain to override or hide or add to attributes in lower levels which can be very important.
If my touch screen UI development system didn't have this kind of clear inheritance chain the UI designer would be vastly harder to do.
@DeanRoddey Visual tools needing a clear inheritance chain is a good argument. A fruitful discussion around that concrete point could be interesting.
@danroth27 already said it:
[...]Instead of having a generic inheritance vs composition argument[...]
Thanks for contacting us. We believe that the question you've raised have been answered. If you still feel a need to continue the discussion, feel free to reopen it and add your comments.
Most helpful comment
Yes, I understand all that. I was just interested if you had specific use cases where you planned to leverage the is-a relationship established by inheritance. Instead of having a generic inheritance vs composition argument I find it helps to talk about concrete scenarios.