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.Binding.Internals
22 /// <typeparam name="TRegistrable"></typeparam>
23 [EditorBrowsable(EditorBrowsableState.Never)]
24 internal class Registrar<TRegistrable> where TRegistrable : class
26 readonly Dictionary<Type, Type> _handlers = new Dictionary<Type, Type>();
31 /// <param name="tview">The type of the view</param>
32 /// <param name="trender">The type of the render.</param>
33 public void Register(Type tview, Type trender)
35 //avoid caching null renderers
38 _handlers[tview] = trender;
41 internal TRegistrable GetHandler(Type type)
43 Type handlerType = GetHandlerType(type);
44 if (handlerType == null)
47 object handler = DependencyResolver.ResolveOrCreate(handlerType);
49 return (TRegistrable)handler;
52 internal TRegistrable GetHandler(Type type, params object[] args)
56 return GetHandler(type);
59 Type handlerType = GetHandlerType(type);
60 if (handlerType == null)
63 return (TRegistrable)DependencyResolver.ResolveOrCreate(handlerType, args);
67 /// For internal use. Returns handler.
69 /// <typeparam name="TOut">The type of the handler</typeparam>
70 /// <param name="type">The type.</param>
71 /// <returns>The handler instance.</returns>
72 public TOut GetHandler<TOut>(Type type) where TOut : TRegistrable
74 return (TOut)GetHandler(type);
78 /// For internal use. Returns handler.
80 /// <typeparam name="TOut">The type of the handler</typeparam>
81 /// <param name="type">The type.</param>
82 /// <param name="args">The args of the type</param>
83 /// <returns>The handler instance.</returns>
84 public TOut GetHandler<TOut>(Type type, params object[] args) where TOut : TRegistrable
86 return (TOut)GetHandler(type, args);
90 /// For internal use. Return the handler of the object.
92 /// <typeparam name="TOut">Thetype</typeparam>
93 /// <param name="obj">The object instance.</param>
94 /// <returns>The handle of the obj.</returns>
95 public TOut GetHandlerForObject<TOut>(object obj) where TOut : TRegistrable
98 throw new ArgumentNullException(nameof(obj));
100 var reflectableType = obj as IReflectableType;
101 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
103 return (TOut)GetHandler(type);
107 /// For inetrnal use. Return the handler of the object.
109 /// <typeparam name="TOut">The type</typeparam>
110 /// <param name="obj">The object instance</param>
111 /// <param name="args">The args of the type</param>
112 /// <returns>The handler of the object.</returns>
113 public TOut GetHandlerForObject<TOut>(object obj, params object[] args) where TOut : TRegistrable
116 throw new ArgumentNullException(nameof(obj));
118 var reflectableType = obj as IReflectableType;
119 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
121 return (TOut)GetHandler(type, args);
125 /// For internal use. Returns the handle type.
127 /// <param name="viewType">The view type.</param>
128 /// <returns>The type of the handle.</returns>
129 public Type GetHandlerType(Type viewType)
132 if (LookupHandlerType(viewType, out type))
135 // lazy load render-view association with RenderWithAttribute (as opposed to using ExportRenderer)
136 var attribute = viewType.GetTypeInfo().GetCustomAttribute<RenderWithAttribute>();
137 if (attribute == null)
139 Register(viewType, null); // Cache this result so we don't have to do GetCustomAttribute again
143 type = attribute.Type;
145 if (type.Name.StartsWith("_", StringComparison.Ordinal))
147 // TODO: Remove attribute2 once renderer names have been unified across all platforms
148 var attribute2 = type.GetTypeInfo().GetCustomAttribute<RenderWithAttribute>();
149 if (attribute2 != null)
150 type = attribute2.Type;
152 if (type.Name.StartsWith("_", StringComparison.Ordinal))
154 Register(viewType, null); // Cache this result so we don't work through this chain again
159 Register(viewType, type); // Register this so we don't have to look for the RenderWith Attibute again in the future
165 /// For internal use. Return the handle type of the object
167 /// <param name="obj">The object instance.</param>
168 /// <returns>The type of the handler.</returns>
169 public Type GetHandlerTypeForObject(object obj)
172 throw new ArgumentNullException(nameof(obj));
174 var reflectableType = obj as IReflectableType;
175 var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType();
177 return GetHandlerType(type);
180 bool LookupHandlerType(Type viewType, out Type handlerType)
182 Type type = viewType;
186 if (_handlers.ContainsKey(type))
188 handlerType = _handlers[type];
192 type = type.GetTypeInfo().BaseType;
203 [EditorBrowsable(EditorBrowsableState.Never)]
204 internal static class Registrar
208 Registered = new Registrar<IRegisterable>();
211 internal static Dictionary<string, Type> Effects { get; } = new Dictionary<string, Type>();
212 internal static Dictionary<string, StyleSheets.StylePropertyAttribute> StyleProperties { get; } = new Dictionary<string, StyleSheets.StylePropertyAttribute>();
214 public static IEnumerable<Assembly> ExtraAssemblies { get; set; }
216 public static Registrar<IRegisterable> Registered { get; internal set; }
218 public static void RegisterAll(Type[] attrTypes)
220 Assembly[] assemblies = Device.GetAssemblies();
221 if (ExtraAssemblies != null)
222 assemblies = assemblies.Union(ExtraAssemblies).ToArray();
224 Assembly defaultRendererAssembly = Device.PlatformServices.GetType().GetTypeInfo().Assembly;
225 int indexOfExecuting = Array.IndexOf(assemblies, defaultRendererAssembly);
227 if (indexOfExecuting > 0)
229 assemblies[indexOfExecuting] = assemblies[0];
230 assemblies[0] = defaultRendererAssembly;
233 // Don't use LINQ for performance reasons
234 // Naive implementation can easily take over a second to run
235 foreach (Assembly assembly in assemblies)
237 foreach (Type attrType in attrTypes)
239 Attribute[] attributes;
242 attributes = assembly.GetCustomAttributes(attrType).ToArray();
244 catch (System.IO.FileNotFoundException)
246 // Sometimes the previewer doesn't actually have everything required for these loads to work
247 Console.WriteLine(nameof(Registrar), "Could not load assembly: {0} for Attibute {1} | Some renderers may not be loaded", assembly.FullName, attrType.FullName);
250 var length = attributes.Length;
251 for (var i = 0; i < length;i++)
253 var attribute = (HandlerAttribute)attributes[i];
254 if (attribute.ShouldRegister())
255 Registered.Register(attribute.HandlerType, attribute.TargetType);
259 string resolutionName = assembly.FullName;
260 var resolutionNameAttribute = (ResolutionGroupNameAttribute)assembly.GetCustomAttribute(typeof(ResolutionGroupNameAttribute));
261 if (resolutionNameAttribute != null)
262 resolutionName = resolutionNameAttribute.ShortName;
264 Attribute[] effectAttributes = assembly.GetCustomAttributes(typeof(ExportEffectAttribute)).ToArray();
265 var exportEffectsLength = effectAttributes.Length;
266 for (var i = 0; i < exportEffectsLength;i++)
268 var effect = (ExportEffectAttribute)effectAttributes[i];
269 Effects [resolutionName + "." + effect.Id] = effect.Type;
272 Attribute[] styleAttributes = assembly.GetCustomAttributes(typeof(StyleSheets.StylePropertyAttribute)).ToArray();
273 var stylePropertiesLength = styleAttributes.Length;
274 for (var i = 0; i < stylePropertiesLength; i++)
276 var attribute = (StyleSheets.StylePropertyAttribute)styleAttributes[i];
277 StyleProperties[attribute.CssPropertyName] = attribute;
281 DependencyService.Initialize(assemblies);