Developer Story: Visual Studio Extension: Creating Extract control feature

Published: 10/5/2017 11:36:00 AM

Hi, It's Milan Mikuš reporting in for my first DotVVM developer story.  I work for Riganti s.r.o. as you might have guessed and I have been developing DotVVM Visual Studio  extension for as long as it exists. It's been a very interesting experience to say at least, exciting, sometimes harsh, but never boring. What I love about this project is, that I can make your work easier bit by bit as the extension takes care of the tiresome stuff for you. I write this blog post today to tell you about a new feature I am implementing that I really hope you'll like.

developer-banner-milan-01-01
For a long time, there was this idea floating around among our frontend developers. It would be nice to just select the HTML and the extension makes new DotVVM Control based on what you have selected. So the feature is finally here, and that is what I have been doing for past month or so. The concept seemed easy enough: I just take the selected HTML paste it into a new file replace selected HTML with newly created control tag. That's it, easy right? Well... wrong! Bindings, of course, can be part of the text you want to extract. In that case, I  needed to make sure extracted bindings still make sense in the newly created control file. If the binding does not contain anything weird this is simple enough. It's just a question of what the ViewModel of the newly created control is. However, a binding can very well look like this:

image

Realizing this I thought something along the lines: "Where is my god now...". Hope of an easy solution suddenly vanished and it became apparent that this feature will have to be more complex. It all boils down to the simple observation: "All bindings containing _root, _parentX, _control and few other things are evil."

After brainstorming with guys from VS Extension team and DotVVM team, mainly Ladislav Šesták, Tomáš Herceg, Stanislav Lukeš and Martin Dybal we came up with this:

  1. For html that contains only "Non evil" bindings, we will extract selected HTML into Markup only control. image
  2. If the selection contains all kinds of "evil" bindings that cannot be extracted easily, we create markup with code control. The "evil" bindings become properties in control code-behind and that means they can be set from the original dotvvm html file from which the control is being extracted.
    image


This is the core of how this Extract Control works now. We have a nice dialog that lets you name the control, choose its prefix, path to save it and name newly created control properties if they are needed. This is the dialog:

image

For your convenience there is a basic validation to make sure that created codebehind actually compiles.

After you hit "Create" Several things happen:

  1. In your original file something like this replaces your originally selected text: image
  2. New control files are created:
    image
  3. And in DotVVM startup class new control is registered: image


There is, however, one small catch I could not get around. For the Extension to notice that new control has been registered, you have to rebuild the project the control was added to. This is because controls can be added programmatically in many ways, and we need to actually run the dotvvm startup class to find out the registered controls. You can also run the application and everything should work just fine.

Let's have a look at the freshly generated file:

image

As you can see all the important parts have been moved. There is the @viewModel directive that was determined from the original file. There is @baseType with generated code-behind class and of course, all bindings have been adjusted so that they work even in the separate file. All the @import directives were also added in case you need them.

This is all I can tell you, for now, I will try to polish the extract control feature, so it is ready for its planned release. Do you like it? Do you have any suggestions? Feel free to tell us at: https://gitter.im/riganti/dotvvm-for-vs

Milan Mikuš