DelphiMVCFramework is now Open Source!

DMVCFramework, Delphi XE4, Delphi XE5, MVC, RTTI 3 Comments »

DelphiMVCFramework Logo

Yes, just after 1 year of development, and a couple of big projects developed with it, the DelphiMVCFramework has been published as OpenSource.

The project is on google code svn https://code.google.com/p/delphimvcframework/

I’ll talk about it at ITDevCon2013 (http://www.itdevcon.it)

In the trunk there are many samples and I’m planning to put many others.

Main DMVCFramework features

  • RESTful (RMM Level 3) compliant
  • Server side generated pages using eLua (Embedded Lua)
  • Messaging extension using STOMP (tested with Apache Apollo and Apache ActiveMQ)
  • Can be used in load balanced environment using memcached (memcached.org)
  • Fancy URL with parameter mappings
  • Integrated RESTClient
  • Works with XE4 and XE5 (tested, but should works also on XE3 and XE2)
  • Experimental support for IOCP
  • Simple, but very very simple, to use…

It contains also a lot of indipendent code that can be used in other kind of projects.

These are the most notable:

  • Mapper (convert JSON <=> Object, ObjectList <=> JSONArray, ObjectLists <=> DataSets)
  • LuaBinding¬†(integrate Lua script into Delphi native code)
  • LuaTextFilter¬†(convert eLua into plain Lua executable script just like JSP)
Currently DMVCFramework use Embarcadero WebBroker framework, but is not tied to it. I’m working on a version that use IOCP (that is 10 times faster than plain WebBroker) and other web libraries for Delphi.
Code is enough stable and is already used in big production system.
WARNING!
There are a couple of bugs that affect WebBroker and so, DMVCFramework.
In our system, I’ve applied some patches to solve these problems. If you need those patches, ask me (I cannot publish the full code because it is Embarcadero licensed code).
The bugs are:
http://qc.embarcadero.com/wc/qcmain.aspx?d=119779
http://qc.embarcadero.com/wc/qcmain.aspx?d=119777
And another bug that affect also DataSnap and TIdHTTPWebBrokerBridge based projects.
Code is tested on XE4 and XE5 but should works also on XE3 and XE2.

Delphi MVC Web Framework - “Hello World”

Delphi XE, Delphi XE2, Design Patterns, Embarcadero, MVC, RTTI, dorm 6 Comments »

This is the first “Hello World” for my Delphi MVC Web Framework.

program DelphiMVCWebFramework;
  1.  
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses
  5.   System.SysUtils,
  6.   MVCEngine in 'MVCEngine.pas',
  7.   BaseController in 'BaseController.pas';
  8.  
  9. var
  10.   mvc: TWebMVCEngine;
  11. begin
  12.   mvc := TWebMVCEngine.Create;
  13.   mvc.AddRoute('/', procedure(Context: TWebContext)
  14.     begin
  15.       Context.Write('Hello World');
  16.     end).Start(8080);
  17.   ReadLn;
  18.   mvc.Free;
  19. end.

Features list (some of them are in the internal roadmap)

  • Completely MVC
  • Addressable with servername/controllername/actionname?par1&par2
  • Addressable with servername/controllername/actionname/par1/par2
  • Can also use anonymous methods as actions for very simple app (in the sample)
  • Really RESTful (Level 3 of the Richardson Maturity Model)
  • Fully integrable into WebBroker and DataSnap
  • Supports multiple resource rapresentations
  • Completely customizable routing using internal formatting or regex
  • Inspired to ASP.NET, Sinatra, Java Spring MVC, Java Restlet
  • Scriptable views support (Pascal, Razor, Lua)
  • Component based
  • Session support
  • ORM support using dorm
  • Classic TDataSet support
  • State server to support real loadbalancing using reverse proxy
  • Can be deployed as standalone (in the example), ISAPI dll and Windows Service
  • Fully support https
  • More to come…
  • This framework is still under development.

    Are you interested in? :-)

    UPDATE:

    The project is open source and you can fint it here

    https://code.google.com/p/delphimvcframework/

A Simple start with MVP in Delphi for Win32, Part 2

