简体   繁体   中英

Can or should I conditionally bind interfaces at runtime with Castle Windsor?

I might be describing this wrong, but here's my dilemma, I have a series of interfaces, like IBreadcrumbRetriever . Their implementations are radically different depending where on my site they are, which I'm using HttpContext.Current.Request.Path to determine.

So inside my concrete class I'm right now have several if statements that determine what items to return (for simplicity sake, let's say List<string> ). This is a code smell to me.

What I would really like, is somehow, and I feel as if IoC and Castle Windsor can help me out here, is determine if the user hitting the page meetings the certain conditional and bind the correct container to that. So I'd have something like

if (HttpContext.Current.Request.Path == some condition)
     IBreadcrumbRetriever is ImplementedBy IsInProductAreaRetriever

Is this a good idea? If so how would I do this? Or do I create like a breadcrumb factory class and use the " .DependsOn(HttpContext.Current.Request.Path) " extension to achieve what I'm doing?

It depends on whether your app architecture is fit for dependency injection.

Not familiar with Castle Windsor but generally speaking, if a dependency can't be resolved at the composition root (app startup) I see nothing wrong with injecting a factory implementation that works with current http context.

For example, in an ASP.NET application your composition root would be in global.asax . There you could bind some IBreadcrumbRetrieverFactory to a BreadcrumbRetrieverFactory implementation. new ing up classes that aren't part of the core framework (and a few that are) is generally a sign of a missed DI opportunity (and of tight coupling).

IoC containers and DI aren't a silver bullet: Depencency Injection is merely a design pattern (think constructor injection, constructors that only assign private readonly fields - the type's dependencies), and IoC containers (all of them) are nothing but tools to facilitate the wiring-up of dependencies with concrete implementations. With that in mind, there's nothing Castle Windsor will do that you can't achieve with poor man's DI : the key is all about pushing the instantiation of dependencies as early as possible - namely, at the application startup, the composition root .

When a dependency is "dynamic", like, when there's a logic that determines whether the implementation of ISmurf should be HappySmurf or GrumpySmurf , the best thing to do is, IMHO, to inject a ISmurfFactory dependency instead of a ISmurf , and push the factory's wiring-up to the composition root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM