My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members

A Poem on XAML

We programmers, as you know, have malformed brains.

Most of the time we tend to think like engineers,

but if you give a regular engineer a new tool,
the engineer will say
"Thank you for this interesting tool.
I will keep it in mind if a problem arises that seems to require it."
A programmer, on the other hand, given a tool like XAML,

starts to think:
"This is very cool.
I wonder what I can do with this

in the absence of all other tools.
What it would be like to live on Planet XAML?
How would I move around?
What would I eat?
How would I procreate?
And if the only tool I have is XAML,
what do the problems look like?"
Charles Petzold

Origins

Where'd Cowbell come from?

The name of the project comes from the Saturday Night Live skit Behind The Music: Blue Oyster Cult. In the words of Christopher Walken, we encourage WPF developers to Explore The Space. As the leader of this project, I am focused solely on getting More Cowbell onto XAML projects.


Community Involvement

Easy, guys.. I put my pants on just like the rest of you - one leg at a time. Except, once my pants are on, I make gold records.
Christopher Walken, as Bruce Dickinson

That's a great idea, send me a patch

There is no shortage of people with crazy ideas. I need people who can execute. The scope of this project is small, and contributions should be easy to make.

Step 1. Derive from MarkupExtension
Step 2. Override ProvideValue

LURR Principle (Listen, Understand, Respond, Repeat)

Public API design is a difficult task. Here is a recipe that I've found works:

Step 1. Listen. Pay attention to what others tell you.
Step 2. Understand.
Step 3. Respond.
Step 4. Repeat. Continue listening, understanding, and responding.

Full Source and Opt-in Knowledge Sharing

Some projects license source code to programmers with a "some source is better than none" policy. A read-only license only benefits a small group of people. A read-only license does not help the project and does not help its client programmers, because it discourages knowledge sharing. There is a better way. Publishing patches to the project prevents teams from fixing the same problems over and over again.


Problem Analysis

XAML Use Case and Scenarios

XAML is for describing hierarchies of objects, and serves as the lingua franca between .NET designers, .NET developers and .NET code generators. It is used by WPF and WF, but also usable for arbitrary scenarios within .NET when describing a hierarchy of objects.

XAML Parsing is Unique Compared to Plain Old XML

Plain Old XML is parsed top-down using recursive-descent parsing. XAML, on the other hand, is parsed top-down by default and can be parsed bottom-up by nesting MarkupExtension elements. Once a recursive-ascent parsing pass is complete, another recursive-descent pass begins. You can think of it as Packrat Parsing.

The Design of WPF Dependency Properties

Wesner Moise's .NET Undocumented has a cool write-up on [DependencyProperty]

Using a MarkupExtension versus an Attached Property

Using a MarkupExtension can obfuscate a XAML document. However, a MarkupExtension gives you flexibility beyond what an Attached Property can give you. In particular, using recursive-ascent parsing to remove boiler plate required by recursive-descent parsing. The goal is to simplify XAML and make XAML more powerful; if a lot of elements use the same raw materials, then a MarkupExtension can aggregate those raw materials into a single logical block of markup. For instance, a MarkupExtension can even be used to aggregate several Attached Properties.

Also, an Attached Property cannot be applied to a non-Dependency Object. e.g.

// This is clearly NOT a dependency object.
public class SubscriptionExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        ...
    }
}

<!-- LocalStateVariable.GroupName requires that SubscriptionExtension be a dependency object -->
<Subscription SubType="sys:String"
              DataItemName="Test_String"
              SamplingRate="5"
              LocalStateVariable.GroupName="Test_Group"
              LocalStateVariable.SaveAsBinary="False"/>

css considered harmful

Namespace Layout

I would like to follow the namespace conventions Microsoft uses for its XAML parser. In particular, the notion that MarkupExtensions should be in a Markup namespace like System.Windows.Markup:

namespace Cowbell.Iconic // for Icon Programming Language inspired features
namespace Cowbell.Frozen.Markup
namespace Cowbell.Bandaids
namespace Cowbell.Bandaids.Silverlight.VersionX.Markup
namespace Cowbell.Bandaids.WPF.VersionX.Markup

Applying a View to a ViewModel

A view consumes a ViewModel's functionality.

  {Apply vw:AllCustomersView, To=vw:AllCustomersViewModel}

