public void TestFixtureSetUp() { _tableDefinition = new TableDefinition { Name = "Table", Columns = new List<ColumnDefinition> { new ColumnDefinition { Name = "Column1", Type = typeof (Guid), IsPrimaryKeyColumn = true }, new ColumnDefinition { Name = "Column2", Type = typeof (int), IsPrimaryKeyColumn = true } } }; var dynamicAssemblyManagerFactory = new DynamicAssemblyManagerFactory(); var dynamicAssemblyManager = dynamicAssemblyManagerFactory.Create("TestDynamicAssembly"); var tableTypes = dynamicAssemblyManager.BuildTypesFor(_tableDefinition); _entityType = tableTypes.EntityType; }
public EntityTypes BuildTypesFor(TableDefinition tableDefinition) { var entityType = CreateEntityType(tableDefinition); var mappingType = CreateMappingType(tableDefinition); return new EntityTypes { EntityType = entityType, MappingType = mappingType, TableDefinition = tableDefinition }; }
private Type CreateMappingType(TableDefinition tableDefinition) { var typeName = tableDefinition.GetMapName(); if (_types.ContainsKey(typeName) == false) { lock (_typeLocker) { if (_types.ContainsKey(typeName) == false) { var type = _mappingTypeBuilder.Build(tableDefinition); _types.TryAdd(typeName, type); } } } return _types[typeName]; }
public Type Build(TableDefinition table) { var entityName = _dynamicAssembly.BuildAssemblyQualifiedTypeName(table.GetEntityName()); var typeBuilder = _dynamicAssembly.CreateType(entityName); var identityProperties = new List<PropertyInfo>(); foreach (var column in table.Columns) { var property = typeBuilder.DefineProperty(column.Name, column.Type); if (column.IsPrimaryKeyColumn) { identityProperties.Add(property); } } if (identityProperties.Any()) { // TODO: i don't think these three methods should be extension methods... typeBuilder.DefineGetHashCodeMethod(identityProperties); var virtualEqualsMethod = typeBuilder.DefineVirtualEqualsMethod(identityProperties); typeBuilder.DefineOverrideEqualsMethod(virtualEqualsMethod, identityProperties); } else { throw new NotSupportedException(String.Format("No primary key columns found for table '{0}'.", entityName)); } var newType = typeBuilder.CreateType(); return newType; }
public Type Build(TableDefinition table) { var mapName = _dynamicAssembly.BuildAssemblyQualifiedTypeName(table.GetMapName()); var entityType = _dynamicAssembly.GetDynamicType(_dynamicAssembly.BuildAssemblyQualifiedTypeName(table.GetEntityName())); var baseClassType = OpenGenericClassMapType.MakeGenericType(entityType); var tableFunction = baseClassType.GetMethod("Table"); var fullFuncType = OpenGenericFuncType.MakeGenericType(entityType, typeof (object)); var filledExpressionType = OpenGenericExpressionType.MakeGenericType(fullFuncType); var lambdaExpressionFunction = OpenGenericLambdaFunction.MakeGenericMethod(fullFuncType); var compositeIdentityPartType = OpenGenericCompositeIdentityPartType.MakeGenericType(entityType); var keyPropertyMethod = compositeIdentityPartType.GetMethod("KeyProperty", new[] { filledExpressionType }); var mapMethod = baseClassType.GetMethod("Map", new[] { filledExpressionType }); var typeBuilder = _dynamicAssembly.CreateType(mapName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit, baseClassType); var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes); var constructorIntermediateLanguageGenerator = constructorBuilder.GetILGenerator(); var baseParameterlessConstructor = baseClassType.GetConstructor(Type.EmptyTypes); if (baseParameterlessConstructor == null) { throw new NullReferenceException(String.Format("Parameterless constructor not found for type '{0}'.", baseClassType)); } constructorIntermediateLanguageGenerator.Emit(OpCodes.Ldarg_0); constructorIntermediateLanguageGenerator.Emit(OpCodes.Call, baseParameterlessConstructor); // TODO: save these LocalBuilders and use them below in calls to stloc?? constructorIntermediateLanguageGenerator.DeclareLocal(typeof (ParameterExpression)); constructorIntermediateLanguageGenerator.DeclareLocal(typeof (ParameterExpression)); constructorIntermediateLanguageGenerator.Emit(OpCodes.Ldarg_0); constructorIntermediateLanguageGenerator.Emit(OpCodes.Ldstr, entityType.Name); constructorIntermediateLanguageGenerator.Emit(OpCodes.Call, tableFunction); constructorIntermediateLanguageGenerator.Emit(OpCodes.Nop); var identityColumns = new List<ColumnDefinition>(); var regularColumns = new List<ColumnDefinition>(); foreach (var columnDefinition in table.Columns) { if (columnDefinition.IsPrimaryKeyColumn) { identityColumns.Add(columnDefinition); } else { regularColumns.Add(columnDefinition); } } if (identityColumns.Count == 0) { } else if (identityColumns.Count == 1) { var column = identityColumns.Single(); var idMethod = baseClassType.GetMethod("Id", new[] { filledExpressionType }); DefineSingleColumnIdMapping(entityType, constructorIntermediateLanguageGenerator, column, idMethod, lambdaExpressionFunction); } else if (identityColumns.Count > 1) { var compositeIdMethod = baseClassType.GetMethod("CompositeId", Type.EmptyTypes); DefineMultipleColumnIdMapping(entityType, constructorIntermediateLanguageGenerator, identityColumns, compositeIdMethod, lambdaExpressionFunction, keyPropertyMethod); } foreach (var column in regularColumns) { DefineColumnMapping(entityType, constructorIntermediateLanguageGenerator, column, lambdaExpressionFunction, mapMethod); } constructorIntermediateLanguageGenerator.Emit(OpCodes.Ret); var newType = typeBuilder.CreateType(); return newType; }