Roslyn Update

There have been some changes to Roslyn since my last post and some of my old examples don’t compile.

CustomWorkspace has been replaced by AdHocWorkspace

Creating a class from scratch is now:

AdhocWorkspace cw = new AdhocWorkspace();
OptionSet options = cw.Options;
options = options.WithChangedOption( CSharpFormattingOptions.NewLinesForBracesInMethods, false );
options = options.WithChangedOption( CSharpFormattingOptions.NewLinesForBracesInTypes, false );
SyntaxNode formattedNode = Formatter.Format( cu, cw, options );
StringBuilder sb = new StringBuilder();
using ( StringWriter writer = new StringWriter( sb ) ) {
    formattedNode.WriteTo( writer );
}

Note that some of the CSharpFormattingOptions syntax changed, too.
In our simple getter and setter, the BinaryExpression used for assigment is now an AssignmentExpression.

PropertyDeclarationSyntax property =
    SF.PropertyDeclaration( SF.ParseTypeName( "String" ), SF.Identifier( "A" ) )
        .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
        .AddAccessorListAccessors( 
            SF.AccessorDeclaration(
                SyntaxKind.GetAccessorDeclaration,
                SF.Block(
                    SF.List( new [] {
                        SF.ReturnStatement( SF.IdentifierName( "_a" ) )
                    } )
                )
            ),
            SF.AccessorDeclaration(
                SyntaxKind.SetAccessorDeclaration,
                SF.Block( 
                    SF.List( new [] {
                        SF.ExpressionStatement( 
                            SF.AssignmentExpression( 
                                SyntaxKind.SimpleAssignmentExpression,
                                SF.IdentifierName( "_a" ),
                                SF.IdentifierName( "value" )
                            )
                        )
                    } )
                )
            )
        )
    ;

Everything else from my old example project seems to compile.

F#, WPF, and Prism

I recently attempted to use F# to create a WPF project using the Prism MVVM library.  The project, if you want to download it or look at the code, is at https://github.com/mkb137/FSharpAndPrism.

Creating a WPF Application in F#

This isn’t too hard.  There’s no option to create an F# WPF application by default, but if you create an F# Console Application and then, in the project settings, flip it over to “Windows Application” it will run like one.

To get the WPF libraries, you have to add these references:
* PresentationCore
* PresentationFramework
* UIAutomationClient
* UIAutomationTypes
* WindowsBase
* System.Xaml

I used the FsXaml project to create usable F# types from WPF XAML files.
You can add vanilla XAML files, like App.xaml, with no backing class and then convert them to F# types via:

type App = XAML<"App.xaml", true>

Two things to be aware of:
1. All XAML files must be compiled as “Resource” (the default is None)
2. Visual Studio LIES.  As you may know, in F# the order of the files in solutions matter.  In F# projects, Visual Studio gives you “move up” and “move down” functions to put the files in order.  But once you start adding XAML files, all bets are off.  If you find the solution mysteriously failing to find libraries that it should, open your .fsproj file in a text editor and have a look at the included file order.  You may need to order it manually.

Adding Prism

I used the UnityBootstrapper, which in F# looks like this:

type Bootstrapper() =
    inherit UnityBootstrapper()
    override this.CreateShell() = 
        WindowUtils.loadComponent "/FSharpAndPrism;component/Shell.xaml"
    override this.InitializeShell() =
        base.InitializeShell()
        Application.Current.MainWindow <- ( this.Shell :?> Window )
        Application.Current.MainWindow.Show()
    override this.ConfigureContainer() =
        base.ConfigureContainer()
        this.Container.LoadConfiguration() |> ignore
        this.Container.RegisterInstance( this.Container ) |> ignore
    override this.ConfigureModuleCatalog() =
        base.ConfigureModuleCatalog()
        let moduleCatalog = this.ModuleCatalog :?> ModuleCatalog
        moduleCatalog.AddModule typedefof<AlphaModule> |> ignore

That WindowUtils.loadComponent is just a utility function to load the XAML resource:

