Saturday, April 27, 2013

Using ARC with non iOS compiler - possible?

Did you ever have the situation with 2 lists sharing the same objects and possibly one or both had the OwnsObjects property set to true? Especially when using interfaced lists like in Spring4d or DSharp you want to make use of reference couting and automatic memory management. But what if some instances are shared between different lists or moved from one list to the other. You cannot use the Delete or Remove method and then add the object to the other list of vice versa if the first list has OwnsObjects true because it will destroy the instance when it gets removed. That is why there is the Extract method which removes the instance but does not destroy it. This can get complicated and possibly leading to memleaks or exceptions quickly.

Using interfaced objects for simple data storages might not be a very good idea. It requires you to write interfaces with the properties just for that purpose and if you use some kind of RTTI based binding you cannot do that as there is no RTTI for interface properties (which are just syntax sugar anyway).

So what would we give for some easy memory management in these cases. How about using the concept we know from interfaces and other types for objects?

Of course we could write some TRefCountObject and inherit our data classes from that base class and handle these in our Notify method inside the list when items get added or removed. But that would be to easy and not magic at all. ;) And more seriously it does not always work to change the base type due to several reasons.

So what do we need? Basically just a new field inside our object to keep track of the reference count. Keep in mind we cannot do a full ARC implementation because that would include assignments and parameter passing which would need compiler support. We just want it for when objects are put into lists.

The method that is responsible for allocating the memory of new instances is TObject.NewInstance. So we need to replace that:

procedure InitializeARC;
var
  Buffer: array[0..4] of Byte;
begin
  Buffer[0] := $E9
  // redirect TObject.NewInstance
  PInteger(@Buffer[1])^ := PByte(@NewInstance) - (PByte(@TObject.NewInstance) + 5);
  WriteMemory(@TObject.NewInstance, @Buffer, 5);
end;

What this code does is place a jump instruction at the very beginning of the TObject.NewInstance method that redirects it to our NewInstance routine which looks like this:

function NewInstance(Self: TClass): TObject;
begin
  // get additional memory for the RefCount field
  GetMem(Pointer(Result), Self.InstanceSize + SizeOf(Integer));
  Result := InitInstance(Self, Result);
end;

It does basically the same as the original except that it allocates 4 bytes more for our RefCount field and then calls our version of InitInstance (which is responsable for initializing the object):

function InitInstance(Self: TClass; Instance: Pointer): TObject;
const
  Buffer: Pointer = @BeforeDestruction;
begin
  Result := Self.InitInstance(Instance);

  // initialize the RefCount field
  GetRefCountFieldAddress(Instance)^ := 0;

  // replace TObject.BeforeDestruction
  if PPointer(NativeInt(Self) + vmtBeforeDestruction)^ = @TObject.BeforeDestruction then
    WriteMemory(PPointer(NativeInt(Self) + vmtBeforeDestruction), @Buffer, SizeOf(Pointer));
end;

Since TObject.InitInstance just zeroes the memory the RTL knows about (obtained by calling InstanceSize) we need to set our field which sits on the last 4 bytes in our instance:

function GetRefCountFieldAddress(Instance: TObject): PInteger; inline;
begin
  // the RefCount field was added last
  Result := PInteger(NativeInt(Instance) + Instance.InstanceSize);
end;

Along with the reference couting we want to make sure that the instance is not getting destroyed when it is still managed by the RefCount (because it sits in some list). That is why the BeforeDestruction method gets replaced. Why not detour like NewInstance? The implementation in TObject is empty so there are not 5 bytes of available that we can overwrite to jump to our implementation. But as it is virtual we can replace it in the classes VMT. Like its implementation in TInterfacedObject it will raise an error when the RefCount is not 0.

procedure BeforeDestruction(Self: TObject);
begin
  if GetRefCount(Self) <> 0 then
    System.Error(reInvalidPtr);
end;

Implementing the actual AddRef and Release routines is pretty easy aswell:

