WCF, WPF

New Enterprise Level Messaging Article Out

Where I work we have a number of disparate systems, which were all written at different times by different people, luckily all use the same technologies, that being .NET.

Though they are all written in differing versions of .NET, for example my team is lucky enough to be able to work in .NET3.5 SP1 / .NET 4.0, but we must also interface to older systems, and some other new’ish systems.

For the newish systems it’s a no brainer we use WCF, and as we want all messages to be reliable we use MSMQ binding for that.

But for the older systems it is a problem, do you write some custom MSMQ code, or do you look around for some sort of generic messaging solution.

I decided that I would look around and see what was freely available generic messaging solutions are out there, and I decided to write up my findings in a new article which goes into my findings in quite a lot of detail.

The particular framework that I picked up was called NServiceBus which seems to be pretty mature, and has been around for a while and works well with:

  • Winforms
  • ASP . NET
  • WPF
  • WCF

It also offers Pub/Sub, FullDuplex Client Server types of topology, and inbuilt message persistence using NHibernate, and allows the users to pick their own IOC container of choice.

It seemed to more than fill our requirements. I should mention that it did take me a while to get my head around how NServiceBus does things, all of which I present in the article.

I am really pleased with how the article turned out, and would urge you all to have a read, and if you like what you see please leave me a vote/comment I would appreciate that. These articles do take a while to write/investigate, and it is always nice to know ones hard work is appreciated, so as I say if you like the article please DO leave a vote/comment on the articles forum.

The full article can be obtained here :

http://www.codeproject.com/KB/dotnet/nserviceBusDemo.aspx

Advertisements
WPF

Pretty Cool Graphs In WPF

I have just finished writing up a new article for www.codeproject.com for which I will write another blog post about. Thing is, when I was looking into parts of that article I wanted to use some graphs in WPF, and had to have a hunt around to see what was out there.

After a look about I found a truly excellent graphing library for WPF which is completely free. It’s a www.codeplex.com project called “GraphSharp” which is freely available at graphsharp.codeplex.com.

I also figured it may be good to show people how to get up and running with GraphSharp in this standalone blog as the new article I published does absolutely no hand holding about the graph creation, as that was not really what the new article is about.

So how do we use GraphSharp then, well we need to do a couple of things

1. Create a customised Vertex type

The 1st step is to define a custom Vertex for the graph such that you can store additional information for each Vertex. This is done as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace GraphSharpDemo
{
    /// 
    /// A simple identifiable vertex.
    /// 
    [DebuggerDisplay("{ID}-{IsMale}")]
    public class PocVertex
    {
        public string ID { get; private set; }
        public bool IsMale { get; private set; }

        public PocVertex(string id, bool isMale)
        {
            ID = id;
            IsMale = isMale;
        }

        public override string ToString()
        {
            return string.Format("{0}-{1}", ID, IsMale);
        }
    }
}

2. Create a customised Edge type

The next step is to define a custom Edge type, you may want to show some extra information when the Edge is hovered over for example. This is done as follows:

using QuickGraph;
using System.Diagnostics;

namespace GraphSharpDemo
{
    /// 
    /// A simple identifiable edge.
    /// 
    [DebuggerDisplay("{Source.ID} -> {Target.ID}")]
    public class PocEdge : Edge
    {
        public string ID
        {
            get;
            private set;
        }

        public PocEdge(string id, PocVertex source, PocVertex target)
            : base(source, target)
        {
            ID = id;
        }
    }
}

3. Create a customised Graph

If you have custom Vertex/Edge you will need to create a custom Graph that knows about these custom types. Again this is very easily achieved, using the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuickGraph;

namespace GraphSharpDemo
{
    public class PocGraph : BidirectionalGraph
    {
        public PocGraph() { }

        public PocGraph(bool allowParallelEdges)
            : base(allowParallelEdges) { }

        public PocGraph(bool allowParallelEdges, int vertexCapacity)
            : base(allowParallelEdges, vertexCapacity) { }
    }
}

4. Create a customised GraphLayout

Using GraphSharp we also need to create a custom LayoutTyppe for the custom graph, which is done as follows:

public class PocGraphLayout : GraphLayout { }

5. Create a ViewModel

Since we are using WPF, why not follow best practices and use MVVM for it, which obviously means creating a ViewModel. Here is an example ViewModel that can be set as the DataContext for a Window/UserControl that hosts the GraphSharp graphing controls.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using GraphSharp.Controls;

namespace GraphSharpDemo
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        #region Data
        private string layoutAlgorithmType;
        private PocGraph graph;
        private List layoutAlgorithmTypes = new List<string>();
        #endregion

        #region Ctor
        public MainWindowViewModel()
        {
            Graph = new PocGraph(true);

            List existingVertices = new List();
            existingVertices.Add(new PocVertex("Sacha Barber", true)); //0
            existingVertices.Add(new PocVertex("Sarah Barber", false)); //1
            existingVertices.Add(new PocVertex("Marlon Grech", true)); //2
            existingVertices.Add(new PocVertex("Daniel Vaughan", true)); //3
            existingVertices.Add(new PocVertex("Bea Costa", false)); //4

            foreach (PocVertex vertex in existingVertices)
                Graph.AddVertex(vertex);

            //add some edges to the graph
            AddNewGraphEdge(existingVertices[0], existingVertices[1]);
            AddNewGraphEdge(existingVertices[0], existingVertices[2]);
            AddNewGraphEdge(existingVertices[0], existingVertices[3]);
            AddNewGraphEdge(existingVertices[0], existingVertices[4]);

            AddNewGraphEdge(existingVertices[1], existingVertices[0]);
            AddNewGraphEdge(existingVertices[1], existingVertices[2]);
            AddNewGraphEdge(existingVertices[1], existingVertices[3]);

            AddNewGraphEdge(existingVertices[2], existingVertices[0]);
            AddNewGraphEdge(existingVertices[2], existingVertices[1]);
            AddNewGraphEdge(existingVertices[2], existingVertices[3]);
            AddNewGraphEdge(existingVertices[2], existingVertices[4]);

            AddNewGraphEdge(existingVertices[3], existingVertices[0]);
            AddNewGraphEdge(existingVertices[3], existingVertices[1]);
            AddNewGraphEdge(existingVertices[3], existingVertices[3]);
            AddNewGraphEdge(existingVertices[3], existingVertices[4]);

            AddNewGraphEdge(existingVertices[4], existingVertices[0]);
            AddNewGraphEdge(existingVertices[4], existingVertices[2]);
            AddNewGraphEdge(existingVertices[4], existingVertices[3]);

            string edgeString = string.Format("{0}-{1} Connected", 
                existingVertices[0].ID, existingVertices[0].ID);
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));

            //Add Layout Algorithm Types
            layoutAlgorithmTypes.Add("BoundedFR");
            layoutAlgorithmTypes.Add("Circular");
            layoutAlgorithmTypes.Add("CompoundFDP");
            layoutAlgorithmTypes.Add("EfficientSugiyama");
            layoutAlgorithmTypes.Add("FR");
            layoutAlgorithmTypes.Add("ISOM");
            layoutAlgorithmTypes.Add("KK");
            layoutAlgorithmTypes.Add("LinLog");
            layoutAlgorithmTypes.Add("Tree");

            //Pick a default Layout Algorithm Type
            LayoutAlgorithmType = "LinLog";

        }
        #endregion

        #region Private Methods
        private PocEdge AddNewGraphEdge(PocVertex from, PocVertex to)
        {
            string edgeString = string.Format("{0}-{1} Connected", from.ID, to.ID);

            PocEdge newEdge = new PocEdge(edgeString, from, to);
            Graph.AddEdge(newEdge);
            return newEdge;
        }

        #endregion

        #region Public Properties

        public List LayoutAlgorithmTypes
        {
            get { return layoutAlgorithmTypes; }
        }

        public string LayoutAlgorithmType
        {
            get { return layoutAlgorithmType; }
            set
            {
                layoutAlgorithmType = value;
                NotifyPropertyChanged("LayoutAlgorithmType");
            }
        }

        public PocGraph Graph
        {
            get { return graph; }
            set
            {
                graph = value;
                NotifyPropertyChanged("Graph");
            }
        }
        #endregion

        #region INotifyPropertyChanged Implementation

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion
    }
}

6. Create and host the Graph Controls

So work with the GraphSharp Graph you need to use the GraphSharp UserControls for WPF. Here is what you need to do where I am using the MainWindowViewModel as just shown to bind against:

<Window x:Class="GraphSharpDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:graphsharp="clr-namespace:GraphSharp.Controls;assembly=GraphSharp.Controls"
        xmlns:local="clr-namespace:GraphSharpDemo"
        xmlns:zoom="clr-namespace:WPFExtensions.Controls;assembly=WPFExtensions"        
        Title="GraphSharpDemo" Height="350" Width="525">

        <zoom:ZoomControl  Grid.Row="1"  Zoom="0.2" 
        ZoomBoxOpacity="0.5" Background="#ff656565">
            <local:PocGraphLayout x:Name="graphLayout" Margin="10"
        Graph="{Binding Path=Graph}"
        LayoutAlgorithmType="{Binding Path=LayoutAlgorithmType, Mode=OneWay}"
        OverlapRemovalAlgorithmType="FSA"
        HighlightAlgorithmType="Simple" />

        </zoom:ZoomControl>
</Window>

7. Create Templates For Graph Vertices/Edges

Finally all that is left to do, is create some DataTemplates that will show what you want for your custom Graph Vertices/Edges. Here are some examples for the custom Vertices/Edges above

<DataTemplate x:Key="demoTemplate" DataType="{x:Type local:PocVertex}">
    <StackPanel Orientation="Horizontal" Margin="5">
        <Image x:Name="img" Source="../Images/boy.ico" Width="20" Height="20" />
        <TextBlock Text="{Binding Path=ID, Mode=OneWay}" Foreground="White" />
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsMale}" Value="false">
            <Setter TargetName="img" Property="Source"
                        Value="../Images/girl.ico" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

<Style TargetType="{x:Type graphsharp:VertexControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type graphsharp:VertexControl}">
                <Border BorderBrush="White" 
                        Background="Black"
            BorderThickness="2"
            CornerRadius="10,10,10,10"
            Padding="{TemplateBinding Padding}">
                    <ContentPresenter Content="{TemplateBinding Vertex}" 
                            ContentTemplate="{StaticResource demoTemplate}"/>

                    <Border.Effect>
                        <DropShadowEffect BlurRadius="2" Color="LightGray" 
                            Opacity="0.3" Direction="315"/>
                    </Border.Effect>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type graphsharp:EdgeControl}">
    <Style.Resources>
        <ToolTip x:Key="ToolTipContent">
            <StackPanel>
                <TextBlock FontWeight="Bold" Text="Edge.ID"/>
                <TextBlock Text="{Binding ID}"/>
            </StackPanel>
        </ToolTip>
    </Style.Resources>
    <Setter Property="ToolTip" Value="{StaticResource ToolTipContent}"/>
</Style>

Putting it all together it looks like this:

image

As always here is a small demo app : GraphSharpDemo.zip

C#

Contracts

I was doing something the other day and I noticed a new namespace that vaguely reminded me of something I looked at a while back.

The namespace in question is System.Diagnostics.Contracts, and the subject I was looking at was Spec# which was a research project for Microsoft. So it looks like some of this is now available in VS2010/.NET4.0.

Though not all of it, looks like you still need to install something extra to get the extra VS2010 Code Contracts tab that Somar talks about on his blog:

I don’t get that using standard VS2010, but hey ho, lets continue our looking at what we can do without installing anything extra.

So I have a really trivial example here where I have a small class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
 
namespace CodeContracts
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass t = new TestClass();
            t.SomeMethod("one");
            Console.ReadLine();
        }
    }
 
 
    public class TestClass
    {
        private List<string> counts = new List<string>();
 
        public int SomeMethod(string count)
        {
            Contract.Assert(count.Length == 5, "count length must be 5");
            counts.Add(count);
            return counts.Count();
        }
    }
 
}

Note the use of Contract.Assert in there, which generates this at Runtime
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

image

Now this is the same as what a lot of us have probably done with small static ArgumentValidator classes etc etc. Not much gain there.

But taking a bigger example (from the example in MSDN), we could have an interface called IArray that we want to implement and we could also have a ContractClassForAttribute and some code contracts on another class that will provide the contracts for a IArray implementation.

// An IArray is an ordered collection of objects.    
[ContractClass(typeof(IArrayContract))]
public interface IArray
{
    // The Item property provides methods to 
    //read and edit entries in the array.
    string this[int index]
    {
        get;
        set;
    }
 
    int Count
    {
        get;
 
    }
 
    // Adds an item to the list.  
    // The return value is the position the new element was inserted in.
    int Add(string value);
 
    // Removes all items from the list.
    void Clear();
 
    // Inserts value into the array at position index.
    // index must be non-negative and less than or equal to the 
    // number of elements in the array.  If index equals the number
    // of items in the array, then value is appended to the end.
    void Insert(int index, string value);
 
 
    // Removes the item at position index.
    void RemoveAt(int index);
}
 
[ContractClassFor(typeof(IArray))]
public abstract class IArrayContract : IArray
{
    int IArray.Add(string value)
    {
        // Returns the index in which an item was inserted.
        Contract.Ensures(Contract.Result<int>() >= -1);
        Contract.Ensures(Contract.Result<int>() < 
            ((IArray)this).Count);
        return default(int);
    }
    string IArray.this[int index]
    {
        get
        {
            Contract.Requires(index >= 0);
            Contract.Requires(index < ((IArray)this).Count);
            return default(string);
        }
        set
        {
            Contract.Requires(index >= 0);
            Contract.Requires(index < ((IArray)this).Count);
        }
    }
    public int Count
    {
        get
        {
            Contract.Requires(Count >= 0);
            Contract.Requires(Count <= ((IArray)this).Count);
            return default(int);
        }
    }
 
