PageRenderTime 35ms CodeModel.GetById 23ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/Compilation/BaseServerObjectExpressionBuilder.cs

#
C# | 176 lines | 74 code | 20 blank | 82 comment | 14 complexity | c54df0bbbffb89f4b4dc848c637be559 MD5 | raw file
  1// --------------------------------------------------------------------------------------------------------------------
  2// <summary>
  3//   Base Server Object Expression Builder
  4// </summary>
  5// --------------------------------------------------------------------------------------------------------------------
  6
  7namespace BlogEngine.Core.Compilation
  8{
  9    using System;
 10    using System.CodeDom;
 11    using System.ComponentModel;
 12    using System.Web;
 13    using System.Web.Compilation;
 14    using System.Web.UI;
 15
 16    /// <summary>
 17    /// Base Server Object Expression Builder
 18    /// </summary>
 19    public abstract class BaseServerObjectExpressionBuilder : ExpressionBuilder
 20    {
 21        #region Properties
 22
 23        /// <summary>
 24        ///     Gets the name of the source object.
 25        /// </summary>
 26        /// <value>The name of the source object.</value>
 27        public abstract string SourceObjectName { get; }
 28
 29        /// <summary>
 30        ///     When overridden in a derived class, returns a value indicating whether the current <see cref = "T:System.Web.Compilation.ExpressionBuilder" /> object supports no-compile pages.
 31        /// </summary>
 32        /// <value></value>
 33        /// <returns>true if the <see cref = "T:System.Web.Compilation.ExpressionBuilder" /> supports expression evaluation; otherwise, false.
 34        /// </returns>
 35        public override bool SupportsEvaluate
 36        {
 37            get
 38            {
 39                return true;
 40            }
 41        }
 42
 43        #endregion
 44
 45        #region Public Methods
 46
 47        /// <summary>
 48        /// When overridden in a derived class, returns an object that represents an evaluated expression.
 49        /// </summary>
 50        /// <param name="target">
 51        /// The object containing the expression.
 52        /// </param>
 53        /// <param name="entry">
 54        /// The object that represents information about the property bound to by the expression.
 55        /// </param>
 56        /// <param name="parsedData">
 57        /// The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)"/>.
 58        /// </param>
 59        /// <param name="context">
 60        /// Contextual information for the evaluation of the expression.
 61        /// </param>
 62        /// <returns>
 63        /// An object that represents the evaluated expression; otherwise, null if the inheritor does not implement <see cref="M:System.Web.Compilation.ExpressionBuilder.EvaluateExpression(System.Object,System.Web.UI.BoundPropertyEntry,System.Object,System.Web.Compilation.ExpressionBuilderContext)"/>.
 64        /// </returns>
 65        public override object EvaluateExpression(
 66            object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
 67        {
 68            return this.GetRequestedValue(entry.Expression.Trim(), target.GetType(), entry.PropertyInfo.Name);
 69        }
 70
 71        /// <summary>
 72        /// When overridden in a derived class, returns code that is used during page execution to obtain the evaluated expression.
 73        /// </summary>
 74        /// <param name="entry">
 75        /// The object that represents information about the property bound to by the expression.
 76        /// </param>
 77        /// <param name="parsedData">
 78        /// The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)"/>.
 79        /// </param>
 80        /// <param name="context">
 81        /// Contextual information for the evaluation of the expression.
 82        /// </param>
 83        /// <returns>
 84        /// A <see cref="T:System.CodeDom.CodeExpression"/> that is used for property assignment.
 85        /// </returns>
 86        public override CodeExpression GetCodeExpression(
 87            BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
 88        {
 89            var inputParams = new CodeExpression[]
 90                {
 91                    new CodePrimitiveExpression(entry.Expression.Trim()), new CodeTypeOfExpression(entry.DeclaringType), 
 92                    new CodePrimitiveExpression(entry.PropertyInfo.Name)
 93                };
 94
 95            // Return a CodeMethodInvokeExpression that will invoke the GetRequestedValue method using the specified input parameters
 96            return new CodeMethodInvokeExpression(
 97                new CodeTypeReferenceExpression(this.GetType()), "Instance().GetRequestedValue", inputParams);
 98        }
 99
100        /// <summary>
101        /// Gets the requested value.
102        /// </summary>
103        /// <param name="key">
104        /// The key of the requested value.
105        /// </param>
106        /// <param name="targetType">
107        /// Type of the target.
108        /// </param>
109        /// <param name="propertyName">
110        /// Name of the property.
111        /// </param>
112        /// <returns>
113        /// The requested value.
114        /// </returns>
115        public object GetRequestedValue(string key, Type targetType, string propertyName)
116        {
117            // First make sure that the server object will be available
118            if (HttpContext.Current == null)
119            {
120                return null;
121            }
122
123            // Get the value
124            var value = this.GetValue(key);
125
126            // Make sure that the value exists
127            if (value == null)
128            {
129                throw new InvalidOperationException(
130                    string.Format("{0} field '{1}' not found.", this.SourceObjectName, key));
131            }
132
133            // If the value is being assigned to a control property we may need to convert it
134            if (targetType != null)
135            {
136                var propDesc = TypeDescriptor.GetProperties(targetType)[propertyName];
137
138                // Type mismatch - make sure that the value can be converted
139                if (propDesc != null && propDesc.PropertyType != value.GetType() && propDesc.Converter != null)
140                {
141                    if (propDesc.Converter.CanConvertFrom(value.GetType()) == false)
142                    {
143                        throw new InvalidOperationException(
144                            string.Format(
145                                "{0} value '{1}' cannot be converted to type {2}.",
146                                this.SourceObjectName,
147                                key,
148                                propDesc.PropertyType));
149                    }
150
151                    return propDesc.Converter.ConvertFrom(value);
152                }
153            }
154
155            // If we reach here, no type mismatch - return the value
156            return value;
157        }
158
159        #endregion
160
161        #region Methods
162
163        /// <summary>
164        /// Gets the value.
165        /// </summary>
166        /// <param name="key">
167        /// The key of the value to retrieve.
168        /// </param>
169        /// <returns>
170        /// The value.
171        /// </returns>
172        protected abstract object GetValue(string key);
173
174        #endregion
175    }
176}