function __ObjAddRef(Instance: TObject): Integer;
begin
  Result := InterlockedIncrement(GetRefCountFieldAddress(Instance)^);
end;

function __ObjRelease(Instance: TObject): Integer;
begin
  Result := InterlockedDecrement(GetRefCountFieldAddress(Instance)^);
  if Result = 0 then
    Instance.Destroy;
end;

The most important thing: You need to add the unit which contains this as the very first unit in your project  (or after ShareMem) so the NewInstance method gets patched as soon as possible.

Time to test if it does what it should:

implementation

{$R *.dfm}

uses
  DSharp.Collections,
  DSharp.Core.ARC;

type
  TList<T: class> = class(DSharp.Collections.TList<T>)
  protected
    procedure Notify(const Value: T; const Action: TCollectionChangedAction); override;
  end;

procedure TList<T>.Notify(const Value: T;
  const Action: TCollectionChangedAction);
begin
  case Action of
    caAdd: __ObjAddRef(Value);
    caRemove: __ObjRelease(Value);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  list1, list2: IList<TObject>;
begin
  list1 := TList<TObject>.Create;
  list2 := TList<TObject>.Create;

  list1.Add(TObject.Create);
  list1.Add(TObject.Create);
  list2.AddRange(list1);
  list1.Delete(1);
end;

initialization
  ReportMemoryLeaksOnShutdown := True;

end.

When we click the button both objects get added to both lists and the last list containing an object will cause it to get destroyed when removed (which happens if the list gets destroyed aswell).

So far this is more of a proof of concept but I think this can make some code easier and less complicated especially when working a lot with lists and moving around objects without knowing what list at the end owns the objects.

You can find that code in the svn repository and as always your feedback is welcome.

Tuesday, April 23, 2013

Why no extension methods in Delphi?

I have been wondering this for a long time now. Why does Delphi not have this great language feature? Sure, we have helpers but they are not the same. First they are still officially considered a feature you should not use when designing new code. However it opens up some interesting possibilities - some might call it hacks... but that is a topic for another day. Second they don't work on interfaces or generic types. And interestingly though that is what I want to talk about today.

But first - if you don't know it already - I suggest you read what an extension method is - really I could not explain it any better. Oh, and to all readers that want to jump the "stop the dotnetification of Delphi - keep these new language features away" wagon - this post is not for you, sorry.

Ever had a class or a set of classes you wanted to add some functionality to? Sure, there are ways to do so like the decorator pattern. But did you see the problem there if you have a type you cannot inherit from because either you cannot modify the code or it's not a class but an interface? Well, then create a new interface and add that functionality there, someone might say. How, if you cannot extend the given type? Use the adapter or bridge pattern? You can see where this is going. You might end having to change existing code or introduce lots of code to apply your additional functionality.

