Amazon.com Widgets Delphi

Flotsam and Jetsam #84

By Nick at June 07, 2014 20:29
Filed Under: Delphi
  • I am currently working on two things:
    • First, I’m working to provide general documentation for the Spring4D project.   The documentation can be found in the project’s wiki, and you are more than welcome to contribute to what I’ve started there.  Interestingly, the wiki can be managed as a Git project consisting of *.md (markdown) files.  That’s the way I’m doing it, though if you want, you can edit the wiki directly in the browser.  Pull requests are gladly accepted.
    • Second, I’m getting back into the Delphi Unit Test project.  Things have slowed down there, and I’ve decided to try to continue adding tests.  Thanks should go to Jeroen Pluimers for putting a lot of effort into the infrastructure of the project.  Of course, pull requests are gladly accepted here as well.
  • You wouldn’t build a fence into your neighbor’s yard.  Why would you allow an object to escape the scope in which it is used?
  • The BOGO offer is back.  That’s “Buy one get one free” for those of you not familiar with the marketing lingo.
  • My book continues to sell pretty well, even after a few months.  Thanks.  The book’s Google Group reached 600 members this week.  Thanks again. 
  • I was having a conversation with a friend this week and we came to the conclusion that you can’t really call yourself a developer if you don’t have Git, Mercurial, and Subversion installed on  your development machine.  You should also be proficient in at least one of them.  What do you think?
  • If you aren’t reading Mark Seamann’s blog, you should be.  This site is solid gold.  Mark wrote the excellent Dependency Injection in .NET which you should read immediately if you haven’t already done so.  For instance, his series on Poka-yoke Design is just fantastic.  Clearly written and illustrated.  I’ve probably raved about his blog before, but it’s just so worth reading.  I’d love to be directed to a better blog on software development.
  • And while you are at it, read this great article – Speed in Software Development.  It was pointed out to me by the inestimable Mark Edington.  I particularly enjoyed it being a former sprinter and a former marathoner – with a strong emphasis on “former”. 

Flotsam and Jetsam #83

By Nick at May 26, 2014 07:23
Filed Under: Delphi, TechBiz
  • Del Yocam is a former Borland CEO, a purchaser of $30,000 couches, the creator of the immortal “Inprise”, a lover of pizza, and apparently a check kiter.
  • I have decided to take the advice of some commenters and leave the site pretty much alone.  I removed a bunch of the ads that weren’t generating much if any revenue and removed some of the little boxes on the side that I didn’t think were very useful or that anyone paid any attention to.  Hopefully it is a bit cleaner that way. 
  • So I have a “Bleg” – a blog beg.  I’m not pleased with the code formatter used by this blog.  It’s hard to set up, seems to keep breaking, and feels old and outdated.  Anyone have any better ideas?
  • I’d like to personally thank each and every one of you that have purchased my book.  I also really appreciate the kind words I’ve received.  I’m really very grateful.  It’s really cool to know that you have written a book that actually has a listing on Amazon.  And I won’t lie – the extra money has been very timely.  And a quick word about that – I have made far, far, far more money having self-published than I would have had I worked through an established publishing house.  The publishing industry is changing rapidly, and my excellent experience with self-publishing is a testimony to that.  Thanks should go to LeanPub and CreateSpace for making it possible.  If you are thinking about writing a book – any kind of book – I’d strongly recommend that route.
  • I’m going to be giving my Unit Testing talk at the Philly.Net Code Camp next month.  If you are in the Philadelphia area, you might consider coming to the event.  It is a much bigger conference this year, spanning two days and happening at the Valley Forge Convention Center.  Typically there are 700 or more folks there – it’s usually a big event.  The talks are generally aimed at .Net developers, but there is a lot of Javascript and other topics.  I’ll be there both days.
  • I had a great time at the Delphi Developer Days in Baltimore earlier in the month.  It was great to see Cary and Loy, as well as Dr. Bob.  The classes were good, Jim McKeeth was there, and it was nice to meet new folks as well.   I highly recommend these events.  There are DDD’s in London and Amsterdam still left.  I don’t know if there is space available, but if you can attend, I think you should.

Coding in Delphi Website

By Nick at May 19, 2014 10:04
Filed Under: Delphi

Coding in Delphi now has its own website.   Visit and be amazed.

I’m not happy with this blog design.

By Nick at May 10, 2014 17:07
Filed Under: Delphi, General

I’m not happy with my blog design.  Frankly, I think it kind of looks terrible. 

But here’s the problem.  I don’t really know what to do about it. 

I’m currently using BlogEngine.Net, and a theme for it that I kind of cobbled together to do things that I wanted it to do.  I wonder if I should switch to WordPress where the plugins and themes are endless, or stick with BlogEngine.net which has much less support. BEN has continued to be updated – I just recently updated this blog to the 2.99 version – but the overall support level isn’t what WordPress is.   I could work on it myself – it is open source – but as you can probably tell, I’m no graphic designer.

A switch now would break all my links.  I don’t want to do that.

My hosting service is DiscountASP.NET, which is very good, but very .NET focused.  If I want to use a different engine, I may have to switch providers.  Not fun. 

I guess my best choice is to just try to somehow improve what I have. 

What do you think?

Delphi XE6 is Here

By Nick at April 15, 2014 11:17
Filed Under: Delphi, Tech Stuff

Delphi XE6 has been released.  There are reportedly over 2500 bug fixes in it, which is quite a few and quite in keeping with the QPS (Quality, Performance, Stability) plan they’ve discussed.  Probably the best place to find out what is in the release is in the DocWiki’s What’s New Page

 

And if you are ready to make the move, you can click on the banner below and purchase:

Thank you ADUG

By Nick at March 30, 2014 16:43
Filed Under: Delphi

I had a great time at ADUG 2014 this year.  I'm grateful to the group for their gracious hospitality.  They took very good care of me, and I'm thankful.  I was honored to sign all of the copies of Coding in Delphi that I did, and was pleased to see so many of them there. :-)  I presented on Dependency Injection and Patterns in Delphi both in Melbourne and Brisbane.  I think that talks were well received.  Overall, I love going to Australia and was honored to be asked.  Thanks, ADUG. 

Flotsam and Jetsam #82

By Nick at March 18, 2014 17:26
Filed Under: Delphi, Flotsam and Jetsam
  • Yay!  Flotsam and Jetsam is back!  Did you miss it?
  • Okay, some really interesting things going on with Appmethod.  Appmethod is Embarcadero’s new cross-platform development tool.  For you Delphi/RADStudio types, it appears to be a FireMonkey only IDE with some new connectivity that will be of interest only to mobile developers.  In other words, it is a new aimed squarely at new customers and not “us”.  Anyway, David I has a bunch of links on his blog, including a bunch of nice press coverage.  This new offering appears to me to be aimed squarely at the Xamarin space, as the pricing is very similar.  Should be fun to see how this plays out. 
    • As a side note – if you are a Delphi/RAD Studio person, this product is not for you, and so you need not be upset if the offering and the pricing is not to your liking.  Stick with RAD Studio and cheer on the product as Embarcadero expands into a new market.  This is a good thing – Embarcadero is branching out to reach into the very hot, growing, and important mobile development market.  This is a new, exciting entry into that nascent market.  I for one am hoping for great success for Appmethod, because that can only be good for Embarcadero and thus Delphi.  It represents a whole new revenue stream for the company, and what is good for Appmethod will be good for Delphi. 
  • Some interesting things to note that are going on with Appmethod:
    • You can report bugs not in QualityCentral, but in a public JIRA repository.  That is very interesting.
    • In addition, there appears to be a completely new Embarcadero Community website.  Appmethod is the only app represented there so far, but the rest of the products can be far away.
    • Part of the new community site are public forums. Looks like you can earn points and rank for being an active participant.  I wonder what will happen to the existing ones that support NNTP. I know many folks over there will give up their NNTP readers when you pry them from their cold, dead fingers.  Again, should be interesting.
    • Here’s the Appmethod EULA online for everyone to read.
  • Book Update: As I hope you know, my book is available two ways – in electronic form to people who purchase XE5, and in paperback form from CreateSpace and Amazon.  Many of you have purchased – more than I had hoped, in fact, and I’m really greatful.  Thanks very much, really.  It’s really an honor to have someone buy your book.  If you have purchased the book, I sure would appreciate a review on Amazon – good or bad! – as that really helps other people decide whether to buy.  Thanks to David Schwartz who was the first to do a review on Amazon.
  • Kind of lost in the shuffle a bit with Appmethod and all is the fact that Embarcadero purchased Erwin From CA Technologies. I find this to be a really interesting move, because when I was at Embarcadero, Erwin was “the enemy” – the product that ER Studio competed most strongly with.  Embarcadero now has two tools that basically do the same thing. I guess they won’t need this page and whitepaper anymoreWinking smile It will be interesting to see how that plays out. 

Nick in Australia

By Nick at March 10, 2014 10:23
Filed Under: Delphi

I’m really excited to return to Australia and speak at the Australian Delphi Users Group.  They were kind enough to invite me, and so off I go next week to Melbourne and Brisbane to talk about Dependency Injection and Design Patterns.  If you are in Australia and not going, I’m guessing that it’s not too late to sign up. If you are going, I’m looking forward to seeing you again or meeting you for the first time.  I’m also looking forward to a little summer weather after this crazy winter in Pennsylvania.  Winking smile

Coding in Delphi Now Available in Print

By Nick at February 22, 2014 10:54
Filed Under: Delphi, Software Development

My book, "Coding in Delphi" is now available in print.  This is pretty cool. You can get it from CreateSpace or Amazon.  I'm grateful for every order. 

It seems very strange to have my own entry for sale on Amazon.  Writing a book is a lot of work, but I will say, it's quite satisfying to hold the book in your hand and see your name on Amazon.com.  :-)

I'd also be very grateful for book reviews on Amazon.  If you like the book, please let people know.  And if you don't like it, write a review and say why.  Either way, I'll appreciate your honest assessment.  You can write the review right from the Amazon order page.  

And again, I'm grateful to all of you who have had so many nice things to say, who helped edit the book, and who make the Delphi community so great.

I’m Speaking at EKON 17

By Nick at September 05, 2013 12:07
Filed Under: Delphi, Personal

Hey, I’d be delighted if you came to see me speak at the EKON 17 conference in Cologne, Germany the first week in November.

Ekon17_2013_fullsize_19917_v2

I’ll be giving two regular talks on Unit Testing and Dependency Injection, as well as an all day tutorial on advanced programming topics such as Generics, Anonymous Methods, RTTI, Virtual Interfaces, and more.  The conference will be a great time with such well-known and respected names as Ray Konopka, Cary Jensen, Jeroen Pluimers, Daniel Wischnewski and more.  Marco Cantu from Embarcadero will also be there.

I’m really looking forward to going.  You should go, too.

The Delphi Unit Test Project

By Nick at August 17, 2013 16:02
Filed Under: Delphi, Unit Testing, Software Development

In a previous post, I humbly suggested that Embarcadero publish their unit tests for Delphi.  I still think it is a good idea, but I understand if they don’t do it.  They do have a lot to do.

So I thought – after suggestions from folks that read the post, including Kenneth Cochran – that it would be a good idea to just go ahead and start our own community project.  So I did.

The Delphi Unit Tests Project

This is a pretty straight-forward project – it is merely a set of unit tests for Delphi’s RTL.  You can find out the basics on the home page of the wiki, where you’ll also find further information about writing tests, etc.  It’s a wiki, so it will continue to be expanded. I’m kind of weird in that I actually enjoy writing unit tests, so I’ve been adding tests over the last week or so.

