Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am thinking of applying a real dependency injection library to my toy C#/GTK# desktop application. I chose NInject, but I think this is irrelevant to my question.

There is a database object, a main window and several utility window classes. It's clear that I can inject the database into every window object, so here DI is useful. But does it make sense to inject utility window classes into other window classes?

Example: I have classes such as:

class MainWindow {…}
class AddItemWindow {…}
class AddAttachmentWindow {…}
class BrowseItemsWindow {…}
class QueryBuilderWindow {…}
class QueryBrowserWindow {…}
class PreferencesWindow {…}
…

Each of the utility classes can be opened from MainWindow. Some utility windows can also be opened from other utility windows. Generally, there might be a really complex graph of who can open whom. So each of those classes might need quite a lot of other window classes injected. I'm worried that such usage will go against the suggestion not to inject too many classes at once and become a code smell. Should I use some kind of a service locator object here?

share|improve this question

2 Answers 2

To avoid overinjection instead of injecting all Window's objects of classes *Window into MainWindow you could use Ninject.Extension.Factory. In this case Abstract Factory could has following interface:

public interface IWindowFactory
{
    AddItemWindow CreateAddItemWindow();
    AddAttachmentWindow CreateAddAttachmentWindow();
    /* etc */
}

And then add binding to Load implementation of Ninject.NinjectModule:

Bind<AddItemWindow>()
    .ToSelf()
    .NamedLikeFactoryMethod<AddItemWindow, IWindowFactory>(f => f.CreateIWindowFactory());

Bind<AddAttachmentWindow>()
    .ToSelf()
    .NamedLikeFactoryMethod<AddItemWindow, IWindowFactory>(f => f.CreateIWindowFactory());

/* etc */

// and factory binding
Bind<IWindowFactory>()
    .ToFactory()
    .InSingletonScope();

Two additional points:

  • There is an excelent article by Mark Seemann Pattern Recognition: Abstract Factory or Service Locator? — so this solution is ok, if you care about Serice Locator anti-pattern, and …
  • To make it 100% not the Serice Locator anti-pattern make sure that Abstract Factory creates only Windows objects, not everything.
share|improve this answer

I'd suggest a UtilityWindowOpener class. Its methods will open the various utility windows. Then you can just inject a UtilityWindowOpener anywhere you may need to open a utility window. The UtilityWindowOpener will then have the various utility windows injected (or possibly create them on demand, that's hidden behind the interface). It'll also bring all navigation logic into fewer locations.

share|improve this answer
    
So, a kind of service locator which would get its dependencies from DI framework? –  liori Dec 15 '12 at 20:46
    
@liori, I'd distinguish it from the service locator because it wouldn't return the utility windows. It would open the utility windows based on the methods called. –  Winston Ewert Dec 15 '12 at 20:46
    
That makes sense, thank you. –  liori Dec 15 '12 at 20:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.