Saturday, October 22, 2011

CodeRage 6 feedback and DSharp news

I think Code Rage 6 had interesting stuff for almost everyone. Thanks to the time difference I could watch the sessions live that interested me most at home after work (as I was also very interested in the Q&A):

LiveBindings (Jim Tierney)

You know I have been complaining about the LiveBindings much in the past. So the questions I had prior to these sessions were: Did I miss something when I started working with them that affected my opinion so negatively and what is the general opinion about those bindings (as the reaction of other people)?

Jim started with some console applications explaining the expression framework beneath the LiveBindings. This session was very interesting and actually motivated me putting some work into the DSharp expressions to use them in the bindings (as I started developing those after I created the bindings). More about that later.

The other two sessions actually had no surprises for me. In fact the Q&A was more interesting. Unfortunately I forgot to save the log so I have to recapitulate that from memory.
Someone asked the question I was expecting: Why using LiveBindings over the traditional way since it looks very complicated setting them up (especially when working with grids and lists). It may be just my point of view but Jim did not have the killer argument. Sure, he mentioned the separation of GUI and BL but hey it is more than that.
If easy and painless to configure bindings can completely take care of your data flow. You just have to care about computing it. Think about how much code you have written in the past to show data, get it from one place to another and much more. Almost all of that code can be removed with a good binding system or at least moved to another place where it is not in the way. When asked about things like property references his answer saddened me - there are no plans for something like that. I still hope he just did not know about it.

Dependency Injection and Unit Testing (Nick Hodges)

On Wednesday I was excited about Nicks sessions and I have to say it again: very well done, Nick! I think these two sessions got people interested in learning more about dependency injection and as I have said in the past: recent releases since 2010 (with introducing the enhanced RTTI) over XE (first version that I did not want to throw out of the window when heavily using generics) to XE2 (more bugfixes and more features for the RTTI like virtual interface - also more on that later) gave us the possibilities other languages as C# or Java have had for ages. Using modern developing techniques to be more productive and raise the code quality.

His second session was about unit testing and I have to admit, I often am more excited about implementing new things instead of testing some existing things. That often has to do with hard to test code (like existing code that respects no clean code rules and is a total mess and has dependencies all over the place). When writing code with testability in mind it actually is fun to write tests, refactor your code and find eventual mistakes within seconds. But what about more advanced unit testing frameworks in Delphi? DUnit has been around for years and with new techniques there is also the need for a more advanced unit testing framework. There are several projects around and as Nick already mentioned it would be great to get the people together to build something great for the community. I just recently read about JBehave and immediately liked the idea.

Also with the possibility to use mocks (I am still a bit jealous that Delphi Mocks by Vincent Parrett is mentioned so often compared to DSharp) there are many ways to use the new features we got in the past 2 years.

RTTI (Robert Love)

As I have been exploring the RTTI since its release Robert could not tell me anything new but his sessions actually were very interesting and inspiring to those that have not touched the RTTI yet or at least not much. There are so many ways using it and actually I already cannot think of living without them.

Actually I found something on friday that was strange - especially with having in mind what Nick did. He put an entire class into the implementation part of a unit registering it to the container in the initialization part of the unit. I mentioned the dependency on the container in that case and tried something else: using TRttiContext.GetTypes to iterate all known types looking for attributes that tell to register that type. But it did not list the class in the implementation part of the unit. The class was not thrown out by the smart linker because it was actually used. It just seems to be the case that GetTypes does not find any types in the implementation part while GetType(...) works.

New things in DSharp

You might have noticed a lot of commits in the DSharp svn repository recently. I have refactored the collectionview classes (those responsable to bind lists of objects to controls) and added some more presenters to work with the DevExpress controls (grid and treelist). The expressions that started as experiment have been improved and are part of the binding framework now. I also moved some units to their own namespace (logging and aspects). And as I mentioned earlier one feature I am very proud of:

DSharp got full AOP for interfaces.

Some weeks ago I implemented AOP for virtual methods that made it possible to patch the VMT of any class at runtime making it possible to inject aspects into every instance of a class, its descendants and every new created class automatically. With the new classes and with support for attributes it is possible to declare aspects and apply them to virtual methods, interface methods and entire interfaces and classes.

I will explain that in detail in a following article as I am currently working on an adapter for the spring DI container to work with my composition and  presentation model which I also will explain in detail soon. For now you can check out the sample and see how easy it can be using aspects like logging on your interfaces, implementing it once and using it everywhere without writing any line of code (well, except the attribute)!

Friday, October 7, 2011

Supports killing objects

Today I had a really bad "d'oh!" moment... feel free to laugh at me because I did not know better. ;)

You all may use the Supports routine - so did I without further thinking about it - until today. I shamefully have to admit that I should have looked at its code and/or the documentation earlier.

What happened? In my bindings I check the source and target objects for special interfaces (f.i. INotifyPropertyChanged). I changed some code and strange things started happening in form of access violations. So I quickly found out that the Supports call caused a Destroy on the object when it did not support the given interface. Looking at the source revealed why: Supports does not only call GetInterface with the given guid, no it also does it for IUnknown causing _AddRef and _Release calls. And we know how that ends on some refcounted object that has the initial refcount of 0.

Actually there is a comment saying: "NOTE: Calling this overload on a ref-counted object that has REFCOUNT=0 will result in it being freed upon exit from this routine." And the documentation says: "Warning [...] For objects that have a reference count of zero, this will result in the object destruction."

Just another reason why Delphi sometimes is a pain in the ass if you are using object references and interfaces. Some may say: "Just use interfaces!" No, I do not want to write interfaces for simple data objects and other things. But I want to use interfaces for certain aspects (f.i. INotifyPropertyChanged). And most important: I do not want my objects getting destroyed if they DO NOT implement the requested interface.

Actually I have no idea why this was implemented like this long ago. Anyway I wrote my own Supports overload now:

function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean;
  Result := Assigned(Instance) and Instance.GetInterface(IID, Intf);

If your instance is assigned for sure you just might call the GetInterface method. I know there might be cases where the other Supports returns true and this one not like when having a customized QueryInterface. But in my cases it should solve my problem of instances getting shot in the head by the Supports call.

Let me know if I missed something about this implementation.