Next Generation Web With ASP.NET MVC, Knockout.js, SignalR, NServiceBus

Most of the websites that we know today, show a similar architecture:

- The Client (Browser) request a specific page.
- The Server handles the request and returns the result.
- The result is displayed on the Browser.
- From here the content of the site remains “static”. That means: If the user wants to see the newest data, he/she needs to refresh the site. (Or the website contains a Javascript polling mechanism and retrieves the new data in background via Ajax.)

With new technologies we can build real-time websites. The SignalR Framework offers the ability to push content from the server to the client. The communication between server and client is always dependent on the Browser possibilities. SignalR has the following fallback strategy:

1. WebSockets Only if supported by server and client. It is the only transport possibility which establishes a true two-way communication.
2. Server Sent Events Supported by browsers except Internet Explorer.
3. Forever Frame Only for Internet Explorer. Hidden IFrame with uncompleted request to the server. The server sends the data through this (one-way) channel.
4. Ajax long polling Ajax request which stays open until the server responds. A new connection is requested after each response.

The best thing is: The API is the same for all fallbacks! We don’t have to take care about the transport mechanism.

Now with SignalR we can create real-time websites. I’ve created a simple website which queries Google and Twitter and pushes the data to the Browser.
This is the architecture:

Next Gen Web Arch

Next Gen Web Arch

The client sends a search request to the server (ASP.NET MVC). The MVC Controller sends a Command via NServiceBus. The Command is stored in a Message Queue. The web request ends at this point.
An NServiceBus server application handles the Command. In this case, the Command contains the the search term entered by the user. The Handler queries Google and Twitter data and publishes the response via NServiceBus.
The ASP.NET MVC application receives the search result from the Message Queue and pushes the data to the client through a SignalR Hub.
Knockout.js is responsible for binding/displaying the data.

Here is a short video: Next Generation Web Video

Typing TypeScript

Since companies are moving every single application to web, TypeScript gets more and more interesting. JavaScript is nice, but it wasn’t designed for big web applications. TypeScript is a Javascript language extension with very useful features. It isn’t a JavaScript killer. The code is converted to JavaScript and the browser executes pure JavaScript code. We don’t need a TypeScript interpreter.

TypeScript features:

Type annotation/signature Declaring function parameter and return types. Enables type checking at compile time.
Classes Classes and inheritance.
Interfaces Used for describing types and indexable objects. Extending existing types.
Modules Code encapsulation. A well designed module is maintainable and can be reused.
Lambda expressions Creating lambda/anonymous functions.

Here is a small example.

module HardWorker {

    export interface ISayHello {
        sayHello(): void;
    }

    export class Developer implements ISayHello {
        public firstName: string;
        public lastName: string;

        constructor(firstName: string, lastName: string) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        sayHello() {
        }
    }

    export class JavaDeveloper extends Developer {
        sayHello() {
            alert("Hello Java");
        }
    }

    export class DotNetDeveloper extends Developer {
        sayHello() {
            alert("Hello C#");
        }
    }
}

window.onload = () => {
    
    var javaDev = new HardWorker.JavaDeveloper("Max", "Muster");
    var dotNetDev = new HardWorker.DotNetDeveloper("Darko", "Micic");
    
    javaDev.sayHello();
    dotNetDev.sayHello();
};

The compiler generates following JavaScript code. (This code is executed in the browser.)

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var HardWorker;
(function (HardWorker) {
    var Developer = (function () {
        function Developer(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        Developer.prototype.sayHello = function () {
        };
        return Developer;
    })();
    HardWorker.Developer = Developer;    
    var JavaDeveloper = (function (_super) {
        __extends(JavaDeveloper, _super);
        function JavaDeveloper() {
            _super.apply(this, arguments);

        }
        JavaDeveloper.prototype.sayHello = function () {
            alert("Hello Java");
        };
        return JavaDeveloper;
    })(Developer);
    HardWorker.JavaDeveloper = JavaDeveloper;    
    var DotNetDeveloper = (function (_super) {
        __extends(DotNetDeveloper, _super);
        function DotNetDeveloper() {
            _super.apply(this, arguments);

        }
        DotNetDeveloper.prototype.sayHello = function () {
            alert("Hello C#");
        };
        return DotNetDeveloper;
    })(Developer);
    HardWorker.DotNetDeveloper = DotNetDeveloper;    
})(HardWorker || (HardWorker = {}));
window.onload = function () {
    var javaDev = new HardWorker.JavaDeveloper("Max", "Muster");
    var dotNetDev = new HardWorker.DotNetDeveloper("Darko", "Micic");
    javaDev.sayHello();
    dotNetDev.sayHello();
};
//@ sourceMappingURL=app.js.map

ASP.NET MVC Conversational Session

I’m proudly presenting you my first self-made NuGet package. :)

