Question

a possibly simple problem, but weird why I have no idea how to do it:

Unity (PRISM) and static methods. In this special case, an extension method. But in general, how do I access a "unity provided instance" in a static method. Think e.g. of a logging service I want to access to log some stuff I am doing inside a static method. Do I really have to pass the ref to the logging service when using it?

Example (close to actual problem)

public static void HookupPrismEvent(ref UIElement, ILogger log) {...}

Seems strange, I think I am missing somethings, like Container.Resolve (static resolve). Have not found anything, but container, unity or static are not the worlds best search terms. Perhaps I should just try it, but still, it feels kind of "strange"..

So any comments on HOW and IF to use DI in static methods?

Chris

EDIT - ok, current approach after answer: EDIT2, after thinking about it, removed container, providing "what needed"....

  public static void AttachPrismEvents(this UIElement element, IEventAggregator eA)
    {
        var ev = eA.GetEvent<KeyPressedEvent>();
        element.KeyDown += ((sender, e) => ev.Publish(e));
    }

or, with logging:

  public static void AttachPrismEvents(this UIElement element, ILogger log, IEventAggregator eA)
    {
        log.Debug("Doing stuff");
        var ev = eA.GetEvent<KeyPressedEvent>();
        element.KeyDown += ((sender, e) => ev.Publish(e));
    }
Was it helpful?

Solution

Static types and members are generally the enemy of all things DI.

Technically, you could have a static Resolve method, but that would not be DI, but rather a pattern known as Service Locator. However, many people (myself included) consider Service Locator an anti-pattern for several reasons:

  • It makes implicit assumptions about the usage requirements of an API (the caller is not made aware that a Service Locator must be correctly configured before the member can be invoked)
  • It becomes impossible to nest containers
  • It introduces a redundant dependency on the Service Locator itself

If you must have a static method, you should pass the dependency via Method Injection, but I think it is often more beneficial to reconsider the overall API design. Often, the desired functionality can be modeled as a member on one of the input parameters instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top