Is it possible to use a scoped lifestyle in Castle Windsor without passing the container around?
Asked Answered
I

1

9

It's generally accepted that passing an IoC container around your application and using it like a service locator is bad practice.

I prefer to use the container only in the composite root of my application and tend to make a single call to Resolve() - resolving the top level object in my application and replying on the container to inject dependencies to classes lower in the object graph.

Castle Windsor has recently added a scoped lifestyle, where you can call container.BeginScope() within a "using" block. From within this "using" block, resolving a component that was registered with a scoped lifestyle will return the same instance each time, for the duration of the "using" block.

container.Register(Component.For<A>().LifestyleScoped());

using (container.BeginScope())
{
    var a1 = container.Resolve<A>();
    var a2 = container.Resolve<A>();
    Assert.AreSame(a1, a2);
}

Question: Given that BeginScope() is an extension method on the container, I fail to see how a scoped lifestyle could be used in an application unless the container is passed around (which I really don't want to do). Does anyone have any examples of where/how the scoped lifestyle can be used?

Thanks,

Tom

Isomerism answered 5/10, 2012 at 22:14 Comment(3)
where how and why are you planning to use the scoped lifestyle?Mulholland
Hi Krzystof, I don't have any plans to use the scoped lifestyle yet. I just wanted to see a few examples of how the scoped lifestyle could be used properly, in case I wanted to use it in the future. I guess using it within factories seems like a logical approach.Isomerism
This seems similar to what i need , I wan't to resolve scoped instances as dependencies in constructors , of objects with in the same scope : #25065016Romeo
M
7

I think the use would typically be inside of a factory, which does generally get to see the container. Think of a web application: in a sense, each invocation of a controller in an MVC app, or a "page", is running a semi-independent program. It's not unreasonable to have that "program" resolve its own dependencies. That is, each controller invocation should resolve its dependencies using the container.

In the scope of a particular web request, or TCP request, or user session, you may want the container to resolve objects differently. This is a way for you to cleanly do so inside one of your own factories. As with all uses of IoC, you have to be care not to abuse it such that business logic ends up sneaking into your registration code.

Metamorphosis answered 6/10, 2012 at 1:28 Comment(1)
Agreed. After doing some further thinking and reading, the general consensus seems to be that the container can be used within the entry point assembly "the composite root" (through installers/bootstrappers and factories), but should not "leak" into other assemblies containing the application domain.Isomerism

© 2022 - 2024 — McMap. All rights reserved.