This is a community project based on Mercurial.  That means that anyone can fork it, add tests, and then submit a pull request.  We’ve already had four or five submissions, and I’m really appreciative.  It’s quite easy to contribute, and you can write tests for anything you like.  Any submitted tests must pass, of course.

We are also using the new Delphi unit testing framework, DUnitX.  It is still a bit rough around the edges, but hopefully this will be an impetus to get it fully up to speed.  I’ve volunteered to write the GUI runner, but there are some architectural issues that need to be taken care of.  Right now, you can output to NUnit xml and the console.  DUnitX is attribute based and really easy to use.

Things I’d  like to eventually get done:

  • I’d like to get at least one test for everything we can in the RTL.
  • I’d like to figure out a way to have tests written for QualityCentral reports.  The tests could “pass”, proving the bug exists, and then when they “fail”, that could show that the bug has been fixed. 
  • I’d love to see our tests eventually get integrated into the Embarcadero internal build.  That would be really cool.

In any event, come join the cause and write a test.  Even one single test would be fine!

Produce More, Consume Less: A year and a half later

By Nick at July 28, 2013 16:31
Filed Under: Personal, Delphi, General

On January 1, 2012 – a year and a half ago – I wrote the this post called “Produce More, Consume Less”.  In it I discussed a bunch of stuff that I wanted to do in the coming year.  I thought it might be fun to review and see how I am doing on those things:

Write a substantive post on my blog once a week.

I did well with this for a while, but recently, I haven’t blogged much because I’ve been working on my book.  (See below).  In addition, 2012 ended up being a difficult year for the Hodges household, and so the blogging didn’t get done as much as I would have liked.  However, I think I have posted a pretty good chunk of content over the last year and a half.

Find an open source project and work on it.

Here I have fallen down.  I’ve wanted for a long time to write /// documentation for the Spring Framework, but I haven’t really done that.  I have created a good collection of Delphi code demos on BitBucket, but I’m not sure we can really call that an “open source project”.  I will put effort into the Spring for Delphi documentation moving forward, I promise.

I’m going to get off my butt and walk.

I did…okay here.  I walked a lot with my wife.  Recently, however, this has tapered off quite a bit, and I’m sorry to say that I’m as heavy as I’ve ever been.  However, in just the last two days, I’ve started a determined effort to start running again.  I ran track and cross-country in college (though you can tell it was a very, very long time ago just by looking at me) and I’d like to be a runner again.  I’m determined this time.  We’ll see.  Actually, I have to because if I don’t, I’m headed for a heart attack.  Seriously.   

I’m going to write a book on coding in Delphi.

Well, I didn’t get it done in 2012, but I’m currently working hard on it and hope to have it done this year instead.  I’m nearly done with all the chapters for the first draft, and am looking more closely into how to get a cover, get it ready for publishing, etc.  I’m setting my sites on publishing it by the end of the year.

I’m going to be deliberate and purposeful in what I read. 

I think I have done pretty well here.  I made a list of books that I wanted to read and have read them, both novels and technical books. (I got an Amazon Kindle Paperwhite for Christmas, and I’ve read my books on it almost exclusively)   I’ve read a lot, and have a good list of “to read” books.  On the Internet side, I’ve pared down my collection of RSS feeds quite a bit, and spend time reading only those that are really important (like the blog of my wife and proofreader, ipaintiwrite). By the way, with the demise of Google Reader, I’ve switched over to The Old Reader for tracking my RSS feeds.

I’m going to be deliberate and plan any [TV and Movie] watching I do. 

Here I’ve done very well.  I don’t watch much TV anymore at all, and when I do, I deliberately choose what to watch and do so.  For instance, I recently finished up “Orange is the New Black” on Netflix, having decided deliberately to watch it.  I also watched “House of Cards”.  I can’t remember the last time I just sat down and randomly picked something to watch on TV.  As for Movies, I’ve seen most of the blockbusters in the theatre and watched almost no movies on DVD, Netflix, etc.  I’m pleased with how this is going.

I’m going to remove FreeCell from my phone.

I did this, as well as removed all other games from my phone. Other than playing Words with Friends at lunch with my co-workers (we are pretty obsessive about it), I’ve done really well here. I have spent very little time playing games, and when I have, it’s  been with my son for some good bonding time.

I’m going to spend time selling stuff on eBay.

This has been average.  I have sold some items, as well as donated a lot of things to charity.  I still have stuff that I’d like to sell, but haven’t really made a big dent in the large amount of “stuff” that I own.  I’d like to have less stuff, and so I’ll have to get after this.

Overall, after a year and a half, it’s not bad, but not great.  Losing weight, getting in shape, and publishing my book are at the top of the list going forward. 

In Which I Argue That Embarcadero Should Open Source Their Unit Tests

By Nick at July 27, 2013 13:27
Filed Under: Software Development, Delphi, Unit Testing

All good developers write unit tests.  The Delphi team is no different.  The team has a suite of unit tests for the RTL and a very, very large set of tests for the compiler.  The tests for the RTL are, to a large degree, DUnit based.  The compiler tests are a bit different, as they date back well before DUnit even existed.  They are a set of console applications that write out PASS or FAIL to the standard output depending on whether the test passed or failed. I believe that this suite of tests also tests a lot of the lower level RTL.   I know the QA team doesn’t like to test the RTL using a tool that depends heavily on the RTL itself.

So anyway, this suite of tests exists.  They get run constantly as part of a continuous integration process at Embarcadero.  And the suite gets expanded as time goes by.  When I managed the R&D team, I even contributed to the test suite myself.

But given that you can’t ever have enough unit tests, and that like all companies, Embarcadero has limited resources, the test suite doesn’t expand fast enough.  (Actually, I suppose no test suite expands fast enough, right?)

So I have a plan:  Embarcadero should open source their unit test suite and accept inputs from the community. 

Here’s why I think they should do that.

  • It will enable the community to expand the suite of tests -- As I noted above, every unit test suite is too small and doesn’t cover enough of the possibilities.  Embarcadero can continue to expand their test suite by themselves, or they can harness the power of the community to write tests.  The current public code repositories allow for forking and pull requests, and it would be dead simple for me or anyone to fork the project, add tests, and then issue a pull request.  This will allow people to write tests for their favorite parts of the RTL, and as will be discussed below, allow them to report bugs by writing tests that should pass but fail.  Many hands make for light work.
  • It will help build customer confidence in the quality of the Delphi RTL –A public facing, expanding suite of tests with community participation will build confidence in the quality of the product.  If people know and see that the RTL and the compiler are bathed in a complete, growing suite of tests, they’ll feel better about the product.  If they see how thorough and complete the suite is, they’ll know that the product they use is solid.
  • It will help people learn the proper way to use the product – One of the things that unit tests can do is to provide a sort of “documentation” for the things being tested.  They can illustrate the proper way to use the RTL code, and show customers the things that can be done that they might not have known about.  A nice suite of tests for a new RTL unit or class will help customers see how to use the class and what it is supposed to do.
  • It will encourage the team at Embarcadero to write more tests – When Lee Ioccoca took over a failing Chrysler in the late 1970s, one of the first things he did was throw down the gauntlet in front of the company: He would give all buyers a 10 year, 100,000 mile warrantee for the car.  That was an impetus to the entire company to improve quality.  Publishing the compiler and RTL test suites will have the same effect on the team at Embarcadero.  If the tests are public, then the team will feel the pressure (the good kind) to ensure that any new code has tests.  The community won’t want to see a new RTL unit without any tests (Will we, guys, right?)
  • It will enable people to report bugs in a better and more useful way – The easiest kind of bug to fix is one with a failing unit test.  If things got really rolling, customers could write unit tests that reveal bugs, Embarcadero could fix the bugs, and then the test would be a true regression test.  That would be awesome.  Customers could even use the tests to suggest fixes.  Having all the tests would enable them and Embarcadero to be more confident in a suggested fix.

