views:

38

answers:

3

By my (likely meager) understanding, doing this in the middle of a method in your controller / presenter is considered bad practice, since it creates a dependency between StructureMap and your presenter:

void Override() {
    ICommentForOverrideGetter comm = StructureMap.ObjectFactory.GetInstance<ICommentForOverrideGetter>();

since this dependancy should be injected into the presenter via the constructor, with your IoC container wiring it up. In this case though my code needs a fresh copy of ICommentForOverrideGetter every time this method runs. Is this an exception to the above best practice, or a case where I should re-think my architecture?

+1  A: 

It is said that there is no problem in computer science which cannot be solved by one more level of indirection:

If you just don't want the dependency in your presenter, inject a factory interface, the real implementation could do new CommentForOverrideGetter or whatever.

Edit:

"I have no problem ignoring best practices when I think the complexity/benefit ratio is too high": Neither do I, but as I said in the comments, I don't like hard dependencies on IoC containers in code I want to unit test and presenters are such a case.

Depending on what your ICommentForOverrideGetter does, you could also use a simple CommentForOverrideGetter.CreateNew() but as you require a fresh instance per call, I'd suspect at least some kind of logic associated with the creation? Or is it a stateful "service"?

Maxem
I absolutely love that saying (from David Wheeler). I know I could do that, but boy, it seems like too much overhead for something so simple. And aren't IoC containers supposed to eliminate the need for factories in situtations like you describe?
Adam
And the IoC call isn't particularly bothering me, I'm just asking more about IoC best practices. I have no problem ignoring best practices when I think the complexity/benefit ratio is too high, I just want to make sure there's nothing else I'm missing.
Adam
Personally, I just wouldn't want a hard dependency on an IoC container in my presenters (or to be more general: classes I want to unit test).
Maxem
This is a really simple case, and I fear my question will look stupid when I describe it, but the main thing for me is figuring out best practices so I can apply them to more complex things like stateful services. I'm not a new programmer, I just started Unit testing / IoC late in the game. Anyway, IComment. is just a very simple view (form) that fetches a comment, and fires off an event that the presenter catches. Under some circumst. the presenter will do X when the event fires, under others it will do Y. So I've just been getting an inst of it when needed, and then wiring up the event
Adam
if you don't want the complexity of setting up an IoC for your unit tests, you should use factories. On the other hand, a simple ObjectFactory.Inject<T>(T instance) is enough in StructureMaps case. I don't hink anyone can give you a definitve answer here as all have different preferences :)
Maxem
Also, when you talk about avoiding hard dependancies in code you're unit testing, like presenters, wouldn't putting the creation code in a factory *still* result in a dependancy between the presenter and your IoC, since the Presenter is calling your factory, and your factory is calling your IoC? Haven't you in effect just "kicked the can down the road" a bit?
Adam
That's fine - people's preferences were all I was looking for. Thank you for taking the time to provide your feedback :)
Adam
+1  A: 

If you insist on doing service location in your method, you should at least inject the container into your controller, so that you can eliminate the static method call. Add a constructor parameter of type StructureMap.IContainer and store it in a field variable. StructureMap will inject the proper container. You can then call GetInstance() on that container, instead of ObjectFactory.

Joshua Flanagan
A: 

The answer I ended up going with, from Jeremy Miller, is to just inject the Func<ICommentGetter> into the presenter.

Adam