NuGet: ASP.NET MVC Conversational Session (Nuget)
Codeplex: ASP.NET MVC Conversational Session (Codeplex)

I’ve created a small extension for ASP.NET MVC which simplifies the session handling in tabbed browsing scenarios.
The extension ensures, that your session data won’t be overwritten. For example:

  • Page 1: Contains a list of entities. When the user clicks on “Edit” a new window/tab gets opened.
  • Page 2 (edit page): Data is stored in session because the edited data needs to be displayed on page 3,4 etc. On the last page, the user decides if he wants to save the data.

Now if the users tries to edit two entities at same time (two different window/tabs), the session data will overwritten. There will be always one entity in the session.

The “ASP.NET MVC Conversational Session” extension helps out in such situations. It allows to create “conversations”.
Features of a conversation:

  • Contains contiguous data.
  • Isolated. Data cannot be overwritten.
  • Parallel conversations possible.
  • Two types of conversations: Controller and Name-scoped

In the scenario above, the page 2 (edit page) should store data in a conversation to prevent problems when the user works with multiple windows/tabs.

The code is fairly easy to use. Here are some examples:

Controller scoped conversation
First you have to set the conversation attribute on the class. You can access the conversation with the extension method “Conversation()”.

[Conversation]
public class PersonController : Controller
{
    protected HttpConversationalSessionState Conversation
    {
        get { return this.Conversation(); }
    }

    public ActionResult Index()
    {
	    this.Conversation["MyKey"] = "Conversation data";
        return View();
    }
    
    // Clear conversation data after this call. (Declarative)
    [Conversation(End=true)]
    public ActionResult SiteTwo()
    {
        // Read data from the CURRENT conversation.
	    var data = this.Conversation["MyKey"];
       
        // Ending current conversation the imperative way
        // is possible too.
        this.Conversation.End();
        
        return View();
    }
}

Name scoped conversation
Works exactly the same way as in the example above with a small difference. You have to define the name of the scope in the conversation attribute. In this example the conversation with the name “demo” can be access from multiple controllers.

[Conversation(Scope = "Demo")]
public class Scope1Controller : Controller
{
    protected HttpConversationalSessionState Conversation
    {
        get { return this.Conversation(); }
    }

    public ActionResult Index()
    {
        this.Conversation["MyKey"] = "Conversation Data";
        return View();
    }
}

[Conversation(Scope = "Demo")]
public class StillScope1Controller : Controller
{
    protected HttpConversationalSessionState Conversation
    {
        get { return this.Conversation(); }
    }

    public ActionResult Index()
    {
		var data = this.Conversation["MyKey"];
        return View();
    }
}

The conversation attribute can also be defined on the controller action. In such scenario, only name scoped conversations makes sense.

The view
Now here comes a part I try to improve in the next releases. :)
Every conversation has a identifier which must be passed from the client. That means, we have to add the identifier to the links and form actions. Here are some examples:

@using System.Web.Mvc.Conversation.View;

@Html.ActionLink("Site two", "SiteTwo").AsConversational()

@using (Html.BeginForm("Confirm", "Person", Html.CreateRouteValues()))
{
  ...
}

The “AsConversational” extension method adds the conversation identifier to the url.
And the same for forms with: “CreateRouteValues”.

If the Conversation Session could run inside ASP.NET MVC (core), we wouldn’t take care about the indentifier. (Link generation would happen in the background.)
But because we are running outside the core (extension), we must add the identifier on our own.

Feel free to test/use this extension.
Here is a small demo app: Conversation Session Demo

And… Your feedback is highly appreciated! ;)

Entity Framework Code First And SQL Server DACPAC

