internal EntityProxyTypeInfo( Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List <PropertyInfo> baseGetters, List <PropertyInfo> baseSetters, MetadataWorkspace workspace) { this._proxyType = proxyType; this._entityType = ospaceEntityType; this._initializeCollections = initializeCollections; foreach (AssociationType associationType in EntityProxyTypeInfo.GetAllRelationshipsForType(workspace, proxyType)) { this._navigationPropertyAssociationTypes.Add(associationType.FullName, associationType); if (associationType.Name != associationType.FullName) { this._navigationPropertyAssociationTypes.Add(associationType.Name, associationType); } } FieldInfo field = proxyType.GetField("_entityWrapper", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(object), "proxy"); ParameterExpression parameterExpression5 = Expression.Parameter(typeof(object), "value"); Func <object, object> getEntityWrapperDelegate = Expression.Lambda <Func <object, object> >((Expression)Expression.Field((Expression)Expression.Convert((Expression)parameterExpression4, field.DeclaringType), field), parameterExpression4).Compile(); this.Proxy_GetEntityWrapper = (Func <object, object>)(proxy => { IEntityWrapper entityWrapper = (IEntityWrapper)getEntityWrapperDelegate(proxy); if (entityWrapper != null && !object.ReferenceEquals(entityWrapper.Entity, proxy)) { throw new InvalidOperationException(Strings.EntityProxyTypeInfo_ProxyHasWrongWrapper); } return((object)entityWrapper); }); this.Proxy_SetEntityWrapper = ((Expression <Func <object, object, object> >)((parameterExpression1, parameterExpression2) => Expression.Assign((Expression)Expression.Field((Expression)Expression.Convert((Expression)parameterExpression4, field.DeclaringType), field), parameterExpression2))).Compile(); ParameterExpression parameterExpression6 = Expression.Parameter(typeof(string), "propertyName"); MethodInfo publicInstanceMethod1 = proxyType.GetPublicInstanceMethod("GetBasePropertyValue", typeof(string)); if (publicInstanceMethod1 != (MethodInfo)null) { this._baseGetter = Expression.Lambda <Func <object, string, object> >((Expression)Expression.Call((Expression)Expression.Convert((Expression)parameterExpression4, proxyType), publicInstanceMethod1, (Expression)parameterExpression6), parameterExpression4, parameterExpression6).Compile(); } ParameterExpression parameterExpression7 = Expression.Parameter(typeof(object), "propertyName"); MethodInfo publicInstanceMethod2 = proxyType.GetPublicInstanceMethod("SetBasePropertyValue", typeof(string), typeof(object)); if (publicInstanceMethod2 != (MethodInfo)null) { this._baseSetter = ((Expression <Action <object, string, object> >)((parameterExpression1, parameterExpression2, parameterExpression3) => Expression.Call((Expression)Expression.Convert(parameterExpression1, proxyType), publicInstanceMethod2, parameterExpression2, parameterExpression3))).Compile(); } this._propertiesWithBaseGetter = new HashSet <string>(baseGetters.Select <PropertyInfo, string>((Func <PropertyInfo, string>)(p => p.Name))); this._propertiesWithBaseSetter = new HashSet <string>(baseSetters.Select <PropertyInfo, string>((Func <PropertyInfo, string>)(p => p.Name))); this._createObject = DelegateFactory.CreateConstructor(proxyType); }
/// <summary> /// Creates an instance with an empty constructor. /// </summary> /// <param name="type">The type</param> /// <param name="constructor">The constructor info</param> /// <returns>The instance created</returns> public object CreateInstanceWithEmptyConstructor(Type type, ConstructorInfo constructor) { if (this.FactoryCache.TryGetValue(type, out Func <object> factory)) { return(factory()); } else { factory = DelegateFactory.CreateConstructor <object>(type, constructor); FactoryCache[type] = factory; return(factory()); } }
public void CreateConstructorInternal() { Type type = typeof(InternalClass); Stopwatch watch = Stopwatch.StartNew(); LateBoundConstructor c = DelegateFactory.CreateConstructor(type); watch.Stop(); Console.WriteLine("Time: {0}ms", watch.ElapsedMilliseconds); Assert.IsNotNull(c); object o = c.Invoke(); Assert.IsNotNull(o); Assert.IsTrue(o.GetType() == type); }
internal EntityProxyTypeInfo( Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List <PropertyInfo> baseGetters, List <PropertyInfo> baseSetters) { DebugCheck.NotNull(proxyType); _proxyType = proxyType; _entityType = ospaceEntityType; _initializeCollections = initializeCollections; _navigationPropertyAssociationTypes = new Dictionary <Tuple <string, string>, AssociationType>(); foreach (var navigationProperty in ospaceEntityType.NavigationProperties) { _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); if (navigationProperty.RelationshipType.Name != navigationProperty.RelationshipType.FullName) { // Sometimes there isn't enough metadata to have a container name // Default codegen doesn't qualify names _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.Name, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); } } var entityWrapperField = proxyType.GetField( EntityWrapperFieldName, BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); var Object_Parameter = Expression.Parameter(typeof(object), "proxy"); var Value_Parameter = Expression.Parameter(typeof(object), "value"); Debug.Assert(entityWrapperField != null, "entityWrapperField does not exist"); // Create the Wrapper Getter var lambda = Expression.Lambda <Func <object, object> >( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Object_Parameter); var getEntityWrapperDelegate = lambda.Compile(); Proxy_GetEntityWrapper = (object proxy) => { // This code validates that the wrapper points to the proxy that holds the wrapper. // This guards against mischief by switching this wrapper out for another one obtained // from a different object. var wrapper = ((IEntityWrapper)getEntityWrapperDelegate(proxy)); if (wrapper != null && !ReferenceEquals(wrapper.Entity, proxy)) { throw new InvalidOperationException(Strings.EntityProxyTypeInfo_ProxyHasWrongWrapper); } return(wrapper); }; // Create the Wrapper setter Proxy_SetEntityWrapper = Expression.Lambda <Func <object, object, object> >( Expression.Assign( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Value_Parameter), Object_Parameter, Value_Parameter).Compile(); var PropertyName_Parameter = Expression.Parameter(typeof(string), "propertyName"); var baseGetterMethod = proxyType.GetMethod( "GetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string) }, null); if (baseGetterMethod != null) { _baseGetter = Expression.Lambda <Func <object, string, object> >( Expression.Call(Expression.Convert(Object_Parameter, proxyType), baseGetterMethod, PropertyName_Parameter), Object_Parameter, PropertyName_Parameter).Compile(); } var PropertyValue_Parameter = Expression.Parameter(typeof(object), "propertyName"); var baseSetterMethod = proxyType.GetMethod( "SetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string), typeof(object) }, null); if (baseSetterMethod != null) { _baseSetter = Expression.Lambda <Action <object, string, object> >( Expression.Call( Expression.Convert(Object_Parameter, proxyType), baseSetterMethod, PropertyName_Parameter, PropertyValue_Parameter), Object_Parameter, PropertyName_Parameter, PropertyValue_Parameter).Compile(); } _propertiesWithBaseGetter = new HashSet <string>(baseGetters.Select(p => p.Name)); _propertiesWithBaseSetter = new HashSet <string>(baseSetters.Select(p => p.Name)); _createObject = DelegateFactory.CreateConstructor(proxyType); }
/// <summary> /// Initializes a new instance of the <see cref="TypeAccessor"/> class. /// </summary> /// <param name="type">The <see cref="Type"/> this accessor is for.</param> public TypeAccessor(Type type) { _type = type; _lateBoundConstructor = new Lazy <LateBoundConstructor>(() => DelegateFactory.CreateConstructor(_type)); }