Delphi 2010, Delphi Dependency Injection, Design Patterns, MVC, MVP, Uncategorized 4 Comments »

Some month ago I wrote a simple article about an MVP variant called PassiveView.
That example was very simple. Now I’ll present a more “advanced” version of that example.

The main problem with first example was the following method:

  1. procedure TfrmCalculatorView.FormCreate(Sender: TObject);
  2. begin
  3.   //Link controls with related interface
  4.   IFirstOperand := TGUIEdit.Create(EditFirstOp);
  5.   ISecondOperand := TGUIEdit.Create(EditSecondOp);
  6.   ICalcResult := TGUIEdit.Create(EditResult);
  7.   IOperators := TGUISelectableList.Create(ComboOperators);
  8.   IError := TGUIEdit.Create(EditError);
  9.  
  10.   //link view and presenter
  11.   FPresenter := TCalculatorPresenter.Create(Self); //<<– THIS IS THE BAD LINE
  12. end;

The “BAD” line links the View with the Presenter but it’s in the view code, so this is meaning that View KNOWS the presenter… and this is not a good thing becouse the view is not so “passive”.

In a more advanced (and complex) version the View should be completely ignorant about the class that implement the presenter and the service.

In the main dpr file now the code now looks like the following.

  1. var
  2.   MainPresenter: ICalculatorPresenter;
  3.   CalculatorView: TForm;
  4. begin
  5.   Application.Initialize;
  6.   Application.MainFormOnTaskbar := True;
  7.   //SETUP THE MAIN APPLICATION FORM FOR VCL PURPOSE
  8.   Application.CreateForm(TfrmCalculatorView, CalculatorView);  
  9.   //SETUP ALL THE LINKS BETWEEN THE MVP TRIAD
  10.   MainPresenter := TCalculatorPresenter.Create(CalculatorView as ICalculatorView, TCalculatorService.Create);
  11.   //LETS START!
  12.   Application.Run;
  13. end.

Now the presenter take care about all links between the MVP triad.

  1. constructor TCalculatorPresenter.Create(CalculatorView: ICalculatorView;
  2.   CalculatorService: ICalculatorService);
  3. begin
  4.   inherited Create;
  5.   FCalculatorService := CalculatorService;
  6.   FCalculatorView := CalculatorView;
  7.   FCalculatorView.SetPresenter(self);
  8.   InitView;  //does the links
  9. end;

There is another addition to the previous example. Now there is only one constructor in the presenter, and using dependency injection take 2 interface for the view and the service.

  1.     constructor Create(CalculatorView: ICalculatorView; CalculatorService: ICalculatorService);

Another plus is the possibility to open the same form a number of times without change the code for create it.

This is the GUI for this simple application.

3 instance of the same view with different presenter and service

3 instance of the same view with different presenter and service

As bonus, unit tests and mock object arent changed.

As usual the source code is here.

A Simple start with MVP in Delphi for Win32, Part 1

CodeGear, Delphi for Win32, Design Patterns, MVC, MVP, Programming, Uncategorized 11 Comments »

As GUI framework such as VCL become more and more powerful, it’s common practice to let the UI layer do more than it should. Without a clear separation of responsibilities, the UI layer can often become an integral part of application and businness logic, but… this kind of responsabilities belongs to other layers of the application.
A design pattern (and his numberless variants), is especially well suited to solving this problem.

In this article I want to build a simple application using MVP pattern. Actually, pattern used is not “clear” MVP but his variation called Passive View.

Using Fowler words:

A perennial problem with building rich client systems is the complication of testing them. Most rich client frameworks were not built with automated testing in mind. Controlling these frameworks programaticly is often very difficult.

A Passive View handles this by reducing the behavior of the UI components to the absolute minimum by using a controller that not just handles responses to user events, but also does all the updating of the view. This allows testing to be focused on the controller with little risk of problems in the view.

Passive View ensures no dependecies between Model and View.

Passive View has no dependencies between view and model (Unlike most MVC-style triad)

Passive View has no dependencies between view and model (Unlike most MVC-style triad)

