Castle Windsor 3 persists PerWebRequest objects across multiple web requests
-
24-06-2021 - |
Question
I have an MVC 4 project and am trying to inject a PerWebRequest object into my controller. However it appears the object is not being recreated across multiple requests
private static IWindsorContainer InitializeWindsor()
{
var container = new WindsorContainer().Install(FromAssembly.This());
// Add Factory facility
container.AddFacility<TypedFactoryFacility>();
// Register all controllers from this assembly
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
container.Register(
AllTypes.FromAssembly(assembly).BasedOn<Controller>().Configure(c => c.LifestyleTransient())
);
}
// Register HTTP Handlers
container.Register(Component.For<HttpRequestBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request)));
container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
// Register components
container.Register(Component.For<PerWebRequestObject>().LifeStyle.PerWebRequest);
}
Here's my PerWebRequestObject:
public class PerWebRequestObject
{
public DateTime DateCreated { get; set; }
public PerWebRequestObject()
{
DateCreated = DateTime.UtcNow;
Debug.WriteLine("Created: " + DateCreated.ToLongTimeString());
}
}
Here's my TestController:
public class TestController : BaseController
{
public PerWebRequestObject pwrObject { get; set; }
public ActionResult Test()
{
Debug.WriteLine(pwrObject.DateCreated.ToLongTimeString());
return new ContentResult();
}
}
Why is this not working? Note that I'm using the WindsorControllerFactory and releasing the Controller like so:
public override void ReleaseController(IController controller)
{
var disposableController = controller as IDisposable;
if (disposableController != null)
disposableController.Dispose();
_windsorContainer.Release(controller);
}
Solution 2
Upgrading to Castle Windsor v3.1 fixed the issue for us without needing to change any code.
I assume there must've been an issue with the combination of Windsor v3.0 + MVC 4.
OTHER TIPS
Two things:
- how do you know the object is not lifecycled properly (not re-created across web-requests)?
One possible explanation is that your dependency looks like this:
controller --> a singleton --> your per-web-request-component
this is a lifestyle mismatch, and that would explain the behaviour you're seing
- do not dispose the controller. That's container's job.