The .NE version is also moving to the V3 and you can even more find this next version in http://svn.apache.org/repos/asf/ibatis/trunk/cs/V2/ Don't care to the V2 directory name it will surely be changed to V3.
This version only targets .NET framework >= 2.* The main change are: - use Castle.DynamicProxy V2 - Configuration element can be register in any order. - Configuration can be made by code (alias, typeHandler, resultMap, parameterMap) - External resource now follow the .NET standard access used by Spring, Castle as <sqlMaps> <sqlMap uri="file://../../${directory}/Mapping1.xml"/> <sqlMap uri="assembly://Apache.Ibatis.DataMapper.SqlClient.Test/Maps/Mapping2.xml"/> <sqlMap uri="file://../../Maps/Mapping3.xml"/> <sqlMap uri="file://../../Maps/Mapping4.xml"/> <sqlMap uri="assembly://Apache.Ibatis.DataMapper.SqlClient.Test/Maps/Mapping5.xml"/> </sqlMaps> - Configuration API change following iBATIS 3.0 Whiteboard http://opensource.atlassian.com/confluence/oss/display/IBATIS/iBATIS+3.0+Whiteboard - iBATIS session access via ISessionFactory Example: /// <summary> /// This module will register the resultMaps under the convention namespace Account /// </summary> public class AccountModule : Module { public override void Load() { RegisterAlias<Account>(); RegisterTypeHandler<bool, OuiNonBoolTypeHandlerCallback>("Varchar"); RegisterResultMap<Account>("account-result-nullable-email") .MappingMember("Id").ToColumnName("Account_ID") .MappingMember("FirstName").ToColumnName("Account_FirstName") .MappingMember("LastName").ToColumnName("Account_LastName") .MappingMember("EmailAddress").ToColumnName("Account_Email"); RegisterParameterMap<Account>("insert-params") .MappingMember("Id").ToColumn("Account_ID") .MappingMember("FirstName").ToColumn("Account_FirstName") .MappingMember("LastName").ToColumn("Account_LastName") .MappingMember("EmailAddress").ToColumn("Account_Email").UsingNullValue(" [EMAIL PROTECTED]") .MappingMember("BannerOption").ToColumn("Account_Banner_Option").UsingDbType("Varchar").UsingType("bool") .MappingMember("CartOption").ToColumn("Account_Cart_Option").WithTypeHandler<HundredsTypeHandlerCallback>(); RegisterResultMap<Account>("account-result-constructor") .UsingConstructor .MappingArgument("identifiant").ToColumnName("Account_ID") .MappingArgument("firstName").ToColumnName("Account_FirstName") .MappingArgument("lastName").ToColumnName("Account_LastName") .MappingMember("EmailAddress").ToColumnName("Account_Email").UsingNullValue(" [EMAIL PROTECTED]") .MappingMember("BannerOption").ToColumnName("Account_Banner_Option").UsingDbType("Varchar").UsingType("bool") .MappingMember("CartOption").ToColumnName("Account_Cart_Option").WithTypeHandler<HundredsTypeHandlerCallback>(); RegisterResultMap<Account>("account-result-joined-document") .MappingMember("id").ToColumnName("Account_ID") .MappingMember("FirstName").ToColumnName("Account_FirstName") .MappingMember("LastName").ToColumnName("Account_LastName") .MappingMember("EmailAddress").ToColumnName("Account_Email").UsingNullValue(" [EMAIL PROTECTED]") .MappingMember("BannerOption").ToColumnName("Account_Banner_Option").UsingDbType("Varchar").UsingType("bool") .MappingMember("CartOption").ToColumnName("Account_Cart_Option").WithTypeHandler<HundredsTypeHandlerCallback>() .MappingMember("Document").UsingResultMap("Document.document"); } } /// <summary> /// This module will register the resultMaps under the specified namespace Document /// </summary> public class DocumentModule : Module { public DocumentModule() : base("Document") { } public override void Load() { RegisterAlias<DocumentCollection>("DocumentCollection"); RegisterResultMap<Document>("baseDocument") .MappingMember("Id").ToColumnName("Document_ID") .MappingMember("Title").ToColumnName("Document_Title"); RegisterResultMap<Newspaper>("newspaper").Extends("baseDocument") .MappingMember("City").ToColumnName("Document_City"); RegisterResultMap<Document>("document").Extends("baseDocument") .MappingMember("Test").ToColumnName("Document_Title") .WithDiscriminator<string>("Document_Type") .UsingResultMap("Document.book").ForValue("Book") .UsingResultMap("newspaper").ForValue("Newspaper"); RegisterResultMap<Document>("document-custom-handler").Extends("baseDocument") .WithDiscriminator<string>("Document_Type") .WithTypeHandler<CustomInheritance>() .UsingResultMap("book").ForValue("Book") .UsingResultMap("newspaper").ForValue("Newspaper"); RegisterResultMap<Book>("book").Extends("document") .MappingMember("PageNumber").ToColumnName("Document_PageNumber"); } } and you configure the stuff like that string resource = "SqlMap_StatementOnly.config"; IConfigurationEngine engine = new DefaultConfigurationEngine(); engine.RegisterInterpreter(new XmlConfigurationInterpreter(resource)); engine.RegisterModule(new AccountModule()); engine.RegisterModule(new DocumentModule()); IMapperFactory mapperFactory = engine.BuildMapperFactory(); dataMapper = ((IDataMapperAccessor)mapperFactory).DataMapper; ISessionFactory sessionFactory = engine.ModelStore.SessionFactory; dataMapper.Insert("InsertAccountViaParameterMap", account); It's not implemented Annotation support nor the auto-generated interface as presented in the Whiteboard for now. I used it with success :-) See unit test for others uses. -- Cheers, Gilles