/// <summary> /// Register a specific System.Type as available for referencing in a Lava template. /// </summary> /// <param name="type"></param> /// <param name="allowedMembers"></param> public override void RegisterSafeType(Type type, IEnumerable <string> allowedMembers) { // Check if any LavaType attributes are implemented. string[] allowedMembersArray; if (allowedMembers == null) { allowedMembersArray = LavaDataObjectHelper.GetLavaTypeInfo(type).VisiblePropertyNames.ToArray(); } else { allowedMembersArray = allowedMembers.ToArray(); } // If no members of the Type are allowed, do not register it. if (!allowedMembersArray.Any()) { return; } // Register the Type and if necessary, provide a converter function to return a Type that supports the IDictionary<string,object> interface required by DotLiquid. if (typeof(IDictionary <string, object>).IsAssignableFrom(type)) { // This Type does not require conversion, it can be accessed directly by DotLiquid. Template.RegisterSafeType(type, allowedMembersArray); return; } else if (typeof(Rock.Lava.ILavaDataDictionary).IsAssignableFrom(type)) { Template.RegisterSafeType(type, (obj) => { // Return a wrapper for the Lava dictionary that supports the IDictionary<string, object> interface. return(new DotLiquidLavaDataDictionaryProxy(obj as ILavaDataDictionary)); }); } else if (typeof(Rock.Lava.ILavaDataDictionarySource).IsAssignableFrom(type)) { Template.RegisterSafeType(type, (obj) => { // Get the Lava Dictionary and return it in a wrapper that supports the IDictionary<string, object> interface. var lavaDictionary = ((Rock.Lava.ILavaDataDictionarySource)obj).GetLavaDataDictionary(); return(new DotLiquidLavaDataDictionaryProxy(lavaDictionary)); }); } else { // Wrap the object in a DotLiquid compatible proxy that supports the IDictionary<string, object> interface. Template.RegisterSafeType(type, (obj) => { return(new DropProxy(obj, allowedMembersArray)); }); } }
private void RegisterLavaTypesAsSafeTypes() { // Register Types that use the LavaTypeAttribute, because it is not recognized by DotLiquid as safe to render. var assemblyDefinition = typeof(LavaTypeAttribute).Assembly.GetName().Name; var errors = string.Empty; // Get the list of assemblies to search. // We are only interested in those that hold a reference to the assembly that defines the LavaTypeAttribute, // so we can exclude system assemblies. var candidateAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(x => !x.GlobalAssemblyCache && !x.FullName.StartsWith("System.") && !x.FullName.StartsWith("Microsoft.")) .ToList(); var searchAssemblies = candidateAssemblies.Where(x => x.GetName().Name == assemblyDefinition || x.GetReferencedAssemblies().Any(a => a.Name == assemblyDefinition)) .ToList(); foreach (var assembly in searchAssemblies) { var registeringTypeName = "(none)"; try { foreach (var type in assembly.GetTypes()) { registeringTypeName = type.Name; var lavaInfo = LavaDataObjectHelper.GetLavaTypeInfo(type); if (lavaInfo.HasLavaTypeAttribute) { RegisterSafeType(type, lavaInfo.VisiblePropertyNames); } } } catch (Exception ex) { errors += $"\n[{ assembly.FullName }:{ registeringTypeName }] { ex.Message }"; } } if (!string.IsNullOrWhiteSpace(errors)) { throw new LavaException("Lava Engine Initialization Error. The following Lava Types could not be registered:" + errors); } }
private object GetDotLiquidCompatibleValue(object value) { // Primitive values do not require any special processing. if (value == null || value is string || value is IEnumerable || value is decimal || value is DateTime || value is DateTimeOffset || value is TimeSpan || value is Guid || value is Enum || value is KeyValuePair <string, object> ) { return(value); } var valueType = value.GetType(); if (valueType.IsPrimitive) { return(value); } // For complex types, check if a specific transformer has been defined for the type. var safeTypeTransformer = Template.GetSafeTypeTransformer(valueType); if (safeTypeTransformer != null) { return(safeTypeTransformer(value)); } if (value is ILiquidizable) { return(value); } // Check if the type is decorated with the LavaType attribute. var lavaInfo = LavaDataObjectHelper.GetLavaTypeInfo(valueType); return(new DropProxy(value, lavaInfo.VisiblePropertyNames.ToArray())); }