( , ), , InjectionResolver. , (.. ServiceLocator.getService() ), , .
, - . ExtrasUtilities.bridgeServiceLocator(_innerServiceLocator, _outerServiceLocator); BridgingInjectionResolver.bridgeInjection(_innerServiceLocator, _outerServiceLocator);
@Singleton
@Rank(1)
public class BridgingInjectionResolver implements InjectionResolver<Inject>
{
@Inject
private ServiceLocator _localServiceLocator;
private ServiceLocator _remoteServiceLocator;
public BridgingInjectionResolver()
{
}
public static void bridgeInjection(ServiceLocator into, ServiceLocator from)
{
checkParentage(into, from);
checkParentage(from, into);
ServiceLocatorUtilities.addClasses(into, BridgingInjectionResolver.class);
into.getService(BridgingInjectionResolver.class).setRemoteServiceLocator(from);
}
private static void checkParentage(ServiceLocator a, ServiceLocator b)
{
ServiceLocator originalA = a;
while (a != null) {
if (a.getLocatorId() == b.getLocatorId()) {
throw new IllegalStateException("Locator " + originalA + " is a child of or is the same as locator " + b);
}
a = a.getParent();
}
}
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> root)
{
ActiveDescriptor<?> ad = _localServiceLocator.getInjecteeDescriptor(injectee);
if (ad != null) {
return _localServiceLocator.getService(ad, root, injectee);
}
ad = _remoteServiceLocator.getInjecteeDescriptor(injectee);
if ((ad != null) && (ad.getDescriptorVisibility() == DescriptorVisibility.LOCAL)) {
ad = null;
}
if (ad == null) {
if (injectee.isOptional()) {
return null;
}
throw new MultiException(new UnsatisfiedDependencyException(injectee));
}
return _remoteServiceLocator.getService(ad, root, injectee);
}
@Override
public boolean isConstructorParameterIndicator()
{
return false;
}
@Override
public boolean isMethodParameterIndicator()
{
return false;
}
private void setRemoteServiceLocator(ServiceLocator remoteServiceLocator)
{
_remoteServiceLocator = remoteServiceLocator;
}
}