// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. // // WARNING: The full namespace-qualified type name should stay the same for the discovery in System.Reactive.Core to work! // using System.ComponentModel; using System.Diagnostics; using System.Reactive; using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Reflection; namespace System.Reactive.PlatformServices { /// /// (Infrastructure) Provider for platform-specific framework enlightenments. /// [EditorBrowsable(EditorBrowsableState.Never)] public class CurrentPlatformEnlightenmentProvider : IPlatformEnlightenmentProvider { /// /// (Infastructure) Tries to gets the specified service. /// /// Service type. /// Optional set of arguments. /// Service instance or null if not found. public virtual T GetService(object[] args) where T : class { var t = typeof(T); #if HAS_EDI if (t == typeof(IExceptionServices)) { return (T)(object)new ExceptionServicesImpl(); } #endif #if !NO_THREAD || WINDOWS if (t == typeof(IConcurrencyAbstractionLayer)) { return (T)(object)new ConcurrencyAbstractionLayerImpl(); } #endif if (t == typeof(IScheduler) && args != null) { switch ((string)args[0]) { #if !WINDOWS && !NO_THREAD case "ThreadPool": return (T)(object)ThreadPoolScheduler.Instance; #elif WINDOWS case "ThreadPool": return (T)(object)ThreadPoolScheduler.Default; #endif #if !NO_TPL case "TaskPool": return (T)(object)TaskPoolScheduler.Default; #endif case "NewThread": return (T)(object)NewThreadScheduler.Default; } } #if WINDOWS || WINDOWSPHONE7 if (t == typeof(IHostLifecycleNotifications)) { return (T)(object)new HostLifecycleNotifications(); } #endif if (t == typeof(IQueryServices)) { // // We perform this Debugger.IsAttached check early rather than deferring // the decision to intercept query operator methods to the debugger // assembly that's dynamically discovered here. Also, it's a reasonable // expectation it'd be pretty hard to turn on interception dynamically // upon a debugger attach event, so we should make this check early. // // In the initial release of v2.0 (RTM), we won't have the corresponding // debugger assembly available yet, so the dynamic load would always // fail. We also don't want to take the price of (an attempt to) a dynamic // assembly load for the regular production case. // if (Debugger.IsAttached) { #if NETCF35 var name = "System.Reactive.Linq.QueryDebugger, System.Reactive.Debugger"; #else #if CRIPPLED_REFLECTION var ifType = t.GetTypeInfo(); #else var ifType = t; #endif var asm = new AssemblyName(ifType.Assembly.FullName); asm.Name = "System.Reactive.Debugger"; var name = "System.Reactive.Linq.QueryDebugger, " + asm.FullName; #endif var dbg = Type.GetType(name, false); if (dbg != null) return (T)(object)Activator.CreateInstance(dbg); } } return null; } } }