1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Reflection;
   4:  using Yappi.Delegates;
   5:   
   6:  namespace Yappi.Samples
   7:  {
   8:      /// <summary>
   9:      /// Base for implementing interfaces with properties.
  10:      /// </summary>
  11:      public class DictionaryBased
  12:      {
  13:          //container for storing property values
  14:          private readonly Dictionary<String, Object> _data = new Dictionary<string, object>();
  15:          private readonly string _defaultstringValue;
  16:   
  17:          /// <summary>
  18:          /// Ctor can be protected.
  19:          /// All non-private constructors will be implemented in autogenrated proxy with same signature.
  20:          /// Will be avaliable with Property.Constructor.Compile method.
  21:          /// </summary>
  22:          /// <param name="defaultString"> Sample .Ctor with parameter</param>
  23:          protected DictionaryBased(string defaultString)
  24:          {
  25:              _defaultstringValue = defaultString;
  26:          }
  27:   
  28:          /// <summary>
  29:          /// Second .ctor.
  30:          /// </summary>
  31:          protected DictionaryBased()
  32:          {
  33:              _defaultstringValue = "";
  34:          }
  35:   
  36:          /// <summary>
  37:          /// Displays data stored in dictionary.
  38:          /// </summary>
  39:          public void WriteData()
  40:          {
  41:              //writing property values from container
  42:              foreach (var pair in _data)
  43:              {
  44:                  Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
  45:              }
  46:          }
  47:   
  48:   
  49:          /// <summary>
  50:          /// Implementation of properties.
  51:          /// Must be IImplementationMap[TBaseType] and new()
  52:          /// Defined as nested type for accessing private members of DictionaryBased
  53:          /// </summary>
  54:          public class Implementation : DefaultImplementation<DictionaryBased>
  55:          {
  56:              /// <summary>
  57:              /// Defines custom property getter logic.
  58:              /// Called once for each implementing property in type initializer (cctor).
  59:              /// </summary>
  60:              /// <typeparam name="TResult">Type of property value.</typeparam>
  61:              /// <typeparam name="TDeclaringType">Type? declaring property.</typeparam>
  62:              /// <typeparam name="TConstructedType">Constructed new type.</typeparam>
  63:              /// <typeparam name="TBaseType">Will be DictionaryBased at run time.</typeparam>
  64:              /// <param name="property">Name of the property.</param>
  65:              /// <returns>Delegate implementing custom logic.</returns>
  66:              public override Func<TBaseType, TResult> ImplementGetter<TBaseType, TDeclaringType, TConstructedType, TResult>(PropertyInfo property)
  67:              {
  68:                  var propertyName = property.Name;
  69:   
  70:                  if (typeof(TResult) == typeof(string))
  71:                  {
  72:                      //lambdas are easy to debug and implement.
  73:                      return (pthis) =>
  74:                      {
  75:                          object value = null;
  76:                          if (pthis._data.TryGetValue(propertyName, out value))
  77:                          {
  78:                              return (TResult)value;
  79:                          }
  80:                          return (TResult)(object)(pthis._defaultstringValue);
  81:                      };
  82:   
  83:                  }
  84:                  //lambdas are easy to debug and implement.
  85:                  return (pthis) =>
  86:                  {
  87:                      object value = null;
  88:                      if (pthis._data.TryGetValue(propertyName, out value))
  89:                      {
  90:                          return (TResult)value;
  91:                      }
  92:                      return default(TResult);
  93:                  };
  94:              }
  95:   
  96:              /// <summary>
  97:              /// Defines custom property setter logic.
  98:              /// Called once for each implementing property in type initializer (cctor).
  99:              /// </summary>
 100:              /// <typeparam name="TResult">Type of property value.</typeparam>
 101:              /// <typeparam name="TDeclaringType">Type declaring property.</typeparam>
 102:              /// <typeparam name="TBaseType">Will be DictionaryBased at run time.</typeparam>
 103:              /// <typeparam name="TConstructedType">Constructed new type.</typeparam>
 104:              /// <param name="property">Name of the property.</param>
 105:              /// <returns>Delegate implementing custom logic.</returns>
 106:              public override Action<TBaseType, TResult> ImplementSetter<TBaseType, TDeclaringType, TConstructedType, TResult>(PropertyInfo property)
 107:              {
 108:                  var propertyName = property.Name;
 109:                  //lambdas are easy to debug and implement.
 110:                  return (pthis, value) =>
 111:                  {
 112:                      pthis._data[propertyName] = (object)value;
 113:                  };
 114:              }
 115:   
 116:              /// <summary>
 117:              /// Static class holding implementation's constructed types.
 118:              /// </summary>
 119:              /// <typeparam name="TInterface">Implemented interface type</typeparam>
 120:              public static class Of<TInterface> where TInterface : class
 121:              {
 122:                  /// <summary>
 123:                  /// Holding constructed proxy type.
 124:                  /// </summary>
 125:                  private static readonly Type Type = PropertyProxy.ConstructType<DictionaryBased, Implementation>(typeof(TInterface));
 126:   
 127:                  /// <summary>
 128:                  /// Constructor calling delegate's wrapper.
 129:                  /// </summary>
 130:                  /// <typeparam name="TDelegate">Any delegate type. 
 131:                  /// Its return type must be assignable from Type. 
 132:                  /// Constructor with corresponding set of parameters must be present.
 133:                  /// </typeparam>
 134:                  public static class Create<TDelegate>
 135:                  {
 136:                      /// <summary>
 137:                      /// Holding delegate, that can be used for creating an instance of proxy implentation.
 138:                      /// </summary>
 139:                      public static readonly TDelegate New = Constructor.Compile<TDelegate>(Type);
 140:                  }
 141:              }
 142:          }
 143:      }
 144:  }

Last edited Jul 1, 2011 at 5:23 PM by Kelqualyn, version 3

Comments

No comments yet.