public void Intercept(IInvocation invocation) { ContentTypeBase docType = (ContentTypeBase)invocation.InvocationTarget; string propertyName = invocation.Method.GetPropertyName(); if (invocation.Method.IsGetter()) { if (docType[propertyName] == null) { // Type typeDocType = DocumentTypeManager.GetDocumentTypeType(docType.Source.NodeTypeAlias); var typeDocType = ProxyUtil.GetUnproxiedType(docType); PropertyInfo propInfo = typeDocType.GetProperty(propertyName); object value = null; try { value = ContentHelper.GetPropertyValueOrMixin(docType, propInfo); docType[propertyName] = value; } catch (Exception exc) { throw new Exception(string.Format("Cannot set the value of a document type property {0}.{1} (document type: {2}) to value: '{3}' (value type: {4}). Error: {5}", typeDocType.Name, propInfo.Name, propInfo.PropertyType.FullName, value, value != null ? value.GetType().FullName : "", exc.Message)); } } invocation.ReturnValue = docType[propertyName]; if (invocation.ReturnValue == null && invocation.Method.ReturnType == typeof(bool)) { invocation.ReturnValue = false; } } else { docType[propertyName] = invocation.Arguments[0]; } }
/// <summary> /// The method populates a given typedObject with values from the node using typeDocType as a information about typedObject properties. /// </summary> /// <param name="node">A node to get values from</param> /// <param name="typeDocType">A type to get properties information from</param> /// <param name="typedObject">Either DocumentTypeBase or mixin reference</param> private static void PopulateInstanceValues(Node node, Type typeDocType, ContentTypeBase typedObject) { foreach (PropertyInfo propInfo in typeDocType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { // Let's support typed access to mixins var mixinAttribute = Util.GetAttribute <MixinPropertyAttribute>(propInfo); // if property is a mixin if (mixinAttribute != null // and property is not to be intercepted && (propInfo.GetGetMethod() != null && (!propInfo.GetGetMethod().IsVirtual || propInfo.GetGetMethod().IsFinal))) { var mixin = GetMixinValue(node, propInfo); propInfo.SetValue(typedObject, mixin, null); continue; } DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null || (propInfo.GetGetMethod() != null && propInfo.GetGetMethod().IsVirtual&& !propInfo.GetGetMethod().IsFinal)) { continue; // skip this property - not part of a Document Type or is virtual in which case value will be intercepted } object value = null; try { value = GetPropertyValue(node, propInfo, propAttr); propInfo.SetValue(typedObject, value, null); } catch (Exception exc) { throw new Exception(string.Format("Cannot set the value of a document type property {0}.{1} (document type: {2}) to value: '{3}' (value type: {4}). Error: {5}", typeDocType.Name, propInfo.Name, propInfo.PropertyType.FullName, value, value != null ? value.GetType().FullName : "", exc.Message)); } } }
internal static object GetPropertyValueOrMixin(ContentTypeBase entity, PropertyInfo propInfo) { var mixinAttribute = Util.GetAttribute <MixinPropertyAttribute>(propInfo); return(mixinAttribute != null?GetMixinValue(entity.Source, propInfo) : GetPropertyValue(entity.Source, propInfo, null)); }