VSFF*: XUnit and related

VSFF* – Visual Studio Full Fat. Just to make an obvious distinction with VSCode.

Advertisements

Snippets: C# console app

If I want to play with some ideas in C# that don’t involve a GUI but where you want some console output, then that’s obviously a use-case for the Console Application template in Visual Studio… but it’s not quite as I like. THIS is as I like:

ConsoleApp01

Pastebin

That then gives me a clear place in the RunTheTest method to new up stuff, and a ready-made prompt so the console doesn’t just run away after execution.

While I’m on it, this will save me a few keystrokes * 1000, as it’s easier to remove stuff doing this crude form of debugging than it is to add it. I always like to surround arguments in those square brackets for easy visual delimitation, better too many than too few:

ConsoleSnip01

Of course I should anyway go back to my Resharper Template notes here, and the related YouTube video here.

Resharper Live Templates

(My YouTube video on ReSharper templates is here.)

I sometimes use expandable snippets in Visual Studio, eg prop, cw, but as I have the luxury of ReSharper, I really ought to look at what that can do for me. Here seems a reasonable starting point:

Resharper01

So it’s not perfect, why would it be, and I was possibly a little ambitious in that I tried to template a whole file first. This is my scenario: In EF / RIA, I want to template the viewmodel class(es) that use the generated proxy classes, so that any additional work really is specific to the individual need at the time. That is of course just a definition of what a template is all about anyway.

Putting aside the whole file thing, and cutting back to something more modest, my first pass is this:

template01

Significant things (this works for me):

  • Its shortcut name is myla
  • Uncheck the default format box – I want to keep things how I’ve formatted them
  • The word ENTITY gets replaced at paste-time with your chosen parameter
  • The word LC_ENTITY is for a private version, and that’s where the built-in macro comes in (“the first character” etc). It is not editable.

This is the point in the code waiting for something to pop in:

template02

As you see, LoadAllOrders is not defined, and _order is not used. Positioning the cursor after the last method, as I start to type my, it finds myla:

template03

, finds the description, which is comforting that it has definitely found my template:

template04

Pressing tab gives this:

template05

Replace [ENTITY]  with [Order] (this has come from NorthWind) gives this:

template06

Press escape, and the editable references disappear. Note that it has done what it said re replacing the leading lower case. In fact, I thought I had done a typo, but it has just used a convention evidently to help it get there.

That principle can now be used for the Observable Collection property, for example, with the highlights being the candidates for replacement:

template07

This is how to get to the template editor, by the way:

template08

template09

Once you press the icon, the template editor appears but half-hides behind the templates explorer. So close the Templates Explorer (‘X’). Now you get a nice clean surface:

template10

The edit starts with the shortcut and description, and by pasting in the code we want to doctor:

template11Generally, we are replacing all instances of [order] with [entity]. This is the first part done:

template19

Next step is Choose macro for the ENTITY variable, that is, the one we are replacing at paste-time. Click OK once you’ve done the highlighted parts:

template20

Then define the LC_ENTITY variable, which derives from the ENTITY variable. Click OK once that is done :

template21

You now have this:

template22

A quirk I’ve noticed is that it seems there is no obvious button to save the template. So just CTRL-S, I suggest, and when you reopen the Templates Explorer, your template should be there:

template23

Let us now see if it actually works. Deleting the existing property-pair brings up errors:

template17

Start to type oc… and it finds your template. Accept that, and you get this:

template24

Then follow usual snippet replacement actions. Now in my case, I’ve made a mistake, as you can from this:

template25

I need to go back and look at how I defined LC_ENTITY, and my red Order should have been pluralised. In fact I see that LC_ENTITY did not get replaced because it was still set at editable, so make sure you set it to Not Editable. Secondly, if you look at the screenshots above, although I set LC_ENTITY to the macro to be based on another variable, I didn’t say what that variable is (ie ENTITY). So correct that.

Once corrected in the template, this is the generated version:

template26

And this is the final template:


private ObservableCollection _$LC_ENTITY$s;
public ObservableCollection $ENTITY$s {
get { return _$LC_ENTITY$s ?? (_$LC_ENTITY$s = new ObservableCollection(_ctx.$ENTITY$s)); }
private set {
if (_$LC_ENTITY$s == value) return;
_$LC_ENTITY$s = value;
RaisePropertyChanged(() => $ENTITY$s);
}
}

And the previous template…

private void LoadAll$ENTITY$s() {
_ctx.$ENTITY$s.Clear();
_$LC_ENTITY$ = _ctx.Get$ENTITY$sQuery();
_ctx.Load(_$LC_ENTITY$, LoadAll$ENTITY$sCompleted, null);
}

private void LoadAll$ENTITY$sCompleted(LoadOperation op) {
Add$ENTITY$SetToCollection();
}

private void Add$ENTITY$SetToCollection() {
foreach (var $LC_ENTITY$ in _ctx.$ENTITY$s) {
$ENTITY$s.Add($LC_ENTITY$);
}
}

And to remind myself to come up with some technique for columns…


public OrderDetailViewModel() {
if (DesignerProperties.IsInDesignTool) {
var list = new List
{
new Order {ShipAddress = "Tottenham", ShipCity = "Lisbon", ShippedDate = new DateTime(2012, 3, 3, 12, 12, 12)},
new Order {ShipAddress = "Liverpool", ShipCity = "Moscow"}
};
Orders = new ObservableCollection(list);
} else {
_ctx = new NWDomainContext();
LoadAllOrders();
}
}

And as I’m making it REALLY untidy, another point to self…

template27Finall

Finally, and again, quite tangentially, a cheatsheet for xaml:

A few days later… In an attempt to to continue to eat my own dog, here is just the text of a the Property, the delegate, the CanSubmit method, and the Submit, as it was then.


using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;

private ICommand _submitCommand;
public ICommand SubmitCommand {
get { return _submitCommand; }
set { if (_submitCommand == value) return;
_submitCommand = value;
RaisePropertyChanged(() => SubmitCommand);
}
}

// constructor begin – this version assumes a string parameter
SubmitCommand = new DelegateCommand(Submit, CanSubmit);
// constructor end

public bool CanSubmit(string cmdParameter) {
if (cmdParameter == null) return true;
return true; //add a condition here… or unconditional true
}

private static void Submit(string cmdParameter) {
// Action to be executed on Submit – this only gets called
// if CanSubmit returned true
}

// Example binding for the xaml
// <Button Content=”Button” HorizontalAlignment=”Left” Height=”36″ Margin=”120,201,0,0″ VerticalAlignment=”Top” Width=”111″ Command=”{Binding SubmitCommand}” CommandParameter=”{Binding Text, ElementName=MyBox}” />

What we have below is the standard public property with a private backing field. Yes, JetBrains have given us a perfectly good one of those as a template, but doesn’t this give you a feeling of more control?

Templates001

TemplatesB02

TemplatesB03

The reason for the commented-out parts is so that if this is the first time for a property, then the Using is already there. The XAML snippet is there so I can bind without thinking at all about how to write it – it might not be the final thing, but it’s probably a good 80/20.

private $VarType$ _$LC_propname$;
public $VarType$ $UC_propname$ {
get { return _$LC_propname$; }
set { if (_$LC_propname$ == value) return;
_$LC_propname$ = value;
RaisePropertyChanged(() => $UC_propname$);
}
}

plus…


// using Microsoft.Practices.Prism.Commands;
// using Microsoft.Practices.Prism.ViewModel;

private ICommand _$type$Command;
public ICommand $UC_type$Command {
get { return _$type$Command; }
set { if (_$type$Command == value) return;
_$type$Command = value;
RaisePropertyChanged(() => $UC_type$Command);
}
}

// constructor begin – this version assumes a string parameter
$UC_type$Command = new DelegateCommand($UC_type$, Can$UC_type$);
// constructor end

private bool Can$UC_type$($generic_type$ cmdParameter) {
// Add logic here. If true is returned, then $UC_type$ is called.
// Remove the unconditional return, as required.
return true;
}

private static void $UC_type$($generic_type$ cmdParameter) {
// Action to be executed on $UC_type$ – this only gets called
// if Can$UC_type$ returned true
}

private $VarType$ _$LC_propname$;
public $VarType$ $UC_propname$ {
get { return _$LC_propname$; }
set { if (_$LC_propname$ == value) return;
_$LC_propname$ = value;
RaisePropertyChanged(() => $UC_propname$);
}
}
TemplatesB06

TemplatesB07