public virtual object GetService(Type serviceType) {
object service = null;
Debug.WriteLineIf(TRACESERVICE.TraceVerbose, "Searching for service " + serviceType.Name);
Debug.Indent();
// Try locally. We first test for services we
// implement and then look in our hashtable.
//
Type[] defaults = DefaultServices;
for (int idx = 0; idx < defaults.Length; idx++) {
if (serviceType == defaults[idx]) {
service = this;
break;
}
}
if (service == null) {
service = Services[serviceType];
}
// Is the service a creator delegate?
//
if (service is ServiceCreatorCallback) {
Debug.WriteLineIf(TRACESERVICE.TraceVerbose, "Encountered a callback. Invoking it");
service = ((ServiceCreatorCallback)service)(this, serviceType);
Debug.WriteLineIf(TRACESERVICE.TraceVerbose, "Callback return object: " + (service == null ? "(null)" : service.ToString()));
if (service != null && !service.GetType().IsCOMObject && !serviceType.IsAssignableFrom(service.GetType())) {
// Callback passed us a bad service. NULL it, rather than throwing an exception.
// Callers here do not need to be prepared to handle bad callback implemetations.
Debug.Fail("Object " + service.GetType().Name + " was returned from a service creator callback but it does not implement the registered type of " + serviceType.Name);
Debug.WriteLineIf(TRACESERVICE.TraceVerbose, "**** Object does not implement service interface");
service = null;
}
// And replace the callback with our new service.
//
Services[serviceType] = service;
}
if (service == null && parentProvider != null) {
Debug.WriteLineIf(TRACESERVICE.TraceVerbose, "Service unresolved. Trying parent");
service = parentProvider.GetService(serviceType);
}
#if DEBUG
if (TRACESERVICE.TraceVerbose && service == null) {
Debug.WriteLine("******************************************");
Debug.WriteLine("FAILED to resolve service " + serviceType.Name);
Debug.WriteLine("AT: " + Environment.StackTrace);
Debug.WriteLine("******************************************");
}
#endif
Debug.Unindent();
return service;
}