Resolving components dynamically based on name

35 views
Skip to first unread message

Tomek Pluskiewicz

unread,
Dec 31, 2012, 4:13:50 AM12/31/12
to Castle Project Users
Hi

I have a seemingly simple use case. There is a ICsvReader component.
Let's name it simply Reader here. We load a known set of CSV files and
some of them have headers and some don't. Currently there are multiple
readers: Reader_Skips1Row, Reader_Skips2Rows etc.

Is there a way to register only one component and have Windsor look at
the component key, strip the "_Skips..." part and resolve the required
component with relevant properties set?

I have tried subresolver and facility with no luck.

Thanks,
Tom

Patrick Steele

unread,
Jan 2, 2013, 8:58:49 AM1/2/13
to castle-pro...@googlegroups.com
If you only have one implementation of ICsvReader registered then any component that depends on an ICsvReader will get that one component (assuming it's being resolved via Windsor).

I guess I'm confused because you said you have multiple implementations of ICsvReader but you only want to register one of them.  Could you give a code example of how you'd like your code to look like in terms of registration and component resolution?

--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.


Tomek Pluskiewicz

unread,
Jan 2, 2013, 10:43:46 AM1/2/13
to castle-pro...@googlegroups.com
Hi

Yes there is only one implementation but it is used as a dependency and configured to be resolved by name. The reader is configured in code

Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.DependsOn(new { SkipHeader = true, HeaderRowsToSkip = 2 } )
.Named("CommaSeparetedCsvReader_Skips2Rows")
.Lifestyle.Transient

Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.DependsOn(new { SkipHeader = true, HeaderRowsToSkip = 1 } )
.Named("CommaSeparetedCsvReader_Skips1Row")
.Lifestyle.Transient

Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.Named("CommaSeparetedCsvReader")
.Lifestyle.Transient

These are used as dependency in a processor class. It is configured in XML, so that in can be manipulated at runtime

<component id="Processor 
   type="Processor">
   <parameters>
      <reader>CommaSeparetedCsvReader_Skips2Rows</reader>
   </parameters>
</component>

Ideally I would like to register only the CommaSeparetedCsvReader component but when an attempt is made to resolve CommaSeparetedCsvReader_Skips2Rows it should strip the suffix, parse it and change the properties accordingly. 

Is it possible to somehow modify the Resolve() behavior?

Thanks
Tom
To unsubscribe from this group, send email to castle-project-users+unsub...@googlegroups.com.

Patrick Steele

unread,
Jan 2, 2013, 11:18:07 AM1/2/13
to castle-pro...@googlegroups.com
I think a Handler Selector would work in this case:

http://docs.castleproject.org/Windsor.Handler-Selectors.ashx


To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.

Tomek Pluskiewicz

unread,
Jan 3, 2013, 8:40:23 AM1/3/13
to Castle Project Users
Thanks

I have already seen IHandlersSelector. After I have chosen a handler
how can I inject the dependencies extracted from the requested
component name? I tried to return a fresh instance of IHandler but I
had problems with initializing it properly. First I needed
IKernelInternal. Having supplied it then it seems that ComponentModel
is incomplete and has no constructors. This one I'm not sure how to
populate.

I did however managed to implement a IHandlersSelector in a hackish
way. When a recognized component key is requested I parse it to
extract the dependency values and register a new component with
IKernel. The gotcha is that a check must be made to ensure that
registration hasn't been made already. Otherwise
StackOverflowException is thrown.

Is this a terrible usage or is that the only way to dynamically
register components at resolve-time?

Regards,
Tom

On 2 Sty, 17:18, Patrick Steele <patrick.ste...@gmail.com> wrote:
> I think a Handler Selector would work in this case:
>
> http://docs.castleproject.org/Windsor.Handler-Selectors.ashx
>
> ---
> Patrick Steelehttp://weblogs.asp.net/psteele
> >>> To post to this group, send email to castle-pro...@**googlegroups.com.
>
> >>> To unsubscribe from this group, send email to castle-project-users+**
> >>> unsub...@googlegroups.com.
> >>> For more options, visit this group athttp://groups.google.com/**
> >>> group/castle-project-users?hl=**en<http://groups.google.com/group/castle-project-users?hl=en>
> >>> .

Ken Egozi

unread,
Jan 3, 2013, 11:48:11 AM1/3/13
to Tomek Pluskiewicz, Castle Project Users
The idea is to have all components registered beforehand, then let the
ihandlerselector choose the right ones in resolve time based on some
transient context

Sent from my Red Lumia 920 From: Tomek Pluskiewicz
Sent: ‎1/‎3/‎2013 5:40 AM
To: Castle Project Users
Subject: Re: Resolving components dynamically based on name
To post to this group, send email to castle-pro...@googlegroups.com.

Tomek Pluskiewicz

unread,
Jan 3, 2013, 12:49:28 PM1/3/13
to Ken Egozi, Castle Project Users
Ken,

So I assumed. In that case I think I will stick to a facility to
automatically register the expected parametrized components or some
kind of a factory (method).

Thanks fo help
Tom

On Thu, Jan 3, 2013 at 5:48 PM, Ken Egozi <ego...@gmail.com> wrote:
> The idea is to have all components registered beforehand, then let the
> ihandlerselector choose the right ones in resolve time based on some
> transient context
>
> Sent from my Red Lumia 920 From: Tomek Pluskiewicz
> Sent: 1/3/2013 5:40 AM
Reply all
Reply to author
Forward
0 new messages