May 22, 2008

Where do you search for .Net tools?

Hi. This will be a very short, but I hope useful, post! Of course I usually do a google search when I want to find some system/programing tools. Also I do keep an eye on some pretty helpful sites:
  • The Free Country (www.thefreecountry.net)
  • Source Forge (www.sourceforge.net)
  • Codeplex (www.codeplex.com)
  • Fresgmeat (freshmeat.net/)
One site that I really like when I want anything related to .Net is sharptoolbox (sharptoolbox.com). If you are a .Net developer you should take a serious look into this site. Which sites do you visit to get system/programing tools? Adriano

May 15, 2008

Usefull firefox trick

There is one little trick in Firefox that few people I know are aware of: It's possible to create "shortcuts" in order to make it easy to browse for sites that accepts inputs.

As an example let's take the free dictionary, very nice (guess what ??) dictionary site :)

When you browse to www.tfd.com and enter a word to search it navigates to www.tdf.com/word.

In Firefox we can add a shortcut so we can speedy our browsing experience. See the example below

Instead going to the TheFreeDictionary site and then typing the word we want to look for (for instance, cake), just type tfd cake in firefox address bar! Simple like that! :)

In order to make this work we need to tell firefox that we want a shortcut named tfd (you can name it at your will) and that it must navigate to www.tfd.com/whatever-we-type-in-address-bar.

To do this, open bookmark manager (CTRL-B) add a new bookmark as follow:

(note the url: http://www.tfd.com/%s)

Press Add and you are done! Now just type tfd cake on firefox address bar!

Adriano

May 14, 2008

Type safe / refactor friendly configuration for Db4o - Part II

In my last post I proposed to derive field names from a property accessor in order to gain type safety and compiler support when configuring some aspects of D4bo.

So, given the following class:

public class Test
{
   private int _age;
   public int Age
   {
      get { return _age; }
      set { _age = value; }
   }
}
we could use the following code:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectField((Test t) => t.Age).Indexed = true;
instead of:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
to configure a field to be indexed. The first step to use this syntax is to be able to figure out the property being accessed. To demonstrate how this can be done let's write a simple function that takes advantage of C# Expression Trees:
public string GetPropertyName<T,R>(
               Expression<Func<T,R> exp)
{
  // Get the property name here.
}

public static void Main()
{
   string s = GetPropertyName((Test t) => t.Age);
}
When compiling the above code, the C# compiler will create an expression tree representing our lambda expression ( (Test t) => t.Age) and pass it along to GetPropertyName() function.

Inside this function we can just use the Body property (which in this case represents t.Age part of our lambda expression) and cast it to MemberExpression. Now all we have to do is to consult MemberExpression.Meber.Name property:

public string GetPropertyName<T,R>(
               Expression<Func<T,R> exp)
{
    MemberExpression me = fieldExp.Body as
                             MemberExpression;
    if (me == null) return "na";

    MemberInfo m = me.Member;
    return m.DeclaringType.FullName + "." + m.Name;
}

At this point we are able to figure out the name of the property being accessed! If you take a deeper look into me.Member we will see that it is a PropertyInfo instance where you can get a lot more information about the property.

In the next post I'll dig a little bit deeper and investigate how we can select a field based on the property being accessed ;)

Thoughts?

Adriano

May 10, 2008

Linq Console Update

Hi! I've just updated the Linq Console application! Now you don't need to copy your model assemblies to Linq Console folder anymore! You can use the load command as follow: :load "c:\my projects\test\Test.Model.dll" and the application will be able to load it :) The source code can be downloaded from our svn server: https://source.db4o.com/db4o/trunk/sandbox/rodrigo/NonOptimizedLinqSpikes/LinqConsole/ Adriano

May 1, 2008

Type safe / refactor friendly configuration for Db4o

As of today, Db4o uses strings to reference fields in some scenarios such:
  • SODA queries
  • Configuration

See the sample bellow:

IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
IMHO, using strings in these situations is sub-optimal as:
  • Such solution relies in internal class details (field names)
  • Compiler can't check whenever the field actually exists.
  • We don't take advantage of modern IDE's refactorings so, chances are that these entities and references to them get out of sync breaking your code; it's even worst because you will figure it out only at runtime :(; it may even get unnoticed as Db4o is completely happy with some invalid field names.
With the introduction of C# 3.0 and its automatic properties we have another issue: we don't even know the field's name used to back the property! Sure, we can cheat by using some tool like reflector or ildasm to figure it out but this would be a fragile solution as C# compiler may choose whatever name it wants, so it may choose different names schemas in the future and we don't want to get our code breaking when new C# compilers come out, do we?

I do believe that this approach was chosen due to technical limitations at the time the code was written, but now, with the debut of C# 3.0 and its new features like extension methods, lambda expressions, expression trees, etc. I bet we can do better :).

To be fair, we've already been improving (removing) some string usages, for instance, Linq / Native Queries uses strong typing instead of strings to reference fields (under the hood they generate SODA queries that still use strings, but the crux here is that these "names" will always be in sync with its entities).

One area that, in my opinion, can be improved is configuration. For instance, in order to setup indexes, deletion behavior (when to cascade delete), etc. we still use strings to identify the field we want to apply the configuration. Suppose we have the following code to configure indexes:

IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
We could introduce new methods to IConfiguration interface so one would be able to do something like this:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectField((Test s) => s.Age).Indexed = true;

Wow! Using this syntax we no longer have issues with refactorings, abusive internal class knowledge and we get compiler time support for free :) (for instance, if we mistype "s.Afe" C# compiler will complain).

To be fair, we have some issues with refactorings. If we change field/class's name we need to inform Db4o about this changes as explained here (I do have some ideas on how to express these calls also but this is a little bit more complex topic that I won't cover here).

What do you think?

In a following post I'll discuss how we could implement this new configuration method. Go to part II of this post. Adriano

10 years ago....

------------------------------ Warning: Personal post :) ------------------------------
Well, ten years ago (may, 1, 1998) I got married to Gislene, my wife :) 


Since then, she has been helping me, providing me advice, being patient with me and loving me! 
Gislene, thanks for all these years! I hope (and will do my best) to be at your side for the next 10 years, then for the next 10 and so on. 


I couldn't finish this without saying.. Gislene, I love you! 


Adriano