or, more verbosely,

  {Apply Template=vw:AllCustomersView, To=vw:AllCustomersViewModel}

transforms into Josh Smith's code example:

  <!-- 
  This template applies an AllCustomersView to an instance 
  of the AllCustomersViewModel class shown in the main window.
  -->
  <DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
    <vw:AllCustomersView />
  </DataTemplate>

See figure 10 from Josh Smith's article WPF Apps With The Model-View-ViewModel Design Pattern

Generic Programming in XAML

Generic programming is a powerful programming style defined by a set of design constraints. Out-of-the-box, XAML does not lend itself well to generic programming. For instance, by default, each XAML markup element maps to a CLR object element. Thus, by default, an interface cannot be an XAML markup element. The solution is to create a generic ClassFactory MarkupExtension class. See Rob Relyea's tutorial MarkupExtension As An Object Element: ClassFactoryExtension.

Complexity

It is often claimed that complexity is only an attribute of an implementation, and not properly part of component specification. This is wrong, and becomes more so with generic components. Users (and algorithms) make basic assumptions about operator complexity, and make decisions about the data structures or algorithms they will use based on those assumptions.
J.C. Dehnert and Alexander Stepanov, Fundamentals of Generic Programming

Ambidextrous Converters

Converters can and should be bidirectional.

Ideas for Generic Programming Against MarkupExtension-derived Classes

XAML Bugs

You cannot nest a StaticResource or DynamicResource within a custom MarkupExtension when using Attribute Syntax. cowbell:Markup Source={StaticResource myResource} will result in a XamlParseException. The workaround is to nest a StaticResource or DynamicResource using Property Element Syntax.

Finding Memory Leaks in WPF Based Applications by Jossef Goldberg

Got performance issues? Check our Kiran's Definitive Guide to WPF Performance Issues

This section is intended to point out bugs in the XAML parser. For help debugging your XAML code, see Debugging and Interpreting Errors in the WPF Designer.

Daniel Paull has pointed out to me that there is a bug in how whitespace is parsed. You currently can't apply xml namespace attributes to property elements (lame). (I hadn't thought of this concept, either, and it's really cool.)

Abstracting Boiler plate

In Windows Presentation Foundation Unleashed, Adam Nathan demonstrates the WPF Command infrastructure:

<Window x:Class="WPFWinApp.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="WPFWinApp" Height="300" Width="600">
      <StackPanel>
            <StackPanel Orientation="Horizontal">
                  <Button Command="Cut" CommandTarget="{Binding ElementName=tb1}" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
                  <Button Command="Copy" CommandTarget="{Binding ElementName=tb1}" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
                  <Button Command="Paste" CommandTarget="{Binding ElementName=tb1}" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
                  <Button Command="Undo" CommandTarget="{Binding ElementName=tb1}" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
                  <Button Command="Redo" CommandTarget="{Binding ElementName=tb1}" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                  <Label>Enter some text:  </Label>
                  <TextBox x:Name="tb1" Width="200" />
            </StackPanel>
      </StackPanel>
</Window>

It would be nice to have a CommandButton MarkupExtension that simplified the creation of a Button whose sole purpose in life is to invoke the functionality of another control. Something like:

<CommandButton Command="Edit" CommandTarget="nameOfElement" Style="{DynamicResource buttonStyle}"/>

By default, cowbell could use ElementName binding. This could be simplified further if Cowbell maintains two MarkupExtension library namespaces, one for Controls with dynamic styling and another for Controls with static styling. e.g.:

<?Mapping XmlnsNamespace="cowbelldynamic" ClrNamespace="clr-namespace:Cowbell.Dynamic" Assembly="Cowbell" ?>
<cowbelldynamic:CommandButton Command="Edit" CommandTarget="nameOfElement" Style="buttonStyle"/>

Behind the scenes, cowbell generates calls to DynamicResource markup extension and Binding ElementName, Binding RelativeSource, and automatically applies the text "Edit" as the content of the button.

XAML Questions

How can I model suspension of evaluation in XAML, like Icon has?

Generators