The most prominent example of extension methods (and not surprisingly the reason they were introduced in C# 3.0) are the extension methods for IEnumerable<T>. If you want to use the foreach (or for..in loop in Delphi) all you have to implement is the GetEnumerator method (and actually the only method that IEnumerable<T> got). So if you ever need to implement that in some of your classes you implement just one method and got access to almost any query operation you can imagine - not saying they all make sense in every context, but you get the idea.

Extension methods are great. You don't clutter your class with things that don't belong there directly but apply to an aspect of your class (in our case being enumerable). They follow good principles like the dependency inversion principle. The way you are using them is more natural and makes more sense than having static methods (or routines) where you pass in the instance you want to call the method on as first parameter.

Even without the fancy LINQ Syntax without question it is much more readable to write

for c in customers.Where(HasBillsToPay).OrderBy<string>(GetCompanyName) do
  Writeln(c.CompanyName);

instead of

for c in EnumerableHelper.OrderBy<string>(
  EnumerableHelper.Where(customers, HasBillsToPay), GetCompanyName) do
  Writeln(c.CompanyName);

And that statement has only two chained calls - imagine how that grows in length if you got a more complex query with grouping or something else. Also in that case it is the order on how the query gets processed - easier to read and to write.

But - you remember - no helpers for interfaces and generics! Well, we can implement these methods in our base TEnumerable<T> class and/or put it on our IEnumerable<T> interface, no? Yes, we can. And everything would be fine if there wasn't one tiny detail - how generics are implemented in Delphi and how the compiler handles them: it generates a type for every specialization. Which means the same code compiled for every possible T in your application, for TCustomer, TOrder, TCategory and so on. Only with a small set of methods implemented (and possible classes for more complex operations like GroupBy for example) this means you get hundreds of KB added for each TList<T> you will ever use - even if you never touch these methods. That is because the linker cannot remove any method inside an interface even if never called.

So how to work around that problem (which is what I have been doing in the Spring4D refactoring branch lately)? Let's take a look again on how extension methods are defined. Nothing prevents us from creating that syntax in Delphi, so a Where method could look like this:

type
  Enumerable = record
    class function Where<TSource>(source: IEnumerable<T>;
      predicate: TPredicate<TSource>): IEnumerable<T>;
  end;

Simple, isn't it? But how to call it? We need a little trick here, let's see:

type
  Enumerable<T> = record
  private
    fThis: IEnumerable<T>;
  public
    function GetEnumerator: IEnumerator<T>;

    function Where(predicate: TPredicate<TSource>): Enumerable<T>

    class operator Implicit(const value: IEnumerable<T>): Enumerable<T>;
  end;

As you can see we use a record type that wraps the interface we want to extend and add the method there. We can implement the "extension methods" there or direct the call to our extension method type if we want to keep it seperatly.

We now have a nice way to do our query just like we wrote it above if customers where from Enumerable<T>. Or we can perform a cast (since we have an implicit operator that will get used). Also notice how the result of the Where method is of the record type. That way we can chain the calls easily. And because we implemented GetEnumerator we can use it in a for..in loop just like any IEnumerable<T>.

What's also nice about the record type is that the linker can now be smart and remove any method that we never call and save us dozens of megabytes in our binary (not kidding).

So our life could be so much easier if we had extension methods (or call them helper) for interfaces and generic types. But as long as we don't have that, we have to find some clever workarounds.

If you are a Spring4D user, check out the changes in the refactoring branch and let me know what you think.

Thursday, June 14, 2012

Bug or no bug - that is the question

Or with other words: when something is not what it looks to be - and you have no clue why.

Let me explain: Recently over on Nicks blog Márton mentioned that TRttiMethod.Invoke cannot handle var and out parameters. While I already created a runtime patch for the bug in the QC entry for 2010 and XE I was not sure about the handling of var and out parameters. I remembered I ran into some problem with calling the Invoke routine and Barry gave me the correct hint on how to handle passing values by reference. So I tried it:


program Project1;

{$APPTYPE CONSOLE}

uses
  Rtti;

type
  TTest = class
  public
    procedure CallVar(var i: Integer);
  end;

procedure TTest.CallVar(var i: Integer);
begin
  Inc(i);
end;

var
  test: TTest;
  ctx: TRttiContext;
  t: TRttiType;
  m: TRttiMethod;
  i: Integer;
begin
  test := TTest.Create;
  t := ctx.GetType(TTest);
  m := t.GetMethod('CallVar');
  i := 42;
  m.Invoke(test, [TValue.From<Integer>(i)]);
  Writeln(i);
  test.Free;
  Readln;
end.

It showed 42. First thought: yes, he is right, it does not handle them correctly. Second thought: wait, TValue is not taking any kind of reference to i. It just takes the value and stores it. So I changed the program a bit to check what was in the passed TValue argument.


var
  [...]
  v: TValue;
begin
  [...]
  v := TValue.From<Integer>(i);
  m.Invoke(test, [v]);
  Writeln(v.AsInteger);
  [...]
end.

Output remained 42. I messed around with passing the pointer to i inside the TValue but then the invoke method raised the EInvalidCast exception telling me: 'VAR and OUT arguments must match parameter type exactly'. I knew that this method checks this (not like the Invoke routine mentioned earlier) and passes them correctly. So what was going on? I changed it again:

var
  [...]
  v: TArray<TValue>;
begin
  [...]
  SetLength(v, 1);
  v[0] := TValue.From<Integer>(i);
  m.Invoke(test, v);
  Writeln(v[0].AsInteger);
  [...]
end.

Hooray, it showed the expected 43. What happened here? In the case where it did not work I used the open array constructor. The documentation says that it equivalent to passing a static array filled with the values passed to the open array constructor. Ok, I tested that:

var
  [...]
  v: array[0..0] of TValue;
begin
  [...]
  v[0] := TValue.From<Integer>(i);
  m.Invoke(test, v);
  Writeln(v[0].AsInteger);
  [...]
end.

Guess what? It returns 43. Seems it is not equivalent. Could it be that the code the compiler creates for an open array constructor does not handle the nested record inside of TValue - TValueData where the actual value is stored in - correctly? I was staring at the assembler code but as you know I pretty much suck reading something out there. While I was glad that TRttiMethod.Invoke actually handles var and out parameters correctly I could make a fix for DSharp mocks. But I still have no clue why passing the value with the open array constructor does not keep the value. Any ideas?

Sunday, June 3, 2012

Weak interface references

We all know how painful it can be working with interfaces and reference counting when it comes to circular or cross references.

Vincent Parrett wrote about that a while ago and presented a nice solution.

The only disadvantage about his solution was the special class type (TWeakReferencedObject) you have to inherit from to use a weak reference to. What if you want to use a weak reference to something that already exists and that you cannot change?

That is where my idea comes in.

The Weak<T> type supports assignment from and to T and makes it usable as if you had a variable of T. It has the IsAlive property to check if the reference is still valid and not a dangling pointer. The Target property can be used if you want access to members of the reference.

Let's assume you have that typical parent child relationship where both have a reference to each other. Normally that would cause a memory leak because that cross references would keep both objects alive. Change the parent reference to be a weak reference and both objects get destroyed properly because the child is not keeping the parent alive.

type
  TParent = class(TInterfacedObject, IParent)
  private
    FChild: IChild;
    procedure AddChild(const AChild: IChild);
  public
    destructor Destroy; override;
  end;

  TChild = class(TInterfacedObject, IChild)
  private
    FParent: Weak<IParent>;
  public
    constructor Create(AParent: IParent);

    function GetParent: IParent;
  end;

So how to check if the object of the reference is still valid? That is done by hooking the TObject.FreeInstance method so every object destruction is noticed and if a weak reference for that object exists it gets removed from the internal list where all weak references are stored.

While it works I am aware that this is hacky approach and it might not work if someone overrides the FreeInstance method and does not call inherited. It also is not yet threadsafe. It also might have a small performance impact because of the dictionary access in every FreeInstance call.

But hey, nothing is for free, isn't it? ;)

Thursday, May 31, 2012

Namespaces, open source and you

I have to admit - this will be kind of a rant. 8)

These days I am getting really annoyed when people are using XE2 when they are contributing to open source projects that are supposed to work also for XE or lower - no offense.

Huh, why?

Because XE2 just as every Delphi before automatically adds units to the uses clauses which are - you can see what is coming - are different from how they have been before for ages. Instead of having Forms in the uses of the typical VCL application, now we get Vcl.Forms. Or all the units that get added to a form.

So everyone not using XE2 will be unable to compile the awesome code you just wrote if you forgot to manually fix this unless he does it himself!

Maybe some clever people out there familar with IDE plugins figure out a way to restore the old way units are named when using them in a uses clause - which still works given you add the required namespaces to the project options.

Please share your thoughts. :)

Sunday, April 22, 2012

Creating a delegate at runtime

We know how anonymous methods work in Delphi for a while now. Barry explained how you can use that knowledge to put a delegate into a method pointer and Mason used the enhanced RTTI to get some details about them.

So we know that a delegate type (like TProc<T>) is basically an interface with an Invoke method that has the same signature as the delegate type definition (like procedure(Arg: T)). We also know that there is an TInterfacedObject behind it that is normally compiler created (these classes with $ActRec in their name).

So we basically have all we need to create our own delegate. Before you say: Why are you doing this? You can assign any regular procedure or method to a delegate when the signature is compatible - I will explain that later.

type
  PDelegate = ^IDelegate;
  IDelegate = interface
    procedure Invoke;
  end;

  TDelegate = class(TInterfacedObject, IDelegate)
  private
    FMethod: TMethod;
    procedure Invoke;
  public
    constructor Create(const AMethod: TMethod);
  end;

So we did something similar to what the compiler does when creating this (without the variable capturing of course which we do not need). Now we can put our method into a delegate variable without the built-in type compatibility and using a much more complicated and non type safe way. ;)

var
  proc: TProc<TObject>;
  method: TMethod;
begin
  method.Code := @TForm1.Button1Click;
  method.Data := Self;
  PDelegate(@proc)^ := TDelegate.Create(method);
  proc(Button1);
end;

One detail is missing. The implementation of the Invoke method. This is basically just adjusting the Self pointer and rerouting the call to the object that belongs to the method pointer (I am using my horribly poor x86 asm knowledge here).

procedure TDelegate.Invoke;
asm
  MOV EBX,[EAX].FMethod.Code
  MOV EAX,[EAX].FMethod.Data
  CALL EBX
end;

I guess many of you have more knowledge about that than I have so you might tell me if I made some mistake here. Also someone knows how this should look for x64?

So what is this all about? Why do we need to put a method into a delegate without the built-in assignment?

Remember DSharp multicast events? They work for any method type. But not for anonymous methods. Internally these events are using the ObjAuto unit to create a method pointer. So I can define Event<TNotifyEvent> and add any method that matches the TNotifyEvent signature. Just not anonymous methods that have this signature. So what if I just want to add a simple delegate? Not possible. I would need to define Event<TProc<TObject>> to do so. Internally the TEvent class works with a list of TMethod so I had to convert T which in that case is a anonymous method type (which is an interface you remember) to TMethod and the other way around. To actually call a multicast event there is the Invoke property which is of type T. Since the internally created method pointer is TMethod I needed to stuff that into an anonymous method type. In that case I already had the object which could hold the "magic" interface, the TEvent class itself.

Now there was just a little thing missing. The CreateMethodPointer function from ObjAuto needs a PTypeData for the signature of the method to create. Easy enough for a defined type in case of methods but not so for anonymous methods. So I needed the signature from the Invoke method of the interface and create some TTypeData from it. Important to mention that anonymous methods still do not have the $M+ by default so that does not work for the types defined in SysUtils.pas. You have to define your own types and adding that (so enhanced RTTI get generated for the interface methods). Fortunately Hallvard has explained how these things look and work so I "just" had to use the information from TRttiMethod to create a TTypeData record and fill that with the information needed by CreateMethodPointer.

I have to run some more tests with various signatures to make sure everything works (also add the 64-bit support). Then you will see these changes commited to the svn repository.

Saturday, December 3, 2011

Putting the pieces together - the DSharp presentation model

Recently there have been several threads and discussions about separating GUI and business logic. Of course that is nothing new, the MVC or MVP patterns are widely known. There is just one problem especially with these two patterns: the dependency between the presenter or the controller and the view and model. Often you cannot easily change the view. Testing the model and the controller or presenter without the view is complicated or impossible.

This is where the MVVM pattern has its benefits. Of course in WPF this pattern can shine because you have XAML but also in Delphi this pattern is worth a closer look. This pattern is also known as Presentation Model. The main benefit over MVC or MVP is that view and viewmodel have no dependency on each other. You can design the GUI independently from the business logic and just bind them together later. And there is the keyword that makes this pattern work: binding.

There are several amazing frameworks for MVVM development in .Net like Caliburn Micro or Prism. Caliburn consists of several different pieces to easily build applications the MVVM way. One of them is the ModelViewBinder. It takes the view (like a form or a frame) and a viewmodel (like a datamodule or another business object) and creates bindings to connect these two using naming conventions. For example the Lastname property of the viewmodel is bound to the Lastname edit on the view, the Orders property which may be a list gets bound to a listview called Orders. You could also bind the Customer.Address.Street property to the Customer_Address_Street edit on the view. All this gets powered by a DI container that puts all the pieces together, also by convention over configuration. If you have a viewmodel called CustomerDetailsViewModel there should be a CustomerDetailsView (there are actually several different conventions and you can add more if you like).

DSharp presentation model makes it possible to use the powerful spring DI container and data bindings to easily build applications that are easy to test and to develop. It sure is just scratching the surface yet but when you take a look at the ContactManager sample in the svn repository you can get a basic idea of what is possible.

Enough with just talking theory. Let's create a simple application!

Step 1 - The View

After creating a new VCL application (FMX is pretty similar - there are just not that many controls supported out of the box yet) we add some controls on the form so it looks like this:


After saving the unit the source looks like this:

unit CalculatorViewForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DSharp.Bindings, DSharp.Bindings.VCLControls;

type
  TCalculatorView = class(TForm)
    BindingGroup1: TBindingGroup;
    CalcOperator: TComboBox;
    CalcResult: TEdit;
    Calculate: TButton;
    Label1: TLabel;
    LeftOperand: TEdit;
    RightOperand: TEdit;
    Error: TEdit;
  end;

implementation

{$R *.dfm}

initialization
  TCalculatorView.ClassName;

end.

