Announcement Announcement Module
Collapse
No announcement yet.
Service locator for rich domain entities Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Service locator for rich domain entities

    Hi all,

    I want to get a reference to a DAO/Repository from a domain object not controlled by Spring. I know this subject has been thoroughly discussed and a number of solutions and workarounds has been proposed, and that the convenience of accessing repositories and other (domain) services from domain entities is a somewhat polemic issue by itself. So I will assume that it's sometimes preferable to be able to do that in order to avoid an anemic model, but that it's also preferable to minimize this kind of dependencies to the bare minimum.

    An extensive (although a bit outdated) account of common solutions can be found here
    http://igorstoyanov.blogspot.com/200...r-service.html. In the general case I think that aspectj support in spring 2.0, specifically the @configurable annotation, is the way to go. But as I want to faithfully adopt the discipline of avoiding the domain entity->service dependencies whenever possible, a simpler (even if more adhoc) solution which involves less new concepts and tools could be desirable. So in this case I'm all for the service locator pattern, as described by Fowler (http://www.martinfowler.com/articles/injection.html).

    Essentially I will stick to the principle of one singleton to rule them all, although I prefer to avoid explicit dependencies on the Spring container, so I won't be using stuff like SingletonBeanFactoryLocator but instead injecting my domain-specific locator from the standard application context descriptor, the same as I do for any other bean.

    Let's ilustrate the above with an example:

    interface XRepositoryLocator { // segregated interface
    XRepository getXRepository();
    }

    interface YRepositoryLocator { // segregated interface
    YRepository getYRepository();
    }

    class Locator implements XRepositoryLocator, YRepositoryLocator {

    private static Locator locator;
    public static void setLocator(Locator locator) {...}
    public static Locator getLocator(Locator locator) {...}

    private XRepository xRepository;
    public void setXRepository(XRepository xRepository) {...}
    public XRepository getXRepository() {...}

    private YRepository yRepository;
    public void setYRepository(YRepository yRepository) {...}
    public YRepository getYRepository() {...}
    }

    For unit testing it's just a matter of injecting the necessary mocks:

    setUp() {
    Locator locator = new Locator();
    XRepository xRepository = new XRepositoryMock();
    locator.setXRepository(xRepository);
    Locator.setLocator(locator);
    }

    This is fine for programmatic locator injection; but is Spring able to inject dependencies using static setters? (Locator.setLocator in the example).

    Of course there is an obvious workaround to avoid static injection, namely:

    class Locator implements XRepositoryLocator, YRepositoryLocator {

    private static Locator locator;

    - public static setLocator(Locator locator) { Locator.locator = locator; }
    + public Locator() { Locator.locator = this; }

    [....]
    }

    But I find this under-the-covers setting of the static field quite a hack, although I could be wrong and this could be customary practice (I mean, in case you are forced to use singletons).

    What do you think? Assuming your choice is to stuck to service locator, how would you change the above design? Any commentaries/suggestions would be welcome!

    Thank you in advance.
    Regards,
    Carlos

  • #2
    You can have a BeanPostProcessor that, after the 'locator' bean is properly wired by Spring, gets the bean reference and sets it into the static location.

    Comment

    Working...
    X