I could think of some objections that they might have.  Here are some of those objections, along with reasons why those objections should be ignored. 

  • “The code isn’t ready for public consumption” – No one cares.  Seriously.  Anyone in the community that complains about the quality of the tests or lack of coverage can get to work and fix things.  No complaining if you aren’t helping.  The tests are probably better than most, and even if they are bad, they’ll get fixed. 
  • “It’s too much work for us” – No it isn’t. “We don’t have the time.” Yes you do.  It shouldn’t take more than an hour to gather the tests and post them on BitBucket or GitHub.  (Please, not SourceForge.  And by the way, whatever you do – for the love of Baby Elvis  -- don’t post it in Subversion. Only Git or Mercurial will allow for the community involvement you want and need.).  Plus, that small investment will enable an army of developers to submit pull requests with new tests.  Those tests can be quickly reviewed and accepted.  It will take less time to accept tests than it will to write them.  Shoot, you could even enlist trusted community members to help out.  I can think of at least one Embarcadero MVP (cough, me, cough) that would be willing to help be a gatekeeper.
  • “This is internal, private stuff that we shouldn’t be sharing”.  No, this is exactly the kind of stuff you should be sharing.  There are no trade secrets here.  The tests are useless without the products.  There is nothing to be lost by doing this, and much to be gained.  This is the kind of thing that a modern, forward-looking company would do.  Be a leader.  Be brave and bold!

I thought long and hard for reasons why Embarcadero shouldn’t open source their tests, and I couldn’t think of any.  Seriously, I can’t think of a downside here.

So how about it, guys?

Service Locator is Indeed an Anti-pattern

By Nick at June 05, 2013 21:20
Filed Under: Delphi, Software Development, Unit Testing, Patterns

As you know, I love Dependency Injection.  I wrote a whole series of articles on it using the Spring for Delphi framework, and in my previous position instituted its pervasive use in the large project there. I’m scheming to integrate it into the legacy app I work on now.  I bought and read the definitive book on the subject:

But there was always one thing that bugged me -- In Mark Seemann's book and in this article (Service Locator is an Anti-pattern) he argues against the use of a ServiceLocator – that is, a class that grabs instances out of the DI Container and hands them to you for your use.  I never really agreed, as I didn’t see any other way to do it – of course you needed to grab instances out of the container via a Service Locator pattern.  How else would you do it? I mean, you can do Constructor Injection and all, but at some point you need to grab an instance of something, right?  I had read his stuff, read the comments and arguments on the topic, but was never really persuaded.  But then again, maybe I was missing something.  The question of “how” always held me back.

Well, I was working on some demo code for my book, and out of the blue, all of a sudden, it hits me:  Seemann is right.  The ServiceLocator is an anti-pattern, mainly because it is pretty much unneeded. 

Here’s what happened. 

First thing: if you go to my demo code on BitBucket, you’ll see a Dependency Injection demo there that uses the ServiceLocator to grab instances of registered classes.  It’s cool – you can understand the basics of DI by looking at it.  You can properly decouple the code and end up with nothing but a unit of interfaces in your uses clause.  Nice.  I even did a CodeRage presentation using this basic code.  That code illustrates how you can use a DI Container and the ServiceLocator to create loosely coupled code.  No worries.  However, you’ll notice that the calls to the ServiceLocator kind of become replacements for calls to Create

Only you can do the same thing with no ServiceLocator calls. 

Second:  The Delphi Spring Container has a set of methods that I confess I never quite understood:

 

    function InjectConstructor(const parameterTypes: array of PTypeInfo): TRegistration<T>; overload;
    function InjectProperty(const propertyName: string): TRegistration<T>; overload;
    function InjectMethod(const methodName: string): TRegistration<T>; overload;
    function InjectMethod(const methodName: string; const parameterTypes: array of PTypeInfo): TRegistration<T>; overload;
    function InjectField(const fieldName: string): TRegistration<T>; overload;

 

These methods allow you to inject (duh) different items into your classes and automatically instantiate them as a result.  I knew they were there, I knew that they were useful, but I never understood completely why they were in there.  You could pretty much get along without them because you had the ServiceLocator to grab anything you need.  

