Windsor will stitch together objects for you at runtime based on what components have been registered.  When you ask for an instance of an object from the Windsor/MicroKernel it will return the object using the constructor it can satisfy.

I ran into a problem the other day when I wanted to create an object that accepted three types, the third was a non-primitive that I didn't control.  Castle's website goes into some detail on this in their documentation on Windsor/MicroKernel:

   1: <configuration>
   2:  
   3:     <components>
   4:         <component id="smtp.sender" 
   5:             service="Namespace.IEmailSender, AssemblyName"
   6:             type="Namespace.SmtpMailSender, AssemblyName">
   7:         
   8:             <parameters>
   9:                 <port>10</port>
  10:                 <host>smtphost</host>
  11:             </parameters>
  12:         
  13:         </component>
  14:     </components>
  15:  
  16: </configuration>

the problem I was running into is what if you have a third parameter, which isn't a primitive?  I have the following signature:

   1: public CommunicationGateway(string host, int port, Encoding encoding)
   2: {
   3:     this.host = host;
   4:     this.port = port;
   5:     this.encoding = encoding;
   6: }

The example above fits quite nicely until I hit the third parameter.  How do I define what that third parameter should be in Windsor given that it's not a class that I control nor a primitive type? This felt like it should be easy, but I could not find the information I needed on the Castle website.  I got some help from Castle committer Dru Sellers.  In the end Dru pointed me to a very simple solution; register the type and pass it in using the service lookup notation, ${}

   1: <component id="CommunicationGateway"
   2:            service="ABCCompany.ICommunicationGateway, ABCCompany"
   3:            type="ABCCompany.CommunicationGateway, ABCCompany">
   4:     <parameters>
   5:         <host>#{Host}</host>
   6:         <port>#{Port}</port>
   7:         <encoding>${Encoding}</encoding>
   8:     </parameters>
   9: </component>
  10:  
  11: <component id="Encoding"
  12:            service="System.Text.Encoding, mscorlib"
  13:            type="System.Text.UTF8Encoding, mscorlib">
  14: </component>

You can see from above that I'm registering a component with the service System.Text.Encoding and supplying UTF8Encoding as the implementation.  Now I can use a strongly-typed System.Text.Encoding object and have it configurable in my Windsor Configuration, much more elegant than using a string (primitive-type) and hoping it works. 

Thanks Dru!


 
Tuesday, October 07, 2008 8:26:04 PM (Central Standard Time, UTC-06:00)
What is "<port>#{Port}</port>" in the last part of your post?
Comments are closed.