New Castle Windsor feature – typed arguments

With Windsor 2.1.1 out the door, we’re already working on version 3.0 (and looking for your feedback and ideas for the next version!). Yesterday I committed first “big” feature that probably will make it to the release.

DISCLAIMER:

All the code shown here represents a work in progress. Keep in mind that final version may be different. This also means that any feedback on this feature is appreciated.

Named Arguments

In current version of Windsor you can define inline dependencies for a component in at least three different ways:

  • When registering it (with value obtained at registration time):
    container.Register(
        Component.For<ICustomer>()
            .ImplementedBy<CustomerImpl>()
            .DependsOn(
                Property.ForKey("Name").Eq("Caption Hook"),
                Property.ForKey("Address").Eq("Fairyland"),
                Property.ForKey("Age").Eq(45)
                )
            );
  • When registering it (with value obtained at resolution time), AKA – Dynamic Parameters
    container.Register(
        Component.For<ClassWithArguments>()
            .LifeStyle.Transient
            .DynamicParameters((k, d) =>
            {
                d["timeStamp"] = DateTime.Now;
                d["user"] = Thread.CurrentPrincipal.Identity;
            })
        );
  • When resolving it (although this is something you should strive to avoid, using constructor injection and/or Typed factory facility)
    var component = container.Resolve<ClassWithArguments>(new
    {
        TimeStamp = DateTime.Now,
        User = Thread.CurrentPrincipal.Identity
    });

 

 

What all these approaches have in common is that you specify dependency by name. Windsor when resolving the component will then use the value you provided for constructor arguments or settable properties with that name it finds on the component. What if you don’t care about the name?

Typed Arguments

Trunk version of Windsor lets you do just that – omit the name in which case Windsor will use the type of the argument as the sole information when building your component.

container.Register(
       Component.For<ClassWithArguments>()
           .Lifestyle.Transient
           .DependsOn(
              Property.ForKey<DateTime>().Eq(DateTime.Now),
              Property.ForKey<IIdentity>().Eq(Thread.CurrentPrincipal.Identity))
    );

 

As you can see here we use the type as the key for the dependency. This works also with dynamic parameters as well as when passing arguments straight from the call site. A new class – Arguments has been introduced to accommodate this new feature (although ordinal Hashtable or Dictionary<object,object> will do just fine as well) .

container.Resolve<ClassWithArguments>(
    new Arguments(new object[]
    {
        DateTime.Now,
        Thread.CurrentPrincipal.Identity
    })
);

The Arguments class itself implements IDictionary and can wrap either another IDictionary containing either named or typed arguments, anonymous type containing named arguments or array of objects to be used as typed arguments. It is advised to use this type when you plan to use typed arguments.

Additionally to help you deal with filling the dictionaries in more usable fashion an extension method on IDictionary (so they work for Arguments type as well) called Insert (with few overloads) has been introduced. It lets you insert arguments in a fluent, more user friendly fashion.

container.Register(
    Component.For<ClassWithArguments>()
    .DynamicParameters((k, d) =>
        d.Insert(DateTime.Now)
        .Insert(Thread.CurrentPrincipal.Identity))
    );

Final words

While this may be appealing at first to use typed arguments everywhere, resist the temptation unless you have a good reason. Named arguments should always be your first choice. Name is a valuable contextual information that may improve the readability of your code. Windsor will favor named arguments over typed and use the latter only if it can’t find a matching named argument.


Posted 02-15-2010 6:09 PM by Krzysztof Koźmic
Filed under:

[Advertisement]

Comments

Alwin wrote re: New Castle Windsor feature – typed arguments
on 02-15-2010 5:34 PM

Yay, looks good.

Does this work with both properties and service overrides?

Blair wrote re: New Castle Windsor feature – typed arguments
on 02-21-2010 10:09 PM

Whats the difference between Parameters Method and DependsOn ?

Krzysztof Koźmic wrote re: New Castle Windsor feature – typed arguments
on 02-22-2010 3:59 AM

Blair

RTM: using.castleproject.org/.../Fluent+Registration+API

basically Parameters is a thin layer on top of XML config and as such is limited to strings. In 99% cases you don't want to use it.

Krzysztof Koźmic wrote re: New Castle Windsor feature – typed arguments
on 02-24-2010 4:51 PM

Alwin,

it does not work service overrides.  There's a very good reason for that though!

I forgot.

I'll add this to TODO list.

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)