Rabid Penguin Rabid Penguin - 2 years ago 127
C# Question

How to resolve instances with Castle Windsor that rely on values from the HttpRequestMessage

I'm using Web Api with the OWIN pipeline.


public class Startup {
public void Configuration(IAppBuilder app) {
var container = new WindsorContainer().Install(FromAssembly.This());

var config = new HttpConfiguration();

// extension method to resolve controllers with Windsor.
app.UseWindsorApi(config, container);

MyClassInstaller.cs (IWindsorInstaller)

public void Install(IWindsorContainer container, IConfigurationStore store)
.DependsOn(new {
configSetting = ConfigurationManager.AppSettings["key"],
otherSetting = ???

MyClass.cs & IMyClass.cs

public class MyClass : IMyClass {
private readonly string configSetting;
private readonly string otherSetting;

public MyClass(string configSetting, string otherSetting) {
this.configSetting = configSetting;
this.otherSetting = otherSetting;

public void DoSomething() {
// method that uses the settings that were set in the constructor.

public interface IMyClass {
void DoSomething();


public class MyController : ApiController {
private readonly IMyClass myClass;

public MyController(IMyClass myClass) {
this.myClass = myClass;

public async Task<IHttpActionResult> GetAsync() {
// uses this.myClass

Here's where I'm stuck. Whenever an instance of MyClass is resolved the value of otherSetting needs to be assigned.

The value of otherSetting is determined by two things.

1) The client_id claims value from the request.

2) An async call to a method that takes the client_id as a parameter and returns a string value. Which is what gets set into otherSetting

public async Task<string> GetOtherSetting(string client_id) {
return "value";

I'm not sure where to even begin to get Castle to inject a value based on those two criteria...

I've updated to potatopeelings answer with some minor changes and it seems to be working fine.

.DynamicParameters(async (k, p) =>
var fundNameProvider = k.Resolve<IFundNameValueProvider>();
p["otherSetting"] = await fundNameProvider.GetFundNameAsync();

I changed it to an async lambda so I can await the method.
I also called ReleaseComponent as I was under the impression that objects you manually Resolved with Castle you also needed to manually release.

Answer Source

Use UsingFactoryMethod and DynamicParamters

First, inject the current claims

Component.For<ClaimsIdentity>().UsingFactoryMethod(() => HttpContext.Current.User.Identity as ClaimsIdentity).LifestylePerWebRequest()

into a service (IOtherValueProvider - PerWebRequest) that has a GetOtherSetting method to wait on an async call (i.e. convert the async call to a synchronous call) to get otherSetting from the client_id extracted from the injected ClaimsIdentity

Then use DynamicParameters to get the value

... register your class ...
.DynamicParameters((kernel, parameters) =>
        parameters["otherSetting"] = kernel.Resolve<IOtherValueProvider>().GetOtherSetting();
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download