Entity Framework Code First Migrations allows you to handle changes in your model (C#) by generating “migration scripts” for keeping the DB in sync with the code. It works very well. But I never used it in a project with more than 1 developer. I think we could run in different problems. And managing all the generated migration scripts requires discipline. There is maybe a solution which handles all this problems very well. But in this example here, I’m explaining a slightly different way for the migration scenario.

Idea:
While developing

  • Every developer has its own development database.
  • The EF configuration is set “auto migration”.
  • The developer doesn’t create any migration scripts.

On Build Server

  • Step 1: Server sets up the new database model.
  • Step 2: Creating a new extract (DACPAC) with SqlPackage.exe.
  • Step 3: Comparing the extract with the previous database model. (Writing a report)
  • Step 4: Generating a migration SQL script. (Handle data loss manually.)
  • Step 5: Publish migration script.

For a PoC, I ran all steps on my development machine. Here is the result:

The model:

public class Person
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Lastname { get; set; }
}

The data context:
In DEBUG the EF uses the MigrateDatabaseToLatestVersion initializer. In all other cases
the ValidationInitializer (custom class) is being used, which only verifies if the current model is compatible with the database model.

public class DataContext : DbContext
{
    public DbSet People { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
#if DEBUG
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, Configuration>());
#else
        Database.SetInitializer(new ValidationInitializer());
#endif
        base.OnModelCreating(modelBuilder);
    }
}

public class ValidationInitializer : IDatabaseInitializer
{
    public void InitializeDatabase(DataContext context)
    {
        if (!context.Database.CompatibleWithModel(false))
        {
            throw new ModelNotCompatibleException();
        }
    }
}

The code above creates/updates automatically the database structure.

class Program
{
    static void Main(string[] args)
    {
        var db = new DataContext();
        // Creates database structure if not exists.
        db.People.ToList();
    }
}

Now we change the person model. (New property “Fullname” and the properties “Firstname” and “Lastname” deleted.)

public class Person
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Fullname { get; set; }
}

I changed the connectionstring so that next time I execute the application a new database is being generated. (I need to this, because I run all steps on my development machine. I need two DBs for schema comparison.)

Now the following steps have to executed on the build server! (In a real/professional environment)

This step generates a DACPAC file based on the new database model.

SqlPackage.exe /Action:Extract /SourceConnectionString:"Data Source=.\;Initial Catalog=DataDb_Release_2; Integrated Security=SSPI;" /TargetFile:"E:\Schema_Release_2.dacpac"

The next step generates the deployment report. (The DB schema won’t be changed!)

SqlPackage.exe /Action:DeployReport /TargetConnectionString:"Data Source=.\;Initial Catalog=DataDb_Release_1; Integrated Security=SSPI;" /SourceFile:"E:\Schema_Release_2.dacpac" /OutputPath:"E:\Schema_Release_2.xml"

The generated XML file contains 3 data issues.



  
    
      
      
      
    
  
  
    
      
        
      
    
  

Now we create a migration SQL script:

SqlPackage.exe /Action:Script /TargetConnectionString:"Data Source=.\;Initial Catalog=DataDb_Release_1; Integrated Security=SSPI;" /SourceFile:"E:\Schema_Release_2.sql"

In this script, we can implement the handling for the 3 reported data issues. Then we can ran the script.

sqlcmd -S .\ -i "Schema_Release_2.sql"

Now we delete the MigrationHistory table in the migrated database! (You need to do this only the first time)

DROP TABLE dbo.__MigrationHistory;

This is it.

So… Now I change the connectionstring in my VS.NET project to the migrated database and I change the project context to “Release”.
EF will do only the model validation and NO “auto migration”. If model isn’t compatible with the DB structure, an exception will be thrown.

Caution: This is only a PoC. I’ve never used it in a real project.

Visual Studio 2012 Fakes

Microsoft has released a kind of “mocking” framework in Visual Studio 2012. In most cases when we are writing unit tests, we’re using frameworks like Moq, which helps us creating Mocks/Stubs. (For example: Mocking the data layer so that we can test the business layer.)

In this tutorial, you see how to use “Stub” and “Shim” of the “Fakes Framework”:

Stub A implementation of a interface or abstract class which will be passed into the logic you want to test.
Shim Method interception at run-time. Allows you to overwrite the implementation of a specific type. (Even .NET types)

This is the structure of my VS.NET solution.

Fakes Solution

Here you see the implemented business and data logic:

public class Bank
{
    public static decimal TransferLimit = 10000;
    private IBankRepository _repo;

    public Bank(IBankRepository repo)
    {
        this._repo = repo;
    }

    public bool Transfer(int account1, int account2, decimal amount)
    {
        if (amount > Bank.TransferLimit)
        {
            var mailer = new SmtpClient();
            mailer.Send("...@....",
                "...@....",
                "Transfer limit exceeded", string.Empty);
            return true;
        }
        else 
        {
            this._repo.Withdraw(account1, amount);
            this._repo.Deposit(account2, amount);
            return true;
        }
    }

    public DateTime InactiveSince(int account)
    {
        return DateTime.Now;
    }
}
public class BankRepository : IBankRepository
{
    public bool Deposit(int account, decimal amount)
    {
        throw new NotImplementedException("todo");
    }

    public bool Withdraw(int account, decimal amount)
    {
        throw new NotImplementedException("todo");
    }
}

Now in my Test project, I added fakes for the assemblies “Data” and “System”.
Fakes

My test class contains three test methods:

Test 1
The first test method creates a Stub object for the repository and defines the return values for the methods “Deposit” and “Withdraw”.

[TestMethod]
public void BankTransfer_StubExample_Interface()
{
    /*** Arrange ***/

    // Create stub for data access
    var stub = new Data.Fakes.StubIBankRepository() 
    {
        // Return true
        DepositInt32Decimal = (account, amount) => true,
        // Return true
        WithdrawInt32Decimal = (account, amount) => true
    };

    /*** Act ***/
    // Call the business logic and pass the 
    // data access stub
    var business = new Business.Bank(stub);
    var result = business.Transfer(1, 2, 75);

    // Assert
    Assert.IsTrue(result);
}

The class “StubIBankRepository” is placed under the namespace “Data.Fakes”. “Data” is the namespace I’ve defined in my Data assembly.
That means:

Data interface Data.IBankRepository
Fake Data.Fakes.StubIBankRepository

In the “Act” section, the Stub object is passed to the Bank constructor and afterwards
the business logic “Transfer” is being executed.
This test tries to transfer 75 from account 1 to account 2.
The transfer limit is 10000 (see code of Bank class above). In this first test, the transfer is below the limit and the data layer will be called. When you scroll up you will see, that the concrete implementation of the IBankRepository will throw an NotImplementedException. But because we are working with a Stub object, the Stub will be called rather than the concrete implementation.

Test 2
The second test is more interesting. The code below tries to transfer 20000 from account 1 to account 2.
In that case, the business logic sends an “notification e-mail” to the bank. The Bank class uses directly the SmtpClient (no abstraction). In our unit test, we want to test the core logic without sending an e-mail.
Because the smtp client isn’t passed to the business logic, we have to intercept the object creation and fake the SmtpClient type at run-time. (Shim)

[TestMethod]
public void BankTransfer_ShimExample_Smtp()
{
    /*** Arrange ***/

    // Create stub. (Stub won't be called in that test!)
    // We don't need to define method implemtations.
    var stub = new Data.Fakes.StubIBankRepository();

    bool result = false;
    using (ShimsContext.Create())
    {
        // "Replace" the real SmtpClient.Send implementation.
        // (Full path: System.Net.Mail.Fakes.ShimSmtpClient)
        ShimSmtpClient.Constructor = self =>
        {
            var shim = new ShimSmtpClient(self);
            shim.SendStringStringStringString = (from, to, subject, body) => { };
        };

        /*** Act ***/
        var business = new Business.Bank(stub);
        result = business.Transfer(1, 2, 20000);
    }

    /*** Assert ***/
    Assert.IsTrue(result);
}

The code above executes the “Transfer” business logic and fakes the SmtpClient so that no e-mail will be sent.

(For accessing the Shim class, you have to extend the System.fakes configuration.)

VS.NET Shim

VS.NET Shim

Test 3
Here the last example. This code shows how to fake the DateTime.Now object using Shim.

[TestMethod]
public void BankTransfer_ShimExample_DateTime()
{
    /*** Arrange ***/
    var stub = new Data.Fakes.StubIBankRepository();
    var date = new DateTime(2012, 01, 03);

    DateTime result = DateTime.MinValue;
    using (ShimsContext.Create())
    {
        // Configure DateTime.Now getter.
        // Return always the same date!
        ShimDateTime.NowGet = () => date;

        /*** Act ***/
        var business = new Business.Bank(stub);
        result = business.InactiveSince(1);
    }

    /*** Assert ***/
    Assert.IsTrue(result == date);
}

Happy unit testing! ;)

Download the Solution!

It’s Worth To Be Lazy<>

In the past few projects I saw a lot of wrong implemented Singleton patterns. Since Microsoft released the class “Lazy<>” in .NET 4.0, Singleton is much easier to implement. So… be lazy and use the class Lazy<> ;)

Here is an example:
This code here initializes the “_instance” variable when accessing the the “Instance” property for the first time.
Lazy<> ensures thread-safe lazy initialization.

public class Unique
{
    private static readonly Lazy<Unique> _instance = new Lazy<Unique>(() => new Unique());

    private Unique() { }

    public static Unique Instance
    {
        get { return _instance.Value; }
    }
}

And here are two examples without the Lazy<> type.

Eager initialization

public class ExampleOne
{
    private static readonly ExampleOne _instance = new ExampleOne();

    private ExampleOne() { }

    public static ExampleOne Instance
    {
        get { return _instance; }
    }
}

Lazy initialization

public class ExampleTwo
{
    private static readonly object _sync = new object();
    private static volatile ExampleTwo _instance;

    private ExampleTwo() { }

    public static ExampleTwo Instance
    {
        get 
        {
            if (_instance == null)
            {
                lock (_sync)
                {
                    if (_instance == null)
                    {
                        _instance = new ExampleTwo();
                    }
                }
            }
            return _instance;
        }
    }
}

Onion Architecture – C#.NET

If you never heard about the “Onion Architecture”, you should read Jeffrey Palermos blog post. He’s the Onion-Architecture-Guru ;-)

I created a very small demo VS.NET solution, which shows how I would apply this type of architecture in a project. (The download link is at the bottom of this post.)

The following graph displays the dependencies between the VS.NET projects.

OnArch Dependency Graph

OnArch Dependency Graph


My Core contains two libraries:

OnArch.Core Is the main core library and contains the business logic and the interfaces for all outer layers. This project doesn’t contain any references to technology specific assemblies like EF etc.
OnArch.Core.Entity Contains only the entities. It’s allowed to place entity-specific logic inside the entity classes. But I would prefer to place all logic in the OnArch.Core project. The reason why I placed the entities in a separated project is: Sometimes you may need only the entities and not the whole application logic etc. For example, when you have a WCF service and a .NET WCF client and you don’t want to generate proxy classes. (You see an example in my demo solution.)

You see in the graph, that all projects in the outer layers are referencing the core libraries. And not vice versa. I’ve excluded the DependencyResolution project because of the clarity of the graph.

As a reference, I posted here the real “Onion”. :-)

Onion Architecture

Onion Architecture

The first version of my demo solution can be downloaded here:

Onion Architecture V 0.1

.

Delayable Notification Collection – WPF/Silverlight MVVM

In my last project (WPF/MVVM) I had to deal with a lot of data in the application. I stored the data in a ObservableCollection and bound the collection to a chart and a grid. Everything worked very well. But the data in the ObservableCollection changed frequently. By default, the ObservableCollection notifies every change in the collection. (Add,Remove etc.) This slowed down the application extremely, because I had to iterate through the collection and add or remove multiple items. Therefore, I decided to create a custom collection which delays the notification. The code below sends at the end only one “dummy” notification. It don’t tells what exactly happend with the data.

Here is the code:

public class DelayableNotificationCollection<T> : ObservableCollection<T>
{
    #region Types

    public class DelayHandler : IDisposable
    {
        public bool CanNotify { get; set; }
        public Func<bool> NotifyIfTrue { get; set; }

        private DelayableNotificationCollection<T> Collection;

        public DelayHandler(DelayableNotificationCollection<T> collection)
        {
            this.Collection = collection;
            this.CanNotify = true;
        }

        public void ForceNotify()
        {
            this.Collection.ExecBaseOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        public void Notify()
        {
            // Dummy notification
            this.Collection.ExecBaseOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        public void Dispose()
        {
            if (this.NotifyIfTrue != null)
            {
                if (this.NotifyIfTrue())
                    this.Notify();
            }
            else
                this.Notify();

            this.CanNotify = true;
            this.NotifyIfTrue = null;
        }
    }

    #endregion

    private DelayHandler Handler;

    public DelayableNotificationCollection()
    {
        this.Handler = new DelayHandler(this);
    }

    private void ExecBaseOnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnCollectionChanged(e);
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (this.Handler.CanNotify)
            this.ExecBaseOnCollectionChanged(e);
    }