Some expressions in Icon can also generate more than one value. Such expressions correspond to the common situation in which there is more than one possible result of a computation. An example is the location of positions at which one string occurs as a substring of another. In general there may be more than one such position, as illustrated by the positions of "or" in "Try for ten or more".
Most programming languages resolve this "ambiguity" by producing the first (left-most) position. On the other hand, a computation may need to be performed on all positions. If only one is produced, it is necessary to "work around" the one-value limitation by forming substrings and searching for the positions in a loop.
The Icon function find(s1,s1) illustrates the usefulness of producing more than one result. It generates the positions at which s1 occurs in s2. It produces the first position and suspends. If another position is needed find(s1,s2) is resumed to produce another position. If there are no more positions, find(s1,s2) fails when it is resumed (as it does initially if there is no position).
Encyclopedia of Microcomputers by Allen Kent, James G. Williams, Rosalind Kent, Carolyn M. Hall

XAML Ideas

Using expression trees in C# 3.0 to create hygienic macros.

Open question: Does XAML out-of-the-box have a "bread crumbs" invocation code smell? e.g. Obj1.Obj2.Obj3 A common way to approach the "bread crumbs" invocation code smell in OO languages is to do proper modeling and make effective use of polymorphism, such that the code that executes is a delegate.

Someone made an observation regarding memory leaks in the comments of Bea Costa's blog entry How should I data bind a Polygon’s Points to a data source? - Part III. He points out the problem with having a value converter defined as a static resource that ultimately stores state for multiple bindings: You don't know when you no longer need that memory. In my humble opinion, value converters should just be pattern matchers and therefore not store any state. Instead, the objects that they pattern match against should store the state. Or, more realistically, a mediator like Binding should store the transient state using a Memento design pattern. Does anyone agree or disagree? The reason I bring this up is that I am trying to think of how I can write a MarkupExtension that is the moral equivalent of C++ Boost smart pointers.

See Tomer Shamam's WPF Control State Persistency for ElementStateExtension, which uses a MarkupExtension as an attached property and as an attribute value. I was wondering if this was possible, and seeing it done has me very excited.

A Fun MarkupExtension for specifying Functions:

{Fun Return={SomeMarkupExtension args}, Call="{Lambda}"}

A Yield MarkupExtension for generator an enumerable collection.

An Enumerator MarkupExtension for returning an enumerable collection.

{Enumerator Value={Fun Return={SomeMarkupExtension args}, Call="{Lambda}"}
{Enumerator Value={Yield {Lambda}}}

Michael Latta critcizes XAML: "XAML timelines can only affect properties, not the actual layout of the XAML file itself. You can not say after this happens add these three TreeViews to this page just there. You can make ones you anticipated in the XAML visible, but not create new ones. For that you need imperative code. In WPF this is C#." To be fair, I don't think Michael is entirely correct. It is not obvious how to specify XAML timelines, but possible. In the comments, William Kempf notes: "Content can be created via triggers... by changing the template."

ExecutablePanel that extends Panel and adds an Execute method that populates its Children at run-time. Client programmer must call this in the Page.Load method. This will allow faster processing of the XAML document by avoiding bottlenecks like waiting for resources.

ExecutablePanel exePanel = Resources["myExePanel"];
exePanel.Execute();

Testable Resources that are coalesce duplicate elements of many tested components (see Set MarkupExtension)

Exploring using XML Entity Declarations as a forward-reference macro system. See ENTITY Declaration

Using XAML to bootstrap testing. William C. Wake's Arrange-Act-Assert test pattern can be specified using a recursive-descent/recursive-ascent/repeat strategy rather than a procedural strategy. Shawn Wildermuth discusses how the core WPF team at Microsoft thinks about XAML Control Design, and he mentions that they use a Create-Set-Use Pattern to designing XAML controls. See also: Learning and Craftsmanship which discusses Act/Arrange-Assert's cousin the Four-Phase test. See also: Fitnesse's Build-Operate-Check pattern

Getting NUnit to run in STA

See if it is possible to model Inheritance of Failure (as seen in the Icon Programming Language) in XAML using recursive-ascent parsing.

What is Icon?

Icon has a novel expression-evaluation mechanism that integrates goal-directed evaluation and backtracking with conventional control structures. It has a string scanning facility for pattern matching that avoids the tedious details usually associated with analyzing strings. Icon's built-in data structures include sets and tables with associative lookup, lists that can be used as vectors or stacks and queues, and records.

A Set MarkupExtension that takes a Collection of Children and returns a Collection consisting of elements in the Set (removing duplicates).

A MacroXAML MarkupExtension for treating XML as a hierarchical function parameter.

Explore a MarkupExtension that abstracts the boilerplate from XAML's Markup Compatiblity (mc:) Language Features.

XAML uses TypeConverter objects to convert

Strings To Things.

(Brush)TypeDescriptor
.GetConverter(typeof(Brush))
.ConvertFromInvariantString("Yellow")

A large library that uses multiple namespaces can take advantage of mapping a namespace URI to multiple namespaces. Most books on WPF don't cover this, but you can do the following:

[assembly: XmlnsDefinition("http://code.google.com/p/cowbell/schemas/", "com.google.code.cowbell")]
[assembly: XmlnsDefinition("http://code.google.com/p/cowbell/schemas/", "com.google.code.cowbell.integration")]

A MarkupExtension that has a public Property of type MarkupExtension, for the sole purpose of having a generic way to nest MarkupExtensions. Nesting markup elements typically means nesting objects. However, MarkupExtension elements can arbitrarily nest, too, and each stage can provide a different kind of object to operate on.

namespace Cowbell
{
    public class MarkupMarkExtension : MarkupExtension
    {
        public MarkupMarkupExtension(MarkupExtension LambdaForm)
        {
            this.LambdaForm = LambdaForm;
        }

        [ConstructorArgument("LambdaForm")]
        public MarkupExtension LambdaForm
        {
            get; set;
        }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget ipvt = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));

        MarkupExtension fe = ipvt.TargetObject as MarkupExtension;
        if (fe != null)
        {
            return me.ProvideValue();
        }
        else
        {
            throw new Exception("Name " + _Name + " is not resolvable because the parent object isn't findable");
        }
    }
}