The only thing you actually have to write there after adding the components including the binding group is adding the unit DSharp.Bindings.VCLControls.pas (only if you don't have DSharp bindings VCL designtime package installed which inserts that unit automatically) and the line in the initialization part of the unit. This is necessary so the linker does not remove this class because it actually is not referenced anywhere (similar to the RegisterComponent you do if you are working with the DI container in the classic way).

Step 2 - The ViewModel

Now we create the viewmodel - the class that actually does the work and holds all the states of for the UI.

For our simple calculator we just need some fields and a method:

unit CalculatorViewModel;

interface

uses
  CalculatorInterfaces,
  DSharp.PresentationModel.ViewModelBase,
  SysUtils;

type
  TCalcOperator = (Add, Subtract, Multiply, Divide);

  TCalculatorViewModel = class(TViewModelBase, ICalculatorViewModel)
  private
    FLeftOperand: Double;
    FRightOperand: Double;
    FCalcOperator: TCalcOperator;
    FCalcResult: Double;
    FError: string;
  public
    procedure Calculate;

    property LeftOperand: Double read FLeftOperand write FLeftOperand;
    property RightOperand: Double read FRightOperand write FRightOperand;
    property CalcOperator: TCalcOperator read FCalcOperator write FCalcOperator;
    property CalcResult: Double read FCalcResult write FCalcResult;
    property Error: string read FError write FError;
  end;

implementation

{ TCalculatorViewModel }

procedure TCalculatorViewModel.Calculate;
begin
  try
    case FCalcOperator of
      Add: FCalcResult := FLeftOperand + FRightOperand;
      Subtract: FCalcResult := FLeftOperand - FRightOperand;
      Multiply: FCalcResult := FLeftOperand * FRightOperand;
      Divide: FCalcResult := FLeftOperand / FRightOperand;
    end;
    FError := '';
  except
    on E: Exception do
    begin
      FError := E.Message;
      FCalcResult := 0;
    end;
  end;
  DoPropertyChanged('CalcResult');
  DoPropertyChanged('Error');
end;

initialization
  TCalculatorViewModel.ClassName;

end.

We inherit from the TViewModelBase class which has some mechanics built-in that we need for the whole thing to work (like inheriting from TComponent which is necessary for the lifetime management and implementing several interfaces the framework needs). If you are just interested in creating something similar to the passive view and constructing the classes yourself and just using DSharp bindings you can just inherit from TPropertyChangedBase or some other class and wire things up yourself (or use the ViewModelBinder to do that without the rest of the framework).

We actually have no setters for the properties in this viewmodel because the changes just happen when you click the calculate button. Did you notice we named the properties exactly like the controls? That is not by accident. As I told you earlier the ViewModelBinder looks for components and properties it can bind together and it does it by their names.

One thing here is not obvious. We added the 4 operators to the items of the combobox earlier and we named them exactly the same (not the classic hungarian notation for enums here though). This is because the ViewModelBinder binds to the Text property of a TComboBox (you can change that to ItemIndex if you like - just edit the line in DSharp.PresentationModel.VCLConventionManager.pas). Then you can name the enums and the items differently. This may also make more sense when you localize the items in the combobox but it depends on how the combobox is set up. In the future the ViewModelBinder might consider the options of the combobox.

The calculation method is actually pretty simple. At the end it sends the notifications of the changed properties: CalcResult and Error. Keep in mind that this example does not show any kind of validations. You can still write rubbish into the edits. Since internally a conversion is done from string to double (bindings have a default value converter unless you specify one yourself) the value is not sent to the viewmodel if the converter cannot convert it into a double. How validations can be done and shown in the UI can be seen in the Validations sample.

Now let's take a look at the last unit of this example:

unit CalculatorInterfaces;

interface

uses
  DSharp.ComponentModel.Composition;

type
  [InheritedExport]
  ICalculatorViewModel = interface
    ['{03AF7AE1-CCDF-4F06-9074-919F6C759DBE}']
  end;

implementation

end.

The InheritedExport attribute tells the DI container to register every class it finds that implements this interface. That is why we had to add the line in the initialization part of the viewmodel unit. Because that class also is referenced nowhere and the linker would just throw it out. Why not doing the registration of the class there instead? That would actually create a dependency on the DI container and you have no chance to remove that registration for unit testing without code changes.

Remember to add a guid to the interface, otherwise the DI container will complain.

But wait - that interface does not have any methods. Yes, for our example it actually does not need them. Because bindings currently can only work between objects the interface is cast to the implementing object behind the scenes. Keep in mind that you cannot do interface delegation and binding to such interfaces. Also in our example we don't call anything on that interface because the Calculate method (of the object) is bound to the button. For a more complex scenario and actually using the interface methods look at the ContactManager example.

Step 3 - Putting the pieces together and starting up

Let's take a look at the dpr file now:

program Calculator;

uses
  Forms,
  CalculatorViewForm in 'CalculatorViewForm.pas' {CalculatorView},
  CalculatorViewModel in 'CalculatorViewModel.pas',
  CalculatorInterfaces in 'CalculatorInterfaces.pas',
  DSharp.PresentationModel.VCLApplication;

{$R *.res}

begin
  Application.Initialize;
  Application.Start<ICalculatorViewModel>;
end.

We have to make some modifications here. By adding the DSharp.PresentationModel.VCLApplication (or FMXApplication) unit we add the Start<T> method to TApplication. That is the method that starts it all up as the name implies. You have to specify the root viewmodel of your application. From there on you can build everything you like - manually or using the presentation model. We removed the other methods except Application.Initialize. I have to admit that I am not totally happy with that solution right now because it kind of breaks something in the IDE regarding editing the project options (only things like Title that result in the IDE editing the dpr file). Everything else still works, no worry. The Initialize call has to stay there because removing it would actually remove the theming from the application (another weird thing related to the source of the dpr file).

Let's start the application and look if it works (if you don't want to do all the steps by yourself you can find the source in the repository as always). For now I am not going into the implementation details - I leave that for a future post to explain how all the different pieces are working together to make it a bit clearer and less "magic".

DSharp presentation model is available for Delphi 2010 (without aspects) and higher (working on 64bit for XE2) - if you experience any problems feel free to send me an email or file an issue on the project page - I usually test it on all platforms but sometimes some of the nasty compiler or rtl bugs may break something.