This project is read-only.

Quick Start Guide

Architecture Overview

MsOrmCodeGen is comprised of two main interfaces, both of which are provided in the Jodo.CodeGenerator.Core assembly:

public interface IEntityProvider
{
        string Name { get; }
        IEnumerable<IEntity> FindEntities(IConfigurationData configurationData, IMemberFactory memberFactory);
}


public interface ICodeGenerator
{
	void GenerateCodeFor(IEnumerable<IEntity> entities);
	string GetCodeOutput();
	event EventHandler<CodeGenerationCompletedArgs> CodeGenerationCompleted;
}


The IEntityProvider interface is used to build a collection of IEntity types. The IEntity interface defines the members of a type for which code will be generated. The ICodeGenerator interface has one main member, GenerateCodeFor, which takes a collection of IEntity types, which can be provided via the IEntityProvider interface, and is responsible for generating code based on the IEntity definitions and whatever strategy its implementation provides. The GetCodeOutput member will return the generated code.

Assemblies

Jodo.CodeGenerator.Core
This is a small code generation framework which provides interface contracts for generation of CLR types such as classes and interfaces. It also provides base classes for a very lightweight templating engine.

MsOrmCodeGen uses this framework to construct implementations of three IEntityProviders and the MsOrmCodeGen ICodeGenerator. This framework could be used for any number of code generation scenarios other then MsOrmCodeGen.

Jodo.CodeGenerator.EdmgenEntityProvider
This is an implementation of an IEntityProvider, which relies on the Microsoft-provided Entity Framework code generator Edmgen.exe to build a collection of IEntity types based on a database schema. The code generated from running Edmgen.exe is parsed to build IEntity types that conform to the requirements of Poco. Edmgen.exe is also leveraged to generate the necessary Xml mapping required to support the generated code.

Note: The Visual Studio solution contains a "post-build" task for this project that dumps its output into the MsOrmCodeGen's bin. Since MsOrmCodeGen does not contain a hard reference to this assembly, this keeps development moving quickly.

Jodo.CodeGenerator.SqlMetalEntityProvider
This is an implementation of an IEntityProvider, which relies on the Microsoft-provided Linq to Sql code generator SqlMetal.exe to build a collection of IEntity types based on a database schema. The code generated from running Sqlmetal.exe is parsed to build IEntity types that conform to the requirements of Poco. Sqlmetal.exe is also leveraged to generate the necessary Xml mapping required to support the generated code.

Note: The Visual Studio solution contains a "post-build" task for this project that dumps its output into the MsOrmCodeGen's bin. Since MsOrmCodeGen does not contain a hard reference to this assembly, this keeps development moving quickly.

Jodo.CodeGenerator.EdmgenSqlMetalEntityProvider
This is an implementation of an IEntityProvider which internally wraps and executes the IEntityProviders found in the Jodo.CodeGenerator.EdmgenEntityProvider and Jodo.CodeGenerator.SqlMetalEntityProvider assemblies. Both IEntityProviders are executed so that all necessary Xml mapping code needed to support Entity Framework and Linq to Sql will be generated. Even though this provider is dependent on the Jodo.CodeGenerator.EdmgenEntityProvider and the Jodo.CodeGenerator.SqlMetalEntityProvider, it does not hold hard references to these assemblies and resolves them at run-time in order to keep all provider implementations independent of each other and easily swappable without potential version conflicts.

Note: The Visual Studio solution contains a "post-build" task for this project that dumps its output into the MsOrmCodeGen's bin. Since MsOrmCodeGen does not contain a hard reference to this assembly, this keeps development moving quickly.

Jodo.CodeGenerator.MsOrmCodeGen
This is an implementation of an ICodeGenerator and is responsible for taking a collection of IEntity types provided by any of the above mentioned IEntityProviders, and building a set of Dto classes that will be compliant with the requirements of Entity Framework and Linq to Sql.

Note: The Visual Studio solution contains a "post-build" task for this project that dumps its output into the MsOrmCodeGen's bin. Since MsOrmCodeGen does not contain a hard reference to this assembly, this keeps development moving quickly.

CodeGeneratorFake
This project has been included to provide an example of the extensibility provided by Jodo.CodeGenerator.Core's loosely coupled architecture. The project includes a bare bones implementation of an IEntityProvider and ICodeGenerator. Reviewing this project will display exactly what is needed to author your own IEntityProvider or ICodeGenerator and have them plug into the provided WinForm client (MsOrmCodeGen). If you build this project and place the generated .dll in the "CodeGenerator" directory of the MsOrmCodeGen client, it will be discovered and runnable.

Note the "[Export(typeof(IEntity))]" attributes that decorate the concrete classes in this assembly. These allow the Managed Extensibility Framework (MEF) to discover these implementations and expose them as composable parts that will fulfill the contracts required by the MsOrmCodeGen client.

MsOrmCodeGen
This is a WinForms client that is made to work with the Jodo.CodeGenerator.MsOrmCodeGen code generator and provides an easy to use GUI for gathering the required data and executing the code generator. Even though the client is specifically made to support Jodo.CodeGenerator.MsOrmCodeGen, it does not maintain a hard reference to it and resolves an implementation of an IEntityProvider and ICodeGenerator at run-time using MEF (Managed Extensibility Framework).

This application's start-up directory contains an "EntityProvider" directory and a "CodeGenerator" directory where implementations of IEntityProviders and ICodeGenerators will be discovered and executed at run-time. You can drop new implementation in these directories in order to change the clients behavior. The client does support the presentation and selection of any number of IEntityProviders (it will display however many you put in the "EntityProvider" directory), but only supports the execution of one ICodeGenerator and will execute the first one it finds (you should only place the one you want to use in the "CodeGenerator" directory).

Known Caveats

When using the IEntityProvider that generates code for both Entity Framework and Linq to Sql (Jodo.CodeGenerator.EdmgenSqlMetalEntityProvider), there are a few things to be aware of. As stated, under the covers, MsOrmCodeGen uses the Microsoft-provided code generation tools to perform a lot of the heavy lifting. Both of these tools, Edmgen.exe and SqlMetal.exe, deal with certain naming conventions in different ways, and these potential differences will make for incapabilities when trying to use one set of Dtos with both technologies. The issue arises in a couple of scenarios:
  • When table or view names contain spaces or words separated by a period, such as "Customer.Address":
SqlMetal will replace a period with an underscore, while Edmgen will completely remove any part of the name before the period. With a table named "Customer.Address", SqlMetal will generate a class named "CustomerAddress", while Edmgen will create a class named "Address". In a case where you are using only one set of Dtos with both technologies, one convention has to win, and MsOrmCodeGen allows Edmgen's conventions to win. This leaves a Linq to Sql Xml mapping file that is looking for a class named "CustomerAddress" which does not exist. This problem has been somewhat mitigated by combining both Edmgen and Sqlmetal classes into one union'ed set. The EntityProviders could be further built out to deal with this issue better, but as for now I consider this a fringe case that is not a high priority. Generally speaking, I believe it is bad practice to name tables or views with periods or spaces, and if avoided this issue would be alleviated.
  • Multiple foreign key relationships to the same table within a table:
If table A has a foreign key relationship with table B, on two different columns, Edmgen and SqlMetal have different conventions for auto-generating the navigation property names that will be created. Edmgen will suffix the names with numbers, so NavigationProp1, NavigationProp2, etc, SqlMetal will generate more descriptive names. Once again you are potentially left with one of the mapping files looking for property names that do not exist on the Dto classes. This problem has been somewhat mitigated by union'ing both Edmgen and SqlMetal property names into one complete set for each generated class. This allows access to the data you might need, but would force you to access that data with different property names depending on the technology you are using. I feel this issue is reasonably dealt with at this time and is also somewhat fringe and has yet to cause me too much grief. If I find this becomes more of an issue in the future, this scenario could be improved.

Road Map

  • Provide Unit Tests

Last edited Jan 31, 2011 at 3:26 AM by jodomofo, version 39

Comments

No comments yet.