Check if Windsor has a matching component registered - castle-windsor

In a Castle Windsor scenario I want to check if my container has a certain service registered, and do basically
if (container.HasComponentFor<IMyService>()) {
// resolve service with container.Resolve<IMyService>()
// then do cool stuff
}
but of course, container.HasComponentFor<IMyService>() doesn't exist. Is there an equivalent?

You can check if the MicroKernel has the component registered:
if (container.Kernel.HasComponent(typeof(IMyService)))
// resolve service with container.Resolve<IMyService>()
// then do cool stuff
}

You could try container.Kernel.HasComponent()

Related

Resolving a dependency while supplying values for downstream dependencies

I've been running into endless problems attempting to use Windsor with Web API and injecting HttpRequestMessage into downstream dependencies of a controller. Since I've tried all the matching answers on Stackoverflow, I'd like to ask the question in a different way:
In Castle Windsor, how can I resolve a component instance while supplying a value for a downstream dependency? That is, the supplied value is required by a component that is required by the component being resolved.
For context, I'm trying to inject HttpRequestMessage so that I can use it to resolve the request context (primarily to resolve an absolute URL).
Edit I'd also like to point out that I don't currently have a dependency on Web Host / System.Web and I'd rather not change that.
A proper approach is to
Create IMyDesiredRouteParameterProvider
Implement it. Get the current request inside it and get the url
Register it and inject it in the desired dependent class via constructor.
I made myself such an implementation and I can say that this way it works fine. You can make Web.Infrastructure assembly and put the implementation there. Or put both the interface and the implementation there if you are going to reference it from another web module.
using System;
using System.Web;
namespace RouteParameterProvider
{
interface IMyRouteParameterProvider
{
string GetRouteParameter();
}
public class ControllerActionMethodRouteParameterProvider : IMyRouteParameterProvider
{
public string GetRouteParameter()
{
string Parameter = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"] as string;
if (string.IsNullOrEmpty(Parameter))
{
throw new InvalidOperationException();
}
return Parameter;
}
}
}
You can get every possible thing that the Request Context contains from :
HttpContext.Current.Request.RequestContext
And it will be better if you rethink your design decision :
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
Containers are to be initialized at runtime and then used to resolve.
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
It sounds like you want to register an item with the container at runtime, post-startup. In general, this is not a good practice--registration should be a discrete event that happens when the app is fired up, and the container's state should not be changed during runtime.
Dependency Injection is about resolving service components, not runtime state--state is generally passed via methods (method injection). In this case it sounds like your LinkGenerator component needs access to the ambient state of the request.
I'm not that familiar with HttpRequestMessage, but this answer seems to show that it is possible to retreive it from HttpContext.Current. You could make this a method on your LinkGenerator class, or wrap this call in a separate component that gets injected into LinkGenerator (HttpRequestMessageProvider?). The latter would be my preferred method, as it allows LinkGenerator to be more testable.
Given the lack of a clean way of doing this and Web API not providing information as to the hosted endpoint beyond per-request context objects, I ended up injecting the base url from configuration.
Is this library by Mark Seemann the answer? In the description he writes explicitly :
This approach enables the use of Dependency Injection (DI) because the
request can be injected into the services which require it.
Then gives an example :
// Inside an ApiController
var uri = this.Url.GetLink(a=> a.GetById(1337));
By which you can then pass the URL down the road in the service that you have injected in the controller.
UPDATE :
Mark Seemann wrote about the same exact problem here:
"Because HttpRequestMessage provides the context you may need to
compose dependency graphs, the best extensibility point is the
extensibility point which provides an HttpRequestMessage every time a
graph should be composed. This extensibility point is the
IHttpControllerActivator interface:..."
This way you can pass request context information to a component deep in the object graph by getting from the HttpRequestMessage and passing it to the DI container.
Just take a look at the interface of IHttpControllerActivator.
The WEB API framework gets the IHttpControllerActivator through DependencyResolver. You probably already replaced it by your CastleWindsorDependencyResolver. Now you have to implement and register your HttpControllerActivator and register it.
When the WEB API framework gets IHttpControllerActivator from DependencyResolver (your Castle Windsor DR) and calls IHttpControllerActivator.Create() it will pass you the HttpRequestMessage. You can get your info from there and pass it to the your CastleDR before you call Resolve(typeof(MyController)) which will resolve the whole object graph - that means you will have MyHttpContextInfo to inject in your XYZComponent deep in the resolution stack.
This way tou are passing the arguments in the last possible moment but it is still possible. In Castle Windsor I make such passing of arguments though CreationContext.AdditionalArguments["myArgument"];.