module WindowUtils =
    let loadComponent( path ) =
    let resourceLocator = new Uri( path, UriKind.Relative )
    Application.LoadComponent( resourceLocator ) :?> DependencyObject

So I create a Shell with a MainRegion region…

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://www.codeplex.com/prism"
    xmlns:infrastructure="clr-namespace:FSharpAndPrism.Infrastructure;assembly=FSharpAndPrism.Infrastructure"
    Title="F# Prism Demo" Height="150" Width="500"
    WindowStartupLocation="CenterScreen"
    >
    <StackPanel Orientation="Vertical">
        <Label Content="View Goes Here:"/>
        <ContentControl prism:RegionManager.RegionName="{x:Static infrastructure:RegionNames.MainRegion}"/>
    </StackPanel>
</Window>

And I create a view…

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Background="White"
    >
    <StackPanel Orientation="Horizontal">
        <Label>This is my view - Data context = </Label>
        <Label Content="{Binding}"/>
    </StackPanel>
</UserControl>

Register it as an F# type…

type MyView = XAML<"MyView.xaml",true>

And define a module that registers it with the region:

type AlphaModule( regionManager : IRegionManager, container : IUnityContainer ) =
    interface IModule with
        member this.Initialize() =
            regionManager.RegisterViewWithRegion( RegionNames.MainRegion, typedefof<MyView> ) |> ignore

And the result is… It doesn’t work.  The application runs but my view is not being loaded into the region.  Why?  Actually, with a little digging I find that the view is being loaded, it’s just not rendering.

FSharpAndPrism-Failure

FsXaml, Prism, and Unity

Problem #1 – Extra Constructor

As it turns out, when FsXaml creates a type derived from UserControl, in addition to UserControl’s void UserControl() constructor, FsXaml is adding a hidden void UserControl(FrameworkElement) constructor.  If the default configuration is not overridden, Unity will use this constructor when resolving the component and the type created with this constructor will not render itself correctly.  A simple but tedious way around this problem is to, for each view, register it with Unity so that the constructor taking no parameters is used.

container.RegisterType<MyView>( new InjectionConstructor() ) |> ignore

FSharpAndPrism-NoContext

Problem #2 – Adding a data context

Prism Views aren’t that useful with out their ViewModel data contexts and those are usually passed in the constructor.  So the first thing we want to do is subclass our the type that FsXaml created and add our own constructor.  This, by the way, solves our Unity problem as well since our subclassed type won’t have the bogus constructor that FsXaml is creating.
Here’s a basic view model type:

type MyViewModel() =
    let mutable name: string = null
    member this.Name
        with public get() = name
        and public set value = name <- value

Here’s our subclassed view (where the original has been renamed with a tick):

type MyView' = XAML<"MyView.xaml",true>

type MyView() =
    inherit MyView'()
    new( viewModel : MyViewModel ) as this =
        MyView()
        then
            this.DataContext <- viewModel

and… we have a problem.  By default, FsXaml derived types are sealed.  There’s no real reason for this other than that FsXaml is using a type provider from the fsprojects/FSharp.TypeProviders.StarterPack and it creates types as sealed for, I suppose, educational purposes.  If the “Sealed” attribute is removed from the created type it works fine.  I submitted a pull request to FsXaml who asked me to submit it upstream to FSharp.TypeProviders.StarterPack.  I submitted it a moment ago and haven’t heard back yet.  Until then, a “fixed” FsXaml implementation is at mkb137/FsXaml

Using the modified FsXaml library, it works and we have our view loaded with its data context:

FSharpAndPrism-WithDataContext

Final Problem: FSC: error FS2024: Static linking may not use assembly that targets different profile.