I was reading Mark Seemann’s book again, and reading about how you should be using constructor injection everywhere, and how you need to push the creation of your component graph all the way back to the composite root. In Delphi, that means all the way back to the first line of the DPR file.  And if you do that, you could end up with this monster constructor that requires every single class your application needs.  And it was this notion that made me think “The ServiceLocator is necessary to get rid of that huge constructor.”

So I confess I never quite got it. 

But yesterday, I’m working on sample code for my book, and of course, I have to show how the above methods work.  I’m working up demos (I’ll show a simple one below that illustrates the whole thing) and it hits me:  The key to the whole notion of a ServiceLocator being an anti-pattern lies in what these five methods can do. 

And basically what they can do is this:  They can cause the creation of every single class needed for your application during the registration process.  They can completely eliminate the need for you to ever call the ServiceLocator (with one exception, discussed below) because if you can call the ServiceLocator, you can use these methods to register the connection between what you need the ServiceLocator for and the registration process.

Put another way, every call to the ServiceLocator can be replaced by a registration call.  You don’t need the ServiceLocator because the registration process alone is enough.

So I think a simple example is in order.  I’ll try to keep it short and sweet. 

Consider the following unit of code:

unit uNoServiceLocatorDemo;

interface

uses
      Spring.Container
    , Spring.Services
    , Spring.Collections
    ;

type
  IWeapon = interface
  ['{0F63DF32-F65F-4708-958E-E1931814EC33}']
    procedure Weild;
  end;

  IFighter = interface
  ['{0C926753-A70D-40E3-8C35-85CA2C4B18CA}']
    procedure Fight;
  end;

  TBattleField = class
  private
    FFighter: IFighter;
  public
    procedure AddFighter(aFighter: IFighter);
    procedure Battle;
  end;

  TSword = class(TInterfacedObject, IWeapon)
    procedure Weild;
  end;

  TKnight = class(TInterfacedObject, IFighter)
  private
    FWeapon: IWeapon;
 public
    constructor Create(aWeapon: IWeapon);
    procedure Fight;
  end;

implementation

{ TBattleField }

procedure TBattleField.AddFighter(aFighter: IFighter);
begin
  FFighter := aFighter;
end;

procedure TBattleField.Battle;
begin
  WriteLn('The Battle is on!');
  FFighter.Fight;
end;

{ TKnight }

constructor TKnight.Create(aWeapon: IWeapon);
begin
  inherited Create;
  FWeapon := aWeapon;
end;

procedure TKnight.Fight;
begin
  WriteLn('The knight swings into action!');
  FWeapon.Weild;
end;

{ TSword }

procedure TSword.Weild;
begin
  WriteLn('"Swoosh" goes the sword!');
end;

initialization

  GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
  GlobalContainer.RegisterType<TKnight>.Implements<IFighter>('knight');


end.

 

Here we have some classes that are all nicely decoupled.  Our registrations are neatly named.  The classes use constructor injection to ask for their dependencies, and the TKnight and the TSword are nicely registered, just waiting to be grabbed and used in a decoupled way using the ServiceLocator.  All is great.  And then in order to actually have our cast of characters do anything, you might do something like this:

 

procedure FightBattle;
var
  Battlefield: TBattleField;
  TempKnight: IFighter;
  TempSword: IWeapon;
begin
  Battlefield := TBattleField.Create;
  try
    TempKnight := ServiceLocator.GetService<IFighter>;
    TempSword := ServiceLocator.GetService<IWeapon>;
    TempKnight.Weapon := TempSword;
    Battlefield.AddFighter(TempKnight);
    Battlefield.Battle;
  finally
    Battlefield.Free;
  end;
end;

 

You need a knight and a sword?  Well, just call the ServiceLocator, grab the sword, arm the knight, add him to the battle, and off it goes.  You get this:

image

 

It all works, and it is all decoupled.  But you are still using the ServiceLocator

The argument against the ServiceLocator is pretty simple: It’s a singleton, singletons are global variables, and global variables are bad. (That’s a gross oversimplification – read the article and the comments for a better discussion….) Plus, if you don’t need it, why use it?

Well, you don’t need it.  Watch.

First thing to note is that Seeman says you should have one call to the ServiceLocator at the very root of your application.  You get one shot.  We’ll see that one shot below.

Second, let’s change how we register our classes and interfaces: 

 

  GlobalContainer.RegisterType<TBattleField>.InjectMethod('AddFighter', ['knight']);

  GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
  GlobalContainer.RegisterType<TKnight>.Implements<IFighter>('knight').InjectConstructor(['sword']);

 

Some things to note:

  • We only changed the way things were registered.  We didn’t change the class structure or relationships at all.
  • We are now registering TBattlefield.  We need to do that for two reasons.  First, in our very simple example, it is the “root” of the application.  It is the place where everything starts in relation to our object graph.  To get an instance of TBattlefield, we make our one allowable call to ServiceLocator.  Second, we need to inject a method, as discussed next.
  • Into TBattleField we have injected a method, specifically the AddFighter method.  Here’s what the call to InjectMethod does -- it says “When the container creates an instance of TBattlefield, look up the AddFighter method and pass to it as its parameter an instance of the interface named ‘knight’”  Thus, when the container creates an instance of TBattleField for you, the AddFighter method will be automatically called, and a valid weapon will be passed to it.  There goes one call to the ServiceLocator
  • The second call to ServiceLocator is eliminated by the call to InjectConstructor.  This registration now means “When you ask for an IFighter, create an instance of TKnight, and when you do, pass the constructor an IWeapon from the registered type named ‘sword’”  Again, there goes the other call to ServiceLocator

Thus we’ve used the container to “wire up” all the dependencies and ensure that they are properly created before the main class or any other class is even asked for.  The call to GlobalContainer.Build in the DPR file will ensure this takes place. 

Finally, we run everything with the much simpler and cleaner:

 

procedure FightBattle;
var
  Battlefield: TBattleField;
begin
  Battlefield := ServiceLocator.GetService<TBattlefield>;
  try
    Battlefield.Battle;
  finally
    Battlefield.Free;
  end;
end;

 

And there’s our one call to ServiceLocator at the very root of our application (FightBattle gets called in the DPR file as this is a console application). 

You can do the same thing with constructors – you can call InjectConstructor, passing the names of registrations for each of the parameters in the constructor.  And if need be, for both InjectConstructor and InjectMethod, you can add in non-registered parameters such as integers and strings, etc.

Bottom line:  Use the injection methods and the container to connect up your classes and inject dependencies, not the ServiceLocator. 

And I haven’t even yet mentioned how you can replace the InjectXXXXXX calls with attributes. 

Okay, now I feel better since I agree with Mark Seemann over at http://blog.pleoh.dk.  Being in disagreement with a smart guy like that isn’t a comfortable place to be. 

THMTLWriter and XE4

By Nick at May 18, 2013 09:55
Filed Under: Delphi

I’m happy to say two things:

  • I’m still alive.  I can’t believe that it has been over two months since I posted. I have been working on my book, but it is sure slow going.  Writing is hard, as my wife says.
  • THTMLWriter works great with Delphi XE4. I’d be delighted to hear from you if you are using it.  And if you haven’t given Delphi XE4 a look, please do.  And use that link up there.  Please.

My Book

A Pithy Quote for You

"If we seek merely swollen, slothful ease and ignoble peace, if we shrink from the hard contests where men must win at the hazard of their lives and risk all that they hold dear, then bolder and stronger peoples will pass us by, and win for themselves the domination of the world."    –  Theodore Roosevelt

Amazon Gift Cards

General Disclaimer

The views I express here are entirely my own and not necessarily those of any other rational person or organization.  However, I strongly recommend that you agree with pretty much everything I say because, well, I'm right.  Most of the time. Except when I'm not, in which case, you shouldn't agree with me.

Month List