Castle Windsor: Can I get all instances of a type?

I am registering a bunch of ITask implementations with Windsor using Named to separate them. Is there a way a class can request all instances of ITask?
Windsor can do what you request via the CollectionResolver subdependency resolver:
var container = new WindsorContainer();
var kernel = container.Kernel;
kernel.Resolver.AddSubResolver(new CollectionResolver(kernel));
Now, if you register multiple implementations of ITask, your task runner can have a ctor like this:
public TaskRunner(IEnumerable<ITask> tasks)
{
// ...
}
which is what you want, right?
Yes,
container.ResolveAll<ITask>()
This blog post explains in detail how to do it in a container ignorant way:
10 Advanced Windsor Tricks – 3. How to resolve arrays
Similar to the other answer given.

Castle Windsor inject types dynamically based on attributes or config file

I have an idea to design something like this. My class can accept a sequence of exception handlers that are registered when an instance of the class is created.
class Foo {
public Foo (IEnumerable<UnhandledExceptionEventHandler> handlers) {
foreach(var handler in handlers) {
AppDomain.CurrentDomain.UnhandledException += handler;
}
}
}
Now, I'd like to do something like this. I want to have Castle Windsor inject the handlers for me either based on attributes applied to the class
[LogExceptions(typeof(SomeExceptionHandler), typeof(AnotherExceptionHandler))]
class Foo { // code }
or specified in a config file. So in the former example, when Castle Windsor wants to resolve an instance of Foo, it would look at the LogExceptions attribute and see that it needs to construct Foo via
new Foo(new[] { new SomeExceptionHandler(), new AnotherExceptionHandler() });
What are the concepts in Castle Windsor that I want to look at that will enable me to solve this problem?
If my design is retarded, please say so but offer constructive ideas! Thanks!
The best extension point for stuff like that is ComponentModel construction contributors. You will need to discover what handlers apply to your component, and then construct an array of service override dependencies for them.

Can you add a dependency to a Castle component that was auto-registered?

I generally use StructureMap, but on a current project I'm using Castle Windsor (2.1). I've found some code to auto-register types and interfaces:
_container.Register(AllTypes.Pick().FromAssembly(GetType().Assembly).WithService.FirstInterface());
However I would like to add a string dependency to one of the types. I can do this without the convention like this:
var registration = Component.For() .ImplementedBy().DependsOn(new[] { Property.ForKey("someString").Eq("blahblah") });
_container.Register(registration);
Is there any way I can do this with the auto-registered types?
you use ConfigureFor<> method which lets you finetune your registration on a granular level.

Windsor Castle: Hooking up to container's resolving and releasing mechanism

I'm trying to implement automatic registration of my listeners to a singleton event aggregator when listeners are created by the IoC container - basically what Jeremy D. Miller is doing, but with Castle instead of StructureMap.
So I want to be able to "intercept" Windsor's object creation mechanism and, if the object supports the marker interface (let's say IListener), call the Subscribe method to an EventAggregator (which is also registered in the container) to make the newly created object a subscriber to events. Also, before the object instance has been released by the container, I want to be able to unsubscribe it.
I'm a little bit confused about what mechanism in Windsor Castle I should use to achieve something like this? I started looking at IInterceptor interface, but it seems to intercept all calls to the object, which is not what I really need (and want to avoid for performance reasons).
IKernel exposes various events like ComponentCreated and ComponentDestroyed which you can use to build that. There are many samples on the web.
Otherwise you could just use the event wiring facility, but it's not convention based.
You could also use OnCreate like this:
container.Register(
Component.For(typeof (Foo)).OnCreate(
(k, c) => {
// ...
eventAggregator.Subscribe(c);
// ...
}));