    public DelayHandler Delay(Func<bool> notifyIfTrue = null)
    {
        this.Handler.CanNotify = false;
        this.Handler.NotifyIfTrue = notifyIfTrue;
        return this.Handler;
    }
}

The following example shows how to use the DelayableNotificationCollection class:

static void Main(string[] args)
{
    var collection = new DelayableNotificationCollection<string>();
    collection.CollectionChanged += collection_CollectionChanged;

    Console.WriteLine("> CollectionChanged will be raised.");
    collection.Add("A");
    Console.WriteLine("> CollectionChanged will be raised.");
    collection.Add("B");
    Console.WriteLine("> CollectionChanged will be raised.");
    collection.Add("C");

    Console.WriteLine();

    using (var handler = collection.Delay())
    {
        Console.WriteLine("> CollectionChanged WON'T be raised.");
        collection.Add("D");
        Console.WriteLine("> CollectionChanged WON'T be raised.");
        collection.Add("E");
        Console.WriteLine("> CollectionChanged WON'T be raised.");
        collection.Add("F");
        Console.WriteLine("> CollectionChanged WILL be raised.");
        handler.ForceNotify();
        collection.Add("G");
        Console.WriteLine("> CollectionChanged WON'T be raised.");
        collection.Add("H");
        Console.WriteLine("> CollectionChanged WON'T be raised.");
        collection.Add("I");

        Console.WriteLine("> CollectionChanged will be raised.");
    }

    Console.WriteLine("> CollectionChanged will be raised.");
    collection.Add("J");
    Console.WriteLine("> CollectionChanged will be raised.");
    collection.Add("K");

    Console.Read();
}

static void collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    Console.WriteLine(">> Notification received.");
}

And here is the output:
DelayableNotificationCollection Demo

Cheers! ;)

Using Neo4j Graph DB With C#.NET

In the following example I’ll explain how to access the Neo4j database with the Neo4jClient. I’ve used both components in a project and was very satisfied.

Information about Neo4j: http://neo4j.org/
Information about Neo4jClient: http://hg.readify.net/neo4jclient/wiki/Home

For this demo I created an entity class called Person. This class will be represented in Neo4j as a node.

public class Person
{
    public string Name { get; set; }
}

Then I defined two relationship classes. An relationship has to inherit from Neo4jClient.Relationship and implement Neo4jClient.IRelationshipAllowingSourceNode<>, Neo4jClient.IRelationshipAllowingTargetNode<>.
The both interfaces are defining the direction and the entity types of the start and end node of the relationship. The following code contains two relationship classes called “KnowsRelationship” and “HatesRelationship”. Both can be used only with the person class. (Start and end node)

If a relationship has attributes, then your class needs to inherit from the generic Relationship class. The generic type is your data class. In my example “HatesData”.

public class HatesData
{
    public string Reason { get; set; }

    public HatesData()
    { }

    public HatesData(string reason)
    {
        this.Reason = reason;
    }
}

public class KnowsRelationship : Relationship, IRelationshipAllowingSourceNode<Person>,
    IRelationshipAllowingTargetNode<Person>
{
    public static readonly string TypeKey = "KNOWS";

    public KnowsRelationship(NodeReference targetNode)
    : base(targetNode)
    { }
 
    public override string RelationshipTypeKey
    {
        get { return TypeKey; }
    }
}

public class HatesRelationship : Relationship<HatesData>, IRelationshipAllowingSourceNode<Person>,
IRelationshipAllowingTargetNode<Person>
{
    public static readonly string TypeKey = "HATES";

    public HatesRelationship(NodeReference targetNode, HatesData data)
        : base(targetNode, data)
    { }

    public override string RelationshipTypeKey
    {
        get { return TypeKey; }
    }
}

Now we have an entity called person and two relationship types which can be used for defining relationship between all person objects.
Now let’s create some sample data. There is no need to set up the data structure like in a RDBMS. The Neo4jclient serializes the objects and sends them to the Neo4j services. Neo4j parses the data and creates nodes and all relationships between them on the fly.

// Init
var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();
         
// Create entities
var refA = client.Create(new Person() { Name = "Person A" });
var refB = client.Create(new Person() { Name = "Person B" });
var refC = client.Create(new Person() { Name = "Person C" });
var refD = client.Create(new Person() { Name = "Person D" });