In this sample, “model” is a simple layer for application logic. In real world, “service layer” should incapsulate “application service” and “domain model“.

Application looks like following:

The Calculator

The Calculator

Div operator with result

Div operator with result

Div operator with a EDivByZero Exception

Div operator with a EDivByZero Exception

Connect View and Presenter
The view (the Form in VCL application) must implement an interface.

This interface should provide all method to interact with GUI:

  1. ICalculatorView = interface
  2.   ['{471E3657-C6CE-49A3-BCB4-8FA6AF611DAD}']
  3.   function FirstOperand: String;
  4.   function SecondOperand: String;
  5.   procedure SetFirstOperand(Value :String);
  6.   procedure SetSecondOperand(Value :String);
  7.   function GetOperator: IGUISelectableList;
  8.   procedure SetCalcResult(const Value: String);
  9.   procedure SetCalcResultReadOnly(const Value: Boolean);
  10.   function Error: IGUIEdit;
  11. end;

For simple interacting with GUI widget (in our example are EditFirstOperand, EditSecondoperand and EditCalcResult) we use a simple methods like following

  1.   function FirstOperand: String;
  2.   function SecondOperand: String;
  3.   procedure SetFirstOperand(Value :String);
  4.   procedure SetSecondOperand(Value :String);

But, if we need more by our widget (like populating combo box or change font color in the EditError or set ReadOnly to true) we should use another interface for a family of component.
In this sample I wrote 3 general interface:

  1.   IGUIBaseInterface = interface
  2.     ['{F0B7F031-9302-415E-8545-1FE20A365840}']
  3.   end;
  4.  
  5.   IGUIEdit = interface(IGUIBaseInterface)
  6.     ['{FE2D56FB-0CFB-4B33-9B56-0A523B235D37}']
  7.     procedure SetText(const Value: String);
  8.     function GetText: String;
  9.     function GetAsInteger: Integer;
  10.     function GetAsFloat: Extended;
  11.     procedure SetReadOnly(const AValue: boolean);
  12.     procedure SetVisible(const Value: Boolean);
  13.     function GetTextAsInteger: Integer;
  14.     procedure SetTextAsinteger(const Value: Integer);
  15.     function GetTextAsFloat: Extended;
  16.   end;
  17.  
  18.   IGUISelectableList = interface(IGUIBaseInterface)
  19.     ['{EEFE5C52-94C3-464B-80F2-05E443B0F0F6}']
  20.     procedure SetText(const Value: String);
  21.     function GetText: String;
  22.     procedure SetValue(const Value: String);
  23.     function GetValue: String;
  24.     function GetSelected: ISSKeyValue;
  25.     procedure AddPair(AKey, AValue: String);
  26.     procedure Clear;
  27.   end;

For implementation details see attached sample code.

Finally in FormCreate of our form we can wire Presenter and View:

  1. TfrmCalculatorView = class(TForm, ICalculatorView)
  2.   //code
  3. end;
  4.   //interface section
  5. procedure TfrmCalculatorView.FormCreate(Sender: TObject);
  6. begin
  7.   //Link controls with related interface
  8.   IOperators := TGUISelectableList.Create(ComboOperators);
  9.   IError := TGUIEdit.Create(EditError);
  10.  
  11.   //link view and presenter
  12.   //In this version VIEW know PRESENTER
  13.   FPresenter := TCalculatorPresenter.Create(Self);
  14. end;

This is a very simple example, so not all looks like real world. In a real world application, for example, view should not known the presenter class. With dependency injection you can do that (Next article in this serie will talk about this).

Every event generated by View (our Form) must be redirected to Presenter.

  1. procedure TfrmCalculatorView.Button1Click(Sender: TObject);
  2. begin
  3.   FPresenter.DoCalc;
  4. end;

Another approach is to publish some events in view interface and let presenter to bind them via standard event handler or anonimous methods (but this is for another post).

In attached sample code there is a sample application and unit test for Service Layer and View.
Required Mock Library is included in the zip file.

Simple Passive View, Sample Code

In 2nd part I’ll talk about unit test and mock object in Passive View.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in