A normal WPF project is compiled against the .NET 4.5 profile which is known internally as Profile7 (see a list of PCL profiles here.  If you attempt to directly use any third-party library that is compiled not just for .NET 4.5, but for .NET 4.5 and Windows Phone (e.g. Profile78), you’ll get the error that you would never see in the same C# project:

FSC: error FS2024: Static linking may not use assembly that targets different profile.

And there’s no way around it as far as I know.  The bug has been logged here on F#’s current home on GitHub, and not yet fixed.

Functional programming with F#

In an episode of the .NET Rocks podcast, guest Bryan Hunter describes his experience analyzing a large object-oriented code base. It’s a good listen. The problems with it were the same problems you see with all large O-O code bases, he says. But one module was a complete surprise because…there were no problems. The application had zero downtime in 4 years of operation. The team was even able to do “hot loading” to deploy updates while the application was running. What was the difference? This module was written in Erlang, a functional language.

The life of a software engineer - cartoon
Life of a software engineer. I believe the original source is http://www.bonkersworld.net/building-software/

Whenever you build an enterprise-scale project, you will find yourself using a bare minimum of libraries and patterns such that despite your best intentions – or even because of your best intentions – your solution will be complex and tricky to maintain from moment one. It’s a terrible life we lead where following best practices feels bad and wrong. Functional programming may be the answer.

I’ve begun to learn .NET’s own functional programming language, F#. I wouldn’t call the language mainstream, but it’s not a toy, either. It’s completely compatible with the rest of the .NET class library so one can make WPF or ASP.NET MVC applications with it. I hope that it will one day lead to a more satisfying experience developing enterprise applications.

Some F# learning resources:

Outlook Add-In for Replicon

My employer uses Replicon to track hours against projects and tasks. Its web-based user interface is…adequate. Entering time in an online calendar is fine but I already have an electronic calendar open all day: Microsoft Outlook.

I started a project to create an add-in that adds an “Add to Replicon” menu item to the Outlook calendar. The Replicon Repliconnect API is used to get project and task information and to send the timesheet information back to the server.

It’s still a work in progress. The initial code is up here.

Fault-safe WCF Proxy Generator for Service Reference clients

WCF is great, but if a connection ever throws an exception for any reason it puts the client in the Faulted state and the client has to be aborted and recreated. It’s a pain in the ass since this can happen anywhere a client method is called.
In a previous post, I showed the dynamic generation of a proxy for a WCF channel.

Nowadays, I suspect most people create their clients using “Add Service Reference”. This generates a ClientBase client that suffers from the same problem as raw channels – if there’s ever an exception, you need to recreate the instance.

Following the earlier post, I created code to use the CIL Emit libraries to dynamically generate a fault-tolerant proxy around a given client. If an exception is thrown, the client is recreated with the correct authentication and whatever settings were used to construct it in the first place.
The code is up on github.

Code Generation with Roslyn – If, Else, and Loops

if statements

This:

MethodDeclarationSyntax method = SF.MethodDeclaration(
    SF.PredefinedType( SF.Token( SyntaxKind.VoidKeyword ) ),
    "MyMethod"
    )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
    .AddBodyStatements( 
        SF.IfStatement(
            SF.BinaryExpression( 
                SyntaxKind.EqualsExpression,
                SF.IdentifierName( "_a" ),
                SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( "X" ) )
            ),
            SF.Block(  
            )
        )
    )
    ;

Will get you this:

public void MyMethod() {
    if (_a == "X") {
    }
}

if-else statements

This:

MethodDeclarationSyntax method = SF.MethodDeclaration(
    SF.PredefinedType( SF.Token( SyntaxKind.VoidKeyword ) ),
    "MyMethod"
    )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
    .AddBodyStatements( 
        SF.IfStatement(
            SF.BinaryExpression( 
                SyntaxKind.EqualsExpression,
                SF.IdentifierName( "_a" ),
                SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( "X" ) )
            ),
            SF.Block(  
            ),
            SF.ElseClause( 
                SF.Token( SyntaxKind.ElseKeyword ),
                SF.IfStatement( 
                    SF.BinaryExpression( 
                        SyntaxKind.EqualsExpression,
                        SF.IdentifierName( "_a" ),
                        SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( "Y" ) )
                    ),
                    SF.Block(  
                    ),
                    SF.ElseClause(
                        SF.Token( SyntaxKind.ElseKeyword ),
                        SF.Block( 
                        )
                    )
                )
            )
        )
    )

Will get you this:

public void MyMethod() {
    if (_a == "X") {
    }
    else if (_a == "Y") {
    }
    else {
    }
}

for loops

This:

MethodDeclarationSyntax method = SF.MethodDeclaration(
    SF.PredefinedType( SF.Token( SyntaxKind.VoidKeyword ) ),
    "MyMethod"
    )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
    .AddBodyStatements( 
        SF.ForStatement(
            SF.VariableDeclaration( 
                SF.PredefinedType( SF.Token( SyntaxKind.IntKeyword ) ), 
                SF.SeparatedList(new [] {
                    SF.VariableDeclarator(
                        SF.Identifier( "i" ),
                        null,
                        SF.EqualsValueClause( SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( 0 ) ) ) 
                    )
                } )
            ),
            SF.SeparatedList<ExpressionSyntax>(),
            SF.BinaryExpression( 
                SyntaxKind.LessThanExpression,
                SF.IdentifierName( "i" ),
                SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( 10 ) )
            ),
            SF.SeparatedList<ExpressionSyntax>( new [] {
                SF.PostfixUnaryExpression(
                    SyntaxKind.PostIncrementExpression,
                    SF.IdentifierName( "i" )
                )
            } ),
            SF.Block(  
            )
        )
    )

Will get you this:

public void MyMethod() {
    for (int i = 0; i < 10; i++) {
    }
}

foreach loops

This defines our generic list:

LocalDeclarationStatementSyntax listDeclaration = SF.LocalDeclarationStatement(
    SF.TokenList(),
    SF.VariableDeclaration( 
        SF.GenericName( 
            SF.Identifier( "IList" ), 
            SF.TypeArgumentList( 
                SF.SeparatedList<TypeSyntax>( new [] { SF.PredefinedType( SF.Token( SyntaxKind.StringKeyword ) ) } ) 
            ) 
        ), 
        SF.SeparatedList( new [] {
            SF.VariableDeclarator(
                SF.Identifier( "list" ),
                null,
                SF.EqualsValueClause( 
                    SF.ObjectCreationExpression(
                        SF.Token( SyntaxKind.NewKeyword ),
                        SF.GenericName( 
                            SF.Identifier( "List" ), 
                            SF.TypeArgumentList( 
                                SF.SeparatedList<TypeSyntax>( new [] { SF.PredefinedType( SF.Token( SyntaxKind.StringKeyword ) ) } ) 
                            ) 
                        ),
                        SF.ArgumentList( SF.SeparatedList<ArgumentSyntax>( new ArgumentSyntax[0] ) ),
                        null
                    )
                )
            )
        } )
    )
);

And this our “foreach”:

ForEachStatementSyntax forEachStatement = SF.ForEachStatement(
    SF.PredefinedType( SF.Token( SyntaxKind.StringKeyword ) ),
    SF.Identifier( "item" ),
    SF.IdentifierName( "list" ),
    SF.Block()
);

Adding both to a method:

MethodDeclarationSyntax method = SF.MethodDeclaration(
    SF.PredefinedType( SF.Token( SyntaxKind.VoidKeyword ) ),
    "MyMethod"
    )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
    .AddBodyStatements( 
        listDeclaration,
        forEachStatement
    );

Will get you this:

public void MyMethod() {
    IList<string> list = new List<string>();
    foreach (string item in list) {
    }
}

while loops

This is one of the more straightforward ones.
This:

MethodDeclarationSyntax method = SF.MethodDeclaration(
    SF.PredefinedType( SF.Token( SyntaxKind.VoidKeyword ) ),
    "MyMethod"
    )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
    .AddBodyStatements( 
        SF.WhileStatement( 
            SF.LiteralExpression( SyntaxKind.TrueLiteralExpression ),
            SF.Block(  
                SF.BreakStatement()
            )
        )
    );

Will get you this:

public void MyMethod() {
    while (true) {
        break;
    }
}

Code Generation with Roslyn – Fields and Properties

I’m going to give a few more basic examples of code generation with Roslyn. The following assume that you have a ClassGenerationSyntax variable named “@class”. The examples have also shortened SyntaxFactory to SF using:

