diff options
Diffstat (limited to 'Xamarin.Forms.Core/DependencyService.cs')
-rw-r--r-- | Xamarin.Forms.Core/DependencyService.cs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core/DependencyService.cs b/Xamarin.Forms.Core/DependencyService.cs new file mode 100644 index 00000000..d3c43998 --- /dev/null +++ b/Xamarin.Forms.Core/DependencyService.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Xamarin.Forms +{ + public static class DependencyService + { + static bool s_initialized; + + static readonly List<Type> DependencyTypes = new List<Type>(); + static readonly Dictionary<Type, DependencyData> DependencyImplementations = new Dictionary<Type, DependencyData>(); + + public static T Get<T>(DependencyFetchTarget fetchTarget = DependencyFetchTarget.GlobalInstance) where T : class + { + if (!s_initialized) + Initialize(); + + Type targetType = typeof(T); + + if (!DependencyImplementations.ContainsKey(targetType)) + { + Type implementor = FindImplementor(targetType); + DependencyImplementations[targetType] = implementor != null ? new DependencyData { ImplementorType = implementor } : null; + } + + DependencyData dependencyImplementation = DependencyImplementations[targetType]; + if (dependencyImplementation == null) + return null; + + if (fetchTarget == DependencyFetchTarget.GlobalInstance) + { + if (dependencyImplementation.GlobalInstance == null) + { + dependencyImplementation.GlobalInstance = Activator.CreateInstance(dependencyImplementation.ImplementorType); + } + return (T)dependencyImplementation.GlobalInstance; + } + return (T)Activator.CreateInstance(dependencyImplementation.ImplementorType); + } + + public static void Register<T>() where T : class + { + Type type = typeof(T); + if (!DependencyTypes.Contains(type)) + DependencyTypes.Add(type); + } + + public static void Register<T, TImpl>() where T : class where TImpl : class, T + { + Type targetType = typeof(T); + Type implementorType = typeof(TImpl); + if (!DependencyTypes.Contains(targetType)) + DependencyTypes.Add(targetType); + + DependencyImplementations[targetType] = new DependencyData { ImplementorType = implementorType }; + } + + static Type FindImplementor(Type target) + { + return DependencyTypes.FirstOrDefault(t => target.IsAssignableFrom(t)); + } + + static void Initialize() + { + Assembly[] assemblies = Device.GetAssemblies(); + if (Registrar.ExtraAssemblies != null) + { + assemblies = assemblies.Union(Registrar.ExtraAssemblies).ToArray(); + } + + Type targetAttrType = typeof(DependencyAttribute); + + // Don't use LINQ for performance reasons + // Naive implementation can easily take over a second to run + foreach (Assembly assembly in assemblies) + { + Attribute[] attributes = assembly.GetCustomAttributes(targetAttrType).ToArray(); + if (attributes.Length == 0) + continue; + + foreach (DependencyAttribute attribute in attributes) + { + if (!DependencyTypes.Contains(attribute.Implementor)) + { + DependencyTypes.Add(attribute.Implementor); + } + } + } + + s_initialized = true; + } + + class DependencyData + { + public object GlobalInstance { get; set; } + + public Type ImplementorType { get; set; } + } + } +}
\ No newline at end of file |