views:

84

answers:

1

I am calling Kernel.RemoveComponent on my Windsor container and it is returning false. I know the component is present (I have verified by calling GetHandler with the same key and it returns the expected info)...so why can't I remove my component from the container? How can I troubleshoot this?

I have a bunch of authentication and authorization that happens in independent handlers and components in my WCF services before the OperationContext is established (OpertaionContext.Current is still null). During this period, I need access to the request message from the request context. I'd like to store the RequestContext instance in my container with a per-thread lifetime. Upon each new request, I need to overwrite this instance so I don't retrieve the wrong request message. Is this simply not a good task for Windsor? If I can't remove the component before re-registering each new RequestContext, then all of the RequestContexts will never get disposed, right?

Thanks!

+1  A: 

RemoveComponent will not remove the component if there are other components depending on it. Why are you removing the component instead of not putting it in the container in the first place?

Krzysztof Koźmic
I want my container to automatically try to remove an existing component if a duplicate/conflicting component is registered instead of throwing an exception. For example, I have a TraceLogger class which is the default ILogger. Further down the road after the app starts up, I want to replace that registration with a DBLogger ILogger, which has some custom Activator and some other special properties. What I register my DBLogger, I want the container to try to remove the TraceLogger first so no error is thrown.
JeffN825
This does not sound right. Why are you changing container after it's set up? Why not have them both in the container and if you need to pick one, use `IHandlerSelector` or `ISubDependencyResolver`?
Krzysztof Koźmic
It doesn't sound right that the behavior of a service should be able to change after start up? Or it doesn't sound like the right approach to unregister the previous implentation before providing a new one? If the former, why? I can think of tons of situations where I would want dynamic service behavior. Why does having a default ILogger, overridden at a later time not make sense? Thanks.
JeffN825
Why would it make sense? I can think of no scenario for this. And if you need dynamic behavior for cases like multi tenancy or similar, there are plenty other solutions than yanking a component out of the container. That's for really rare scenarios - I didn't need to do this ever, and my gut feeling is - in your case it's not the best solution either.
Krzysztof Koźmic
I'm not trying to argue about this...I'd genuinely like to understand what better approaches there may be, and I'm certainly open to suggestions. Let's take my specific scenario, where, on the client (WPF), I want to log to a DB via WCF calls with my DBLogger. But I can't make these WCF calls until the user has logged in and the remote connections have been initialized. I still need logging during this startup period, so I want to use my TraceLogger. How would you propose to implement this? Using a HandlerSelector? Or should I take another approach altogether?
JeffN825
Also, just to add one thing, I am indeed writing a multi-tennant client server application.
JeffN825
Yes - handler selector is indeed recommended solution for situations like this. Check this post for a sample: http://ayende.com/Blog/archive/2008/10/05/windsor-ihandlerselector.aspx and the doco: http://stw.castleproject.org/Windsor.Handler-Selectors.ashx
Krzysztof Koźmic
In addition if you're using framework like log4net IIRC you can have the same instance of logger log to trace and then reconfigure the logger dynamically to log to DB (or both).
Krzysztof Koźmic
Ok, I'm back :). So, I've run into this situation again. Please see edited question above.
JeffN825
How do you access the context?
Krzysztof Koźmic
I have a RequestInterceptor (from the WCF REST Starter Kit) which allows me to intercept the message very early in the request (before the message is deserialized or security is processed), via a custom channel (RequestInterceptorReplyChannelListener).
JeffN825
So, I went ahead and implemented this effectively by scoping each client request within a child container that has its own per-thread RequestContext instance. That's said, given your (@ Krzysztof) comments on Child Containers on your blog I'd be very interested in your thoughts on a more appropriate solution.
JeffN825
You could probably try to build a better suited LifestyleManager. That's the most commonly used and the most robust solution for these kinds of problems.
Krzysztof Koźmic