    void IArray.Clear()
    {
        Contract.Ensures(((IArray)this).Count == 0);
    }
 
    void IArray.Insert(int index, string value)
    {
        Contract.Requires(index >= 0);
        // For inserting immediately after the end.
        Contract.Requires(index <= ((IArray)this).Count);  
        Contract.Ensures(((IArray)this).Count == 
            Contract.OldValue(((IArray)this).Count) + 1);
    }
 
    void IArray.RemoveAt(int index)
    {
        Contract.Requires(index >= 0);
        Contract.Requires(index < ((IArray)this).Count);
        Contract.Ensures(((IArray)this).Count == 
            Contract.OldValue(((IArray)this).Count) - 1);
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

So now look at what happens when I create a class that implements IArray.

 

public class TestArrayContractClass : IArray
{
    private List<string> internalItems = new List<string>();
 
    #region IArray Members
 
    public string this[int index]
    {
        get
        {
            return internalItems[index];
        }
        set
        {
            internalItems[index] = value;
        }
    }
 
    public int Count
    {
        get { return internalItems.Count; }
    }
 
    public int Add(string value)
    {
        internalItems.Add(value);
    }
 
    public void Clear()
    {
        internalItems.Clear();
    }
 
    public void Insert(int index, string value)
    {
        internalItems.Insert(index, value);
    }
 
    public void RemoveAt(int index)
    {
        internalItems.RemoveAt(index);
    }
 
    #endregion
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

See even at design time, I get alerted to the fact that my contract is incorrect, I am not implementing the Add method correctly:

image

So if I try and run this, I will get a problem:

image

So I fix that and run it again, and all is good.

 

And here are some more interesting links on this

MVVM, Silverlight, WPF

Cinch + Latest Enhancements = I Am Finally Done

Ok everyone, this is hopefully it my last Cinch posting, then back to some other stuff for me.

I have this weekend made the following enhancements, and they were enhancements there was nothing wrong with codebase prior to this, but they were good ideas people gave me so I included them.

  • Altered Cinch V1 DataWrapper to take a Action in its constructor such that when the Cinch code generator is used the non auto generated part of the overall ViewModel class will be called back using the Action passed to the constructor of the DataWrapper when a property changes. Also got rid of ridiculous condtructors on the DataWrapper class, and also made it a partial class
  • Modified the Cinch code generator to support this, so when you next run the code generator you will see what it did. I basically added another callback call inside of DataWrapper<T> class
  • Altered Cinch V2 DataWrapper the same way as I did for V1 above.
  • Removed small issue in the WorkspaceData.ToString() override where I did not take into account a possible null dataValue. As you never know what this value could be (it could be any object) I have removed the ToString for the dataValue entirely. This is described at : http://cinch.codeplex.com/workitem/4917
  • Made the following classes partial
    • ValidatingObject (Cinch v1 and Cinch v2)
    • ValidatingViewModelBase (Cinch v1 and Cinch v2)
    • ViewModelBase (Cinch v1)
    • ValidatingViewModelBase (Cinch v1)
    • WorkspaceData (Cinch v2 WPF only)
  • Added a new ViewAwareStatusWindow service targeting Windows
  • Added a Non mandatory extra event to WorkSpaceData that can be used to cancel a closing of a workspace. Revised WPF demo to show this for ImageLoader workspace and left About workspace as it was to show it is not mandatory.
  • Resynced with MeffedMVVM release 58837

But that is my done with Cinch now, unless someone finds a bad bug that breaks loads of things in which case I will of course take notice, but until then Hasta La Vista Baby…..More new stuff to enjoy whoohoo

 

Enjoy

MVVM, Silverlight, WPF

Cinch V2 Part 6 : Out Now (Also my 100th article at codeproject)

I have just released the 6th and final part in my Cinch V2 article series. This article covers Silverlight4 support using Cinch.

It can be read using this link :

http://www.codeproject.com/KB/WPF/CinchV2_6.aspx

celebrate

It is also my 100th article over at codeproject, which means a great deal to me, and if you like what I do, I would really appreciate some votes and comments for that article, so please do that, if you feel inclined.

I will be doing a few enhancements to Cinch based on some cool ideas people have suggested. But once I do that, I fully intend on making it to 200 codeproject articles or more. As such I have a massive list of stuff that I want to learn, and I will be cracking on with that, and shall also get back to properly blogging. Enough of this self promotional horse crap thing, that has been happening lately with Cinch, it just had to be done, and it has been done now, so thanks everyone and thanks for all the tuna….But me and Cinch are now done, as I have more interesting things to do.