2 using System.Collections.Generic;
3 using System.ComponentModel;
5 using System.Reflection;
6 using Tizen.NUI.Binding;
8 namespace Tizen.NUI.Binding
10 // Previewer uses reflection to bind to this method; Removal or modification of visibility will break previewer.
11 internal static class Registrar
13 internal static void RegisterAll(Type[] attrTypes) => Internals.Registrar.RegisterAll(attrTypes);
17 namespace Tizen.NUI.Internals
19 [EditorBrowsable(EditorBrowsableState.Never)]
20 public class Registrar<TRegistrable> where TRegistrable : class
22 readonly Dictionary<Type, Type> _handlers = new Dictionary<Type, Type>();
24 public void Register(Type tview, Type trender)
26 //avoid caching null renderers
29 _handlers[tview] = trender;
32 internal TRegistrable GetHandler(Type type)
34 Type handlerType = GetHandlerType(type);
35 if (handlerType == null)
38 object handler = DependencyResolver.ResolveOrCreate(handlerType);
40 return (TRegistrable)handler;
43 internal TRegistrable GetHandler(Type type, params object[] args)
47 return GetHandler(type);
50 Type handlerType = GetHandlerType(type);
51 if (handlerType == null)
54 return (TRegistrable)DependencyResolver.ResolveOrCreate(handlerType, args);
57 public TOut GetHandler<TOut>(Type type) where TOut : TRegistrable
59 return (TOut)GetHandler(type);
62 public TOut GetHandler<TOut>(Type type, params object[] args) where TOut : TRegistrable
64 return (TOut)GetHandler(type, args);
67 public TOut GetHandlerForObject<TOut>(object obj) where TOut : TRegistrable
70 throw new ArgumentNullException(nameof(obj));
72 var reflectableType = obj as IReflectableType;
73 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
75 return (TOut)GetHandler(type);
78 public TOut GetHandlerForObject<TOut>(object obj, params object[] args) where TOut : TRegistrable
81 throw new ArgumentNullException(nameof(obj));
83 var reflectableType = obj as IReflectableType;
84 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
86 return (TOut)GetHandler(type, args);
89 public Type GetHandlerType(Type viewType)
92 if (LookupHandlerType(viewType, out type))
95 // lazy load render-view association with RenderWithAttribute (as opposed to using ExportRenderer)
96 var attribute = viewType.GetTypeInfo().GetCustomAttribute<RenderWithAttribute>();
97 if (attribute == null)
99 Register(viewType, null); // Cache this result so we don't have to do GetCustomAttribute again
103 type = attribute.Type;
105 if (type.Name.StartsWith("_", StringComparison.Ordinal))
107 // TODO: Remove attribute2 once renderer names have been unified across all platforms
108 var attribute2 = type.GetTypeInfo().GetCustomAttribute<RenderWithAttribute>();
109 if (attribute2 != null)
110 type = attribute2.Type;
112 if (type.Name.StartsWith("_", StringComparison.Ordinal))
114 Register(viewType, null); // Cache this result so we don't work through this chain again
119 Register(viewType, type); // Register this so we don't have to look for the RenderWith Attibute again in the future
124 public Type GetHandlerTypeForObject(object obj)
127 throw new ArgumentNullException(nameof(obj));
129 var reflectableType = obj as IReflectableType;
130 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
132 return GetHandlerType(type);
135 bool LookupHandlerType(Type viewType, out Type handlerType)
137 Type type = viewType;
141 if (_handlers.ContainsKey(type))
143 handlerType = _handlers[type];
147 type = type.GetTypeInfo().BaseType;
155 [EditorBrowsable(EditorBrowsableState.Never)]
156 internal static class Registrar
160 Registered = new Registrar<IRegisterable>();
163 internal static Dictionary<string, Type> Effects { get; } = new Dictionary<string, Type>();
164 internal static Dictionary<string, StyleSheets.StylePropertyAttribute> StyleProperties { get; } = new Dictionary<string, StyleSheets.StylePropertyAttribute>();
166 public static IEnumerable<Assembly> ExtraAssemblies { get; set; }
168 public static Registrar<IRegisterable> Registered { get; internal set; }
170 public static void RegisterAll(Type[] attrTypes)
172 Assembly[] assemblies = Device.GetAssemblies();
173 if (ExtraAssemblies != null)
174 assemblies = assemblies.Union(ExtraAssemblies).ToArray();
176 Assembly defaultRendererAssembly = Device.PlatformServices.GetType().GetTypeInfo().Assembly;
177 int indexOfExecuting = Array.IndexOf(assemblies, defaultRendererAssembly);
179 if (indexOfExecuting > 0)
181 assemblies[indexOfExecuting] = assemblies[0];
182 assemblies[0] = defaultRendererAssembly;
185 // Don't use LINQ for performance reasons
186 // Naive implementation can easily take over a second to run
187 foreach (Assembly assembly in assemblies)
189 foreach (Type attrType in attrTypes)
191 Attribute[] attributes;
194 attributes = assembly.GetCustomAttributes(attrType).ToArray();
196 catch (System.IO.FileNotFoundException)
198 // Sometimes the previewer doesn't actually have everything required for these loads to work
199 Console.WriteLine(nameof(Registrar), "Could not load assembly: {0} for Attibute {1} | Some renderers may not be loaded", assembly.FullName, attrType.FullName);
202 var length = attributes.Length;
203 for (var i = 0; i < length;i++)
205 var attribute = (HandlerAttribute)attributes[i];
206 if (attribute.ShouldRegister())
207 Registered.Register(attribute.HandlerType, attribute.TargetType);
211 string resolutionName = assembly.FullName;
212 var resolutionNameAttribute = (ResolutionGroupNameAttribute)assembly.GetCustomAttribute(typeof(ResolutionGroupNameAttribute));
213 if (resolutionNameAttribute != null)
214 resolutionName = resolutionNameAttribute.ShortName;
216 Attribute[] effectAttributes = assembly.GetCustomAttributes(typeof(ExportEffectAttribute)).ToArray();
217 var exportEffectsLength = effectAttributes.Length;
218 for (var i = 0; i < exportEffectsLength;i++)
220 var effect = (ExportEffectAttribute)effectAttributes[i];
221 Effects [resolutionName + "." + effect.Id] = effect.Type;
224 Attribute[] styleAttributes = assembly.GetCustomAttributes(typeof(StyleSheets.StylePropertyAttribute)).ToArray();
225 var stylePropertiesLength = styleAttributes.Length;
226 for (var i = 0; i < stylePropertiesLength; i++)
228 var attribute = (StyleSheets.StylePropertyAttribute)styleAttributes[i];
229 StyleProperties[attribute.CssPropertyName] = attribute;
233 DependencyService.Initialize(assemblies);