A MarkupExtension that has a public Property of type List

<markupextension>
, for the sole purpose of defining a sequence of MarkupExtension transformations. It might be best to design this as MarkupExecute and MarkupEscape, both extending MarkupExtension.

almost same as above, except uses a List

A Pragma MarkupExtension. In C#, pragma can be used to apply a change from one point in a file going forward. This change can be reverted by issuing another pragma. In XAML, a Pragma could be lexically scoped by the section of the DOM tree it is contained within. Therefore, it automatically rolls itself back.

A MarkupExtension called Pairs that constructs a Dictionary. The Pairs MarkupExtension may also use a TypeConverter to define a "mini language". A "mini language" is used by the Path element: <Path Stroke="Black" Thickness="5" Data="M 30,60 Q 50,90 70,60" /> A more complicated TypeConverter can use Property.Element Syntax for scenarios where types are too complex for a "mini language"; properties are themselves objects and can therefore be arbitrarily complex. Also, as Rob Relyea points out in Strings to Things a "mini language" is not extensible, because extending the language would introduce versioning problems.

A MultiBinding MarkupExtension and a new IMultiValueConverter interface to replace the horrible design of MultiBinding and IMultiValueConverter in .NET Framework 3.0. See WPF Binding Expression Alternatives for what people have done to improve the basic Binding MarkupExtension. The Blendables library also provides two additional Binding mechanisms:

EvalBinding and SimpleBinding with examples. The last thing I want to do is proliferate XAML with a bunch of different Binding MarkupExtensions, like Java's GeoTools Binding implementation.

A String MarkupExtension that delegates to the CLR string object. The point of this MarkupExtension is to allow type-safe representation of XML as strings, e.g.:

<cowbell:String>
  <TextBlock Text="Hello World"/>
</cowbell:String>

would create a CLR String that stores <TextBlock Text="Hello World"/>

A Meta and/or Load MarkupExtension that is a delegate for XamlReader.Load(), allowing efficient compilation down to baml. These intermediate transformations are never seen inside the resulting baml, and thus would allow multi-stage programming.

A Merge MarkupExtension that can do thinks like merge resource dictionaries, rather than the heavy handed WPF approach of MergedDictionaries.

A CodeProject article about creating aggregate views of data by implementing IValueConverter as an aggregate "function object". In the example, an Excel-like Max function is called. This implementation is not good in the reusable sense, because it does not take advantage of monad comprehensions. (My current position on this is that we should also seek to better understand the differences between subtype polymorphisms (single dispatch, double dispatch, multiple dispatch) and set-based feature dispatch.) See also, http://nice.sourceforge.net/visitor.html Visitor Pattern versus Multimethods and Robert Cecil Martin'S I Use Visitor All the Time, and these course notes point out a common use case for the visitor pattern: "The assumption is that you have received a fixed unrelated class hierarchy (from a vendor), which cannot be changed, and you need to add some new functionality to the hierarchy, which means that normally the base class interface needs to be changed.". Visitor Revisited discusses the descriptive flaw in design patterns. and visitor pattern discussion by stan james, and Subject-oriented programming and the visitor pattern; all links via http://www.compwisdom.com/topics/Visitor-pattern