// Create relationships
client.CreateRelationship(refA, new KnowsRelationship(refB));
client.CreateRelationship(refB, new KnowsRelationship(refC));
client.CreateRelationship(refB, new HatesRelationship(refD), new HatesData("Crazy guy")));
client.CreateRelationship(refC, new HatesRelationship(refD), new HatesData("Don't know why...")));
client.CreateRelationship(refD, new KnowsRelationship(refA));

And here is the result visualized with the Neo4j web admin.
Graph Sample Data

Now the cool thing is, you can query the data very easy. Let’s select all
who hates the “Person D”.
(I used in this example the Cypher query language.)

var query = new Neo4jClient.Cypher.CypherQuery(
    "start n=node(8) match n<-[r:HATES]-e return e.Name as Name;", 
    new Dictionary<string, object>(), 
    CypherResultMode.Projection);

var result = client.ExecuteGetCypherResults<Person>(query);

This query will return the person "B" and "C". (Like displayed in the picture above. Id 6 and 7.)

Have fun with Neo4j and Neo4jClient ;)

Entity Framework ‘Code First’ Approach and Domain-Driven Design

With the Code First approach we can create clean entities without any EF specific code. After the first demo, I saw that you have to deal with the IDbSet interface, which is placed in the Entity Framework library.
When you place the entities in your business dll you have to reference the EF library. This is a bit ugly. After some testing I saw that the IDbSet interface implements the generic IQueryable interface.
So it’s possible to cast the IDbSet to a more common interface.
In this example you will see how to use EF Code First without referencing the EF lib in your business library.

EDIT 15.04.2013:
Based on the user feedback, I decided to extend the VS.NET solution. The first version was focusing on the BL and DAL. The new version contains a possible end-to-end solution. -> ASP.NET MVC – BL – DAL (Entity Framework). What’s new?:

  • Dependency Injection: The CompositionRoot project contains the type mapping definition and is responsible for the type resolution.
  • The UI project references the CompositionRoot (for initializing at startup) and the Business (for accessing the business interfaces.)
  • And again: This blog post still focuses on the technical aspects of EF and persisting domain entities.

Here is a picture of my solution folder. The business dll references only the System lib. This project contains the core logic and the interfaces for the DAL.
The Domain folder contains the entities.

Solution Folder

Solution Folder


The context interface is clean. There are no EF specific types used:

public interface IContext
{
    IQueryable<Person> People { get; set; }
    IQueryable<Address> Addresses { get; set; }
    void Add<T>(T obj) where T : DomainObject;
    void Save();
}

And here are the entities:

public class DomainObject
{
    public Guid MyId { get; set; }
}

public class Person : DomainObject
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public ICollection<Address> Addresses { get; set; }
}

public class Address : DomainObject
{
    public string Street { get; set; }
    public string City { get; set; }
    public int Zip { get; set; }
    public virtual Person Person { get; set; }
}

In the infrastructure library I created a context class which implements the IContext interface.

public class Context : DbContext, IContext
{
    public Context()
        : base("MyDb")
    { }

    public IDbSet<Person> PersonSet { get; set; }
    public IDbSet<Address> AddressSet { get; set; }

    public IQueryable<Person> People
    {
        get { return this.PersonSet; }
        set { this.PersonSet = (IDbSet<Person>)value; }
    }

    public IQueryable<Address> Addresses
    {
        get { return this.AddressSet; }
        set { this.AddressSet = (IDbSet<Address>)value; }
    }

    public IQueryable<TEntity> GetSet<TEntity>() where TEntity : class
    {
        return this.Set<TEntity>();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasKey(x => x.MyId)
            .Property(x => x.MyId)
            .HasColumnName("Id");

        modelBuilder.Entity<Address>().HasKey(x => x.MyId);
            
        base.OnModelCreating(modelBuilder);
    }

    public void Add<T>(T obj) where T : DomainObject
    {
        this.Set<T>().Add(obj);
    }

    public void Save()
    {
        base.SaveChanges();
    }
}

The both public properties PersonSet and AddressSet are used by the EF. But for development, only the properties “People” and “Addresses” are important.
My Entities do not have any entity framework specific Data Annotations like [Key], [ForeignKey] etc.
This definition is made in the OnModelCreating method.
This is it!

Here is the source code.