using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

Properties

The code

// Add a property
PropertyDeclarationSyntax @property = SF.PropertyDeclaration( SF.ParseTypeName( "String" ), "MyProperty"  )
    .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) );
// Add a getter
@property = @property.AddAccessorListAccessors(
    SF.AccessorDeclaration( SyntaxKind.GetAccessorDeclaration )
        .WithSemicolonToken( SF.Token(SyntaxKind.SemicolonToken ) 
        ) );
// Add a private setter
@property = @property.AddAccessorListAccessors( 
    SF.AccessorDeclaration( SyntaxKind.SetAccessorDeclaration )
    .AddModifiers( SF.Token( SyntaxKind.PrivateKeyword ) )
    .WithSemicolonToken( SF.Token(SyntaxKind.SemicolonToken ) 
    ) );
// Add the property to the class
@class = @class.AddMembers( @property );

Produces the code:

public class MyClass {
    public String MyProperty { get; private set; }
}

Variables

This adds a simple field to the class:

FieldDeclarationSyntax aField = SF.FieldDeclaration( 
    SF.VariableDeclaration( 
        SF.ParseTypeName( "String" ), 
        SF.SeparatedList(new [] { SF.VariableDeclarator( SF.Identifier( "_a" ) ) } )
    ) )
    .AddModifiers( SF.Token( SyntaxKind.PrivateKeyword ) );
@class = @class.AddMembers( aField );

Generating the code:

private String _a;

This code initializes the field to a new object:

ExpressionSyntax initializationExpression = SF.ObjectCreationExpression(
    SF.Token( SyntaxKind.NewKeyword ),
    SF.ParseTypeName( "OtherClass" ),
    SF.ArgumentList( SF.SeparatedList<ArgumentSyntax>( new [] {
        SF.Argument( SF.LiteralExpression( SyntaxKind.NumericLiteralExpression, SF.Literal( 1 ) ) ),
        SF.Argument( SF.LiteralExpression( SyntaxKind.StringLiteralExpression, SF.Literal( "abc" ) ) )
    } ) ),
    null
    );
FieldDeclarationSyntax bField = SF.FieldDeclaration( 
    SF.VariableDeclaration( 
        SF.ParseTypeName( "OtherClass" ), 
        SF.SeparatedList(new [] {
            SF.VariableDeclarator(
                SF.Identifier( "_b" ),
                null,
                SF.EqualsValueClause( initializationExpression ) 
            )
        } )
    ) )
    .AddModifiers( SF.Token( SyntaxKind.PrivateKeyword ) )
    .AddModifiers( SF.Token( SyntaxKind.ReadOnlyKeyword ) )
    ;
@class = @class.AddMembers( bField );

Generating the code:

private readonly OtherClass _b = new OtherClass(1, "abc");

Field-backed Properties

The following code generates a getter and setter backed by a field:

PropertyDeclarationSyntax property =
    SF.PropertyDeclaration( SF.ParseTypeName( "String" ), SF.Identifier( "A" ) )
        .AddModifiers( SF.Token( SyntaxKind.PublicKeyword ) )
        .AddAccessorListAccessors( 
            SF.AccessorDeclaration(
                SyntaxKind.GetAccessorDeclaration,
                SF.Block(
                    SF.List( new [] {
                        SF.ReturnStatement( SF.IdentifierName( "_a" ) )
                    } )
                )
            ),
            SF.AccessorDeclaration(
                SyntaxKind.SetAccessorDeclaration,
                SF.Block( 
                    SF.List( new [] {
                        SF.ExpressionStatement( 
                            SF.BinaryExpression( 
                                SyntaxKind.SimpleAssignmentExpression,
                                SF.IdentifierName( "_a" ),
                                SF.IdentifierName( "value" )
                            )
                        )
                    } )
                )
            )
        )
    ;

Producing the following code:

public String A {
    get {
        return _a;
    }

    set {
        _a = value;
    }
}

The ratio of code to output shows that it would be a lot easier to generate code from scratch with TextWriter.