See also Catamorphisms, part three

As Holub notes, two principles of object-oriented systems are: # Never ask an object for the information you need to do something; rather, ask the object that has the information to do the work for you. # It must be possible to make any change to the way an object is implemented, no matter how significant that change may be, by modifying the single class that defines that object.

Ward's Wiki has an article on AlternateHardAndSoftLayers that provides an answer to the question Why Compile Data? One of the contributors discusses the architecture of Quake 3: Arena: "The game logic itself (physics, weapons, scoring, etc) runs atop the engine in a flexible virtual machine. Game code communicates with the engine through system calls or "traps" (there is also a small shared memory segment for high-bandwidth communication). [...] In Quake 3 the game code is written in a dialect of C, and then compiled down to bytecode (which the engine may JIT compile for extra speed). [...] The advantage of this split between engine and game code is that you can swap out the game logic without recompiling the engine."

A DynamicDraw MarkupExtension that dynamically draws objects. Idea based on the following Avalon newsgroup posting:

Sujet: Dynamically Drawing Objects De: kmattern@araneasolutions.com (kmttern) Groupes: microsoft.public.windows.developer.winfx.avalon Date: 25. Mar 2008, 09:51:16

This should be so simple! I need to generate a bar graph using WPF. It's easy to do with XAML and I have some very nice graphs. But I need to dynamically genenerate the graphs because I do not know before I query the database how many bars I will need. It should be so simple to draw as many rectangles I need and to place them on my canvas. But I can't find anything on how to do it. What few WPF examples I can find on anyting are written in C#. Surely there are Visual Basic users out there as well.
OS XP Pro Language VB 2008
Any ideas will be greatly appreciated
Ken

Dr. WPF's ConceptualPanel/LogicalPanel idea Mike Hillberg's Leveraging Freezables to Provide an Inheritance Context for Bindings - in the comments, Rob Eisenberg points out that Mike's approach is similar to Caliburn's ActionMessage and EventMessage systems.


Design Constraints

The Inner Dependency Problem Looking at WPF and JavaFX, thinking on SWT: Andrey Platov discusses Apache, academics and freelancers all trying to use Desktop UI APIs to bring the browser to the desktop. Natural way to develop UI: Andrey Platov discusses in a roundabout way why the notion of global styles is wrong, because he points out that the WPF composition-based styling system allows you to define appearance at any level you choose, including the window-level or application-level.

  • Straddling Tables Matthew Holloway quote: "At a bare minimum Tables consist of a flat list of rows containing cells. They don’t necessarily contain headers or footers, or cell spans, or hierarchical rows. As it turns out however when you add a few more features then Tables become a generalised model for both DataGrids and TreeViews so –for the purposes of comparing tables– we’ll call all three of these Tables."

Fair Criticism of WPF

Occasionally, I come across an article pointing out a flaw in WPF. I will record those articles here:

When a markup extension is used to provide an attribute value, the attribute value should instead be provided by the logic within the backing class for the relevant markup extension.
TextBoxBase exposes a lot of concepts based around this, like a SelectionChanged event, AutoWordSelection and Cut/Copy/Paste based on the selection. However, there's no way to determine what the selection is! TextBox and RichTextBox aren't consistent in how they expose the selection.
TextBox exposes SelectionStart and SelectionEnd while RichTextBox exposes a Selection. That's wacky enough to be highly questionable to me. Just bad design. But what's worse is that all of these methods are implemented in terms of a TextSelectionInternal on the base TextBoxBase, which, like the name indicates, is internal! How did this design pass code review?
  • Thinking in WPF: Scenario: You have a read-only CLR property not backed by a DependencyProperty, and therefore cannot be set from markup. This includes setting its value to a Binding MarkupExtension in order to forward the read-only property to another control. For instance, when you are using a ViewModel, you want the selected item to be stored in the ViewModel based on feedback from the user.
  •   <TreeView SelectedValue="{Binding Path=Selected, Mode=OneWayToSource}" />
      <ItemsControl ItemsSource="{Binding FlattenedTree.Items}"/>
      private object selected;
      public object Selected
      {
          set
          {
              this.selected = value;
              Changed("FlattenedTree");
          }
      }
    
      public FlattenedTree FlattenedTree
      {
          get 
          { 
              if (selected == null)
                  return null;
              return new FlattenedTree(selected); 
          }
      }
Instead of pushing the selected item back into the model to convert it and send it out again - lets just convert it!

Solving XAML's out-of-the-box violation of the Open-Closed Principle. M. Orçun Topdağı's work on GeoStructor is an inspiration:

  <Style x:Key='GObjectGeneratorButtonStyle'
         TargetType='{x:Type ContentPresenter}'>
    <Setter Property='ContentTemplate'>
      <Setter.Value>
        <DataTemplate>
          <Button x:Name='xButton'
                  Margin='1'
                  Content='{Binding Attrib.UIName}'
                  IsEnabled='{Binding IsApplicableToSelection}'
                  Command='{x:Static g:GEngine.Generate}'
                  CommandParameter='{Binding}'
                  ToolTip='{fix:Binding i={Binding IsApplicableToSelection}, 
                                        b={Binding}, 
                                        ToTarget="i ? b.Attrib.Description : b.Requirements"}'
                  ToolTipService.ShowOnDisabled='True' />
        </DataTemplate>
      </Setter.Value>
    </Setter>
  </Style>

Future of Silverlight?

An Interview with Scott Guthrie where he reveals that a future iteration of Silverlight will allow you to view Silverlight applications in the browser or on the desktop on multiple platforms.

Deployment

You don't want to tightly couple your application to the Windows Registry. Jon Galloway points out in his blog that We should be virtualizing applications not machines. I don't totally agree with this. IBM got virtualization right (s/360), Intel/Microsoft got virtualization wrong (MS-DOS); we're stuck with the aftermath. However, he has a key point that shouldn't be overlooked:

  • "The best way for developers to better the situation is to write software which is well compartmentalized, so we don't need to put it in an artificial container. This is commonly done by making good use of an application virtual machine (like the common language runtime, the Java language runtime, etc.). These technologies tend to steer you towards writing well isolated software, but for the sake of legacy integration they don't prevent you from going back to old, bad habits like writing to the Windows registry, modifying or installing shared resources, installing COM objects, or storing files and settings in the wrong place. Software written to run on a software virtual machine isn't guaranteed to be isolated, but it's generally more likely to play nice." ~ Jon Galloway


My Thoughts

Currently, I am developing a Silverlight 2 application. Through no choice of my own, I am using XAML. Being forced to use a language has a strange way of forcing you to become an insider and assess the language fairly. Initially, I did not like XAML at all. After using it for three months, it has become familiar and -- surprise -- is now my preferred template language. Funny how adoption works.

The question I've been asking myself is, "Was it just a matter of becoming familiar with the language that changed my opinion about it?" I don't think so. I still see major problems with the way Microsoft expects developers to write XAML. My two biggest complaints are that XAML out-of-the-box violates the Open-Closed Principle and promotes Pollution of the Knowledge Space.

For instance, if I want to adjust the style of a column header for a DataGrid control, then I have to copy-and-paste a multiple line ControlTemplate off MSDN and edit one line within that ControlTemplate. All I want to do is adjust a Layout Property like VerticalContentAlignment, yet the out-of-the-box way of writing XAML forces me to pollute the Style setter with information unrelated to Layout Properties. In doing so, I have polluted the knowledge space by providing excess details to accomplish the primary objective of the Style setter. These extraneous details are orthogonal concerns that I should not have to worry about at that particular point in time.

From what I have seen on the Internet, most criticism of XAML is an ad hominem attack against Microsoft. For instance, they argue that we already have XForms, CSS, XHTML, XUL, SVG and sXBL. From their perspective, it looks like Microsoft is re-inventing the wheel and that XAML is just another weapon for an Embrace, Extend, Extinguish coup d’état. Such a point of view is sad, but a reflection of the fact that Microsoft has continuously changed the standard way of doing things. For synchronization, it used to be Hailstorm and now it is LiveMesh. For database technologies, it has evolved from ODBC to OLE DB to RDO to ADO to ADO.NET. For any given technology Microsoft has touched, there has been disruptive evolution.

Yet, in XAML, Microsoft appears to have created something permanent. It is a single, unified language that closely obeys Elliotte Rusty Harold's stringent Effective XML guidelines. The biggest negative is that it is tightly coupled to the CLR; the Application Pack URI format is just one example of its tight integration with Microsoft virtual machine technology.


NUnit Stuff

Comparison to org.springframework.util.Assert

Build-Operate-Check and Arrange-Acts-Assert

Data Driven Test

JUnit

JUnit: A Cook's Tour - based on JUnit 3.8.x

RowTest

Andreas Schlapsi wrote an NUnitExtension called RowTest, which allows NUnit users to write a single unit test to test the same functionality using different values.

NUnit 2.4.7 added official support for RowTest Extension as an add-in. The extension resides in the NUnit.Framework.Extensions namespace. The idea for the feature -- a single test method to execute multiple tests with different parameter inputs -- was taken from MbUnit. MbUnit offers RowTest with support for Negative Assertions.

[TestFixture]
public class DivisionFixture
{
    [RowTest]
    [Row(1000,10,100.0000)] 
    [Row(1,0,0, ExpectedException = typeof(ArithmeticException))]
    [Row(-1000,10,-100.0000)]
    [Row(1000,7,142.85715)]
    [Row(1000,0.00001,100000000)]
    [Row(4195835,3145729,1.3338196)]
    public void DivTest(double num, double den, double res)
    {
        Assert.AreEqual(res, num / den, 0.00001 );
    }
}

MbUnit is a generative unit testing framework. Traditional unit testing frameworks required a single method for each set of test data, resulting in code duplication. This code duplication creates monolithic test fixtures, because the test fixture has N tests where N tests have the same state-process, but expect different outcomes based on different input parameters. MbUnit lifts these input parameters and outcomes into a RowAttribute decorator.

Andreas also wrote a tutorial on how to write an NUnit add-in. He also wrote a very persuasive essay, Decorate Your Tests. I would like to see cowbell add support for decorators somehow, possibly mimicking the NUnit way of doing things: an IMarkupExtensionDecorator interface that requires implementing the following signature: public MarkupExtension Decorate(MarkupExtension markupExtension, MemberInfo memberInfo);. Below is how NUnit does it:

IExtensionPoint testDecorators = host.GetExtensionPoint( "TestDecorators" );
...
// There is currently no mechanism to control the order in which the decorators are applied.
// NUnit applies decorators in the order in which they are returned through reflection.
// Therefore pay attention to this issue if you use more than one decorator.
public interface ITestDecorator
{
	Test Decorate( Test test, MemberInfo member );
}

The Gallio test automation platform and the MbUnit unit testing framework

Jamie Cansdale: "When using MbUnit, it is common for a single test method to execute multiple tests with different parameter inputs. The most famous of these test types is the MbUnit RowTest."

MbUnit also supports PairWise, Repeat and Rollback2. Andrew Stopford notes: PairWise and RowTest will drill across a range of values between x and y. It's really intended to throw a wide net over your tests, you could then combine with code coverage to check you don't have plains of untested code showing up and that your checking for the unexpected in your code. I'd double up with a more directed test to check expected against actual as well as a wide net test so you get the best of both worlds. Rollback allows automatic rollback of database changes by wrapping the changes in a COM+ transaction.

Another MbUnit feature is the Provider attribute.

Fair Criticism of NUnit

  • MbUnit vs. NUnit - Unit testing requires testing a number of permutations, and NUnit's RowTestExtension requires you to write a test method for each assertion. This requirement is a testing anti-pattern, and we should probably Avoid Multiple Asserts. Therefore, a RowTest must support Negative Assertions.
  • MbUnit: A Generative Unit Test Framework by Jonathan 'Peli' de Halleux - contrasts MbUnit with traditional xUnit
  • Curtail Complexity with a Rules Engine: "Using a hip rules engine doesn’t necessarily reduce complexity– it just isolates portions of it into a format that can be manipulated by non programmers. In essence, a rules engine creates flexibility, while also providing for more testability."
  • Phil Haack comments that there is a Rollback attribute for NUnit, but felt the extensibility model is tricky. because he could not get Rollback to work with ExpectedException. He also explains NUNit was working on fixing this problem.

John Gossman on VisualState and Triggers

WPF Team Members on Attached Behaviors

Powered by Google Project Hosting