Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 241
Tom Davis Avatar asked Oct 05 '12 22:10

Tom Davis


People also ask

What is the scope of a component in the Windsor container?

When a Component is resolved from the Windsor container it must have a definition of the scope it is in. By scope meaning if and how it is reused and when to release the object for the Garbage Collector to destroy.

What is out of the box Windsor?

Out of the box Windsor provides set of lifestyles that cover most real life scenarios. Singleton components will only produce a single instance that is bound to the container. The instance will be created the first time someone requests it, and subsequently reused every time it's needed.

How to release custom scoped objects from a container?

Instead of calling Container.BeginScope (), you can just new CustomScope () and dispose it in the end to make sure your "custom scoped objects" released properly. You can call Container.BeginScope () inside your CustomScope and dispose them both in the end in order to support components registered with default lifetime scope.


1 Answers

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.

like image 197
Sebastian Good Avatar answered Oct 20 '22 09:10

Sebastian Good