From: <fab...@us...> - 2009-07-17 20:36:52
|
Revision: 4651 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4651&view=rev Author: fabiomaulo Date: 2009-07-17 20:36:48 +0000 (Fri, 17 Jul 2009) Log Message: ----------- Fix NH-1892 (cache configuration by code) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/ConfigurationExtensions.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/EntityCacheConfigurationProperties.cs trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IEntityCacheConfigurationProperties.cs trunk/nhibernate/src/NHibernate/Util/ExpressionsHelper.cs trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityCacheConfigurationFixture.cs trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.cs trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.hbm.xml trunk/nhibernate/src/NHibernate.Test/UtilityTest/ExpressionsHelperFixture.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/ConfigurationExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/ConfigurationExtensions.cs 2009-07-17 17:02:38 UTC (rev 4650) +++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/ConfigurationExtensions.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -1,5 +1,6 @@ using System; using NHibernate.Hql; + namespace NHibernate.Cfg.Loquacious { public static class ConfigurationExtensions @@ -51,5 +52,24 @@ dataBaseIntegration(new DbIntegrationConfigurationProperties(configuration)); return configuration; } + + public static Configuration EntityCache<TEntity>(this Configuration configuration, Action<IEntityCacheConfigurationProperties<TEntity>> entityCacheConfiguration) + where TEntity : class + { + var ecc = new EntityCacheConfigurationProperties<TEntity>(); + entityCacheConfiguration(ecc); + if (ecc.Strategy.HasValue) + { + configuration.SetCacheConcurrencyStrategy(typeof (TEntity).FullName, EntityCacheUsageParser.ToString(ecc.Strategy.Value), + ecc.RegionName); + } + foreach (var collection in ecc.Collections) + { + configuration.SetCollectionCacheConcurrencyStrategy(collection.Key, + EntityCacheUsageParser.ToString(collection.Value.Strategy), + collection.Value.RegionName); + } + return configuration; + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/EntityCacheConfigurationProperties.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/EntityCacheConfigurationProperties.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/EntityCacheConfigurationProperties.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,65 @@ +using System; +using System.Collections; +using System.Linq.Expressions; +using System.Collections.Generic; +using NHibernate.Util; + +namespace NHibernate.Cfg.Loquacious +{ + internal class EntityCacheConfigurationProperties<TEntity> : IEntityCacheConfigurationProperties<TEntity> + where TEntity : class + { + private readonly Dictionary<string, IEntityCollectionCacheConfigurationProperties> collections; + + public EntityCacheConfigurationProperties() + { + collections = new Dictionary<string, IEntityCollectionCacheConfigurationProperties>(10); + Strategy = null; + } + + #region Implementation of IEntityCacheConfigurationProperties + + public EntityCacheUsage? Strategy { set; get; } + public string RegionName { set; get; } + + public void Collection<TCollection>(Expression<Func<TEntity, TCollection>> collectionProperty, + Action<IEntityCollectionCacheConfigurationProperties> collectionCacheConfiguration) + where TCollection : IEnumerable + { + if (collectionProperty == null) + { + throw new ArgumentNullException("collectionProperty"); + } + var mi = ExpressionsHelper.DecodeMemberAccessExpression(collectionProperty); + if(mi.DeclaringType != typeof(TEntity)) + { + throw new ArgumentOutOfRangeException("collectionProperty", "Collection not owned by " + typeof (TEntity).FullName); + } + var ecc = new EntityCollectionCacheConfigurationProperties(); + collectionCacheConfiguration(ecc); + collections.Add(typeof (TEntity).FullName + "." + mi.Name, ecc); + } + + #endregion + + public IDictionary<string, IEntityCollectionCacheConfigurationProperties> Collections + { + get { return collections; } + } + } + + internal class EntityCollectionCacheConfigurationProperties : IEntityCollectionCacheConfigurationProperties + { + public EntityCollectionCacheConfigurationProperties() + { + Strategy = EntityCacheUsage.ReadWrite; + } + + #region Implementation of IEntityCollectionCacheConfigurationProperties + + public EntityCacheUsage Strategy { get; set; } + public string RegionName { get; set; } + + #endregion + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IEntityCacheConfigurationProperties.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IEntityCacheConfigurationProperties.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IEntityCacheConfigurationProperties.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,21 @@ +using System; +using System.Linq.Expressions; +using System.Collections; + +namespace NHibernate.Cfg.Loquacious +{ + public interface IEntityCollectionCacheConfigurationProperties + { + EntityCacheUsage Strategy { get; set; } + string RegionName { get; set; } + } + + public interface IEntityCacheConfigurationProperties<TEntity> where TEntity: class + { + EntityCacheUsage? Strategy { get; set; } + string RegionName { get; set; } + + void Collection<TCollection>(Expression<Func<TEntity, TCollection>> collectionProperty, Action<IEntityCollectionCacheConfigurationProperties> collectionCacheConfiguration) + where TCollection : IEnumerable; + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-07-17 17:02:38 UTC (rev 4650) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-07-17 20:36:48 UTC (rev 4651) @@ -464,6 +464,7 @@ <Compile Include="Cfg\Loquacious\CacheConfiguration.cs" /> <Compile Include="Cfg\Loquacious\ConfigurationExtensions.cs" /> <Compile Include="Cfg\Loquacious\DbIntegrationConfiguration.cs" /> + <Compile Include="Cfg\Loquacious\EntityCacheConfigurationProperties.cs" /> <Compile Include="Cfg\Loquacious\FluentSessionFactoryConfiguration.cs" /> <Compile Include="Cfg\Loquacious\IBatcherConfiguration.cs" /> <Compile Include="Cfg\Loquacious\ICacheConfiguration.cs" /> @@ -472,6 +473,7 @@ <Compile Include="Cfg\Loquacious\IConnectionConfiguration.cs" /> <Compile Include="Cfg\Loquacious\IDbIntegrationConfiguration.cs" /> <Compile Include="Cfg\Loquacious\IDbSchemaIntegrationConfiguration.cs" /> + <Compile Include="Cfg\Loquacious\IEntityCacheConfigurationProperties.cs" /> <Compile Include="Cfg\Loquacious\IFluentSessionFactoryConfiguration.cs" /> <Compile Include="Cfg\Loquacious\IMappingsConfiguration.cs" /> <Compile Include="Cfg\Loquacious\IProxyConfiguration.cs" /> @@ -638,6 +640,7 @@ <Compile Include="Type\DbTimestampType.cs" /> <Compile Include="Type\DefaultCollectionTypeFactory.cs" /> <Compile Include="Bytecode\ICollectionTypeFactory.cs" /> + <Compile Include="Util\ExpressionsHelper.cs" /> <Compile Include="Util\NullableDictionary.cs" /> <Compile Include="Hql\Ast\ANTLR\Util\PathHelper.cs" /> <Compile Include="Hql\Ast\ANTLR\Util\SyntheticAndFactory.cs" /> Added: trunk/nhibernate/src/NHibernate/Util/ExpressionsHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/ExpressionsHelper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Util/ExpressionsHelper.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,19 @@ +using System.Linq.Expressions; +using System.Reflection; +using System; + +namespace NHibernate.Util +{ + public static class ExpressionsHelper + { + public static MemberInfo DecodeMemberAccessExpression<TEntity, TResult>(Expression<Func<TEntity, TResult>> expression) + { + if (expression.Body.NodeType != ExpressionType.MemberAccess) + { + throw new HibernateException( + string.Format("Invalid expression type: Expected ExpressionType.MemberAccess, Found {0}", expression.Body.NodeType)); + } + return ((MemberExpression)expression.Body).Member; + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityCacheConfigurationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityCacheConfigurationFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityCacheConfigurationFixture.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,83 @@ +using System; +using NHibernate.Cfg; +using NHibernate.Cfg.Loquacious; +using NHibernate.Mapping; +using NUnit.Framework; + +namespace NHibernate.Test.CfgTest.Loquacious +{ + [TestFixture] + public class EntityCacheConfigurationFixture + { + [Test] + public void ConfigureCacheOfClass() + { + Configuration configure = new Configuration().Configure(); + configure.AddResource("NHibernate.Test.CfgTest.Loquacious.EntityToCache.hbm.xml", GetType().Assembly); + + configure.EntityCache<EntityToCache>(ce => + { + ce.Strategy = EntityCacheUsage.NonStrictReadWrite; + ce.RegionName = "MyRegion"; + }); + + var pc = (RootClass) configure.GetClassMapping(typeof (EntityToCache)); + Assert.That(pc.CacheConcurrencyStrategy, + Is.EqualTo(EntityCacheUsageParser.ToString(EntityCacheUsage.NonStrictReadWrite))); + Assert.That(pc.CacheRegionName, Is.EqualTo("MyRegion")); + } + + [Test] + public void ConfigureCacheOfCollection() + { + Configuration configure = new Configuration().Configure(); + configure.AddResource("NHibernate.Test.CfgTest.Loquacious.EntityToCache.hbm.xml", GetType().Assembly); + + configure.EntityCache<EntityToCache>(ce => + { + ce.Strategy = EntityCacheUsage.NonStrictReadWrite; + ce.RegionName = "MyRegion"; + ce.Collection(e => e.Elements, cc => + { + cc.RegionName = "MyCollectionRegion"; + cc.Strategy = + EntityCacheUsage.NonStrictReadWrite; + }); + }); + + Mapping.Collection pc = configure.GetCollectionMapping("NHibernate.Test.CfgTest.Loquacious.EntityToCache.Elements"); + Assert.That(pc.CacheConcurrencyStrategy, + Is.EqualTo(EntityCacheUsageParser.ToString(EntityCacheUsage.NonStrictReadWrite))); + Assert.That(pc.CacheRegionName, Is.EqualTo("MyCollectionRegion")); + } + + [Test] + public void ConfigureCacheOfCollectionWithOutEntity() + { + Configuration configure = new Configuration().Configure(); + configure.AddResource("NHibernate.Test.CfgTest.Loquacious.EntityToCache.hbm.xml", GetType().Assembly); + + configure.EntityCache<EntityToCache>(ce => ce.Collection(e => e.Elements, cc => + { + cc.RegionName = "MyCollectionRegion"; + cc.Strategy = + EntityCacheUsage.NonStrictReadWrite; + })); + + var pc = (RootClass) configure.GetClassMapping(typeof (EntityToCache)); + Assert.That(pc.CacheConcurrencyStrategy, Is.Null); + } + + [Test] + public void NotAllowRelatedCollections() + { + Configuration configure = new Configuration().Configure(); + configure.AddResource("NHibernate.Test.CfgTest.Loquacious.EntityToCache.hbm.xml", GetType().Assembly); + + var exception = + Assert.Throws<ArgumentOutOfRangeException>( + () => configure.EntityCache<EntityToCache>(ce => ce.Collection(e => e.Relation.Elements, cc => { }))); + Assert.That(exception.Message, Text.Contains("Collection not owned by")); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.CfgTest.Loquacious +{ + public class EntityToCache + { + public string Name { get; set; } + public IList<string> Elements { get; set; } + public AnotherEntity Relation { get; set; } + } + + public class AnotherEntity + { + public IList<string> Elements { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/CfgTest/Loquacious/EntityToCache.hbm.xml 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.CfgTest.Loquacious" + assembly="NHibernate.Test"> + + <class name="EntityToCache"> + <id name="Id" type="Int32"> + <generator class="hilo" /> + </id> + + <property name="Name" /> + <bag name="Elements"> + <key column="parentId"/> + <element type="string"/> + </bag> + </class> +</hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-07-17 17:02:38 UTC (rev 4650) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-07-17 20:36:48 UTC (rev 4651) @@ -109,6 +109,8 @@ <Compile Include="CfgTest\HbmOrderingFixture.cs" /> <Compile Include="CfgTest\LocatedInTestAssembly.cs" /> <Compile Include="CfgTest\Loquacious\ConfigurationFixture.cs" /> + <Compile Include="CfgTest\Loquacious\EntityCacheConfigurationFixture.cs" /> + <Compile Include="CfgTest\Loquacious\EntityToCache.cs" /> <Compile Include="CfgTest\Loquacious\LambdaConfigurationFixture.cs" /> <Compile Include="CfgTest\MappingDocumentAggregatorTests.cs" /> <Compile Include="CfgTest\MappingDocumentParserTests.cs" /> @@ -1368,6 +1370,7 @@ <Compile Include="UserCollection\User.cs" /> <Compile Include="UserCollection\UserCollectionTypeTest.cs" /> <Compile Include="UtilityTest\AssemblyQualifiedTypeNameFixture.cs" /> + <Compile Include="UtilityTest\ExpressionsHelperFixture.cs" /> <Compile Include="UtilityTest\IdentityMapFixture.cs" /> <Compile Include="UtilityTest\IdentityMapSequencedFixture.cs" /> <Compile Include="UtilityTest\JoinedEnumerableFixture.cs" /> @@ -1957,6 +1960,7 @@ <EmbeddedResource Include="Bytecode\Lightweight\ProductLine.hbm.xml" /> <EmbeddedResource Include="DriverTest\MultiTypeEntity.hbm.xml" /> <EmbeddedResource Include="Criteria\Lambda\Mappings.hbm.xml" /> + <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> <EmbeddedResource Include="NHSpecificTest\NH1877\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1868\Mappings.hbm.xml" /> Added: trunk/nhibernate/src/NHibernate.Test/UtilityTest/ExpressionsHelperFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/UtilityTest/ExpressionsHelperFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/UtilityTest/ExpressionsHelperFixture.cs 2009-07-17 20:36:48 UTC (rev 4651) @@ -0,0 +1,39 @@ +using NHibernate.Util; +using NUnit.Framework; +using System.Collections.Generic; + +namespace NHibernate.Test.UtilityTest +{ + public class TestingClass + { + public int IntProp + { + get { return 0; } + } + + public bool BoolProp + { + get { return false; } + } + + public IEnumerable<string> CollectionProp + { + get { return new string[0]; } + } + } + + [TestFixture] + public class ExpressionsHelperFixture + { + [Test] + public void DecodeMemberAccessExpression() + { + Assert.That(ExpressionsHelper.DecodeMemberAccessExpression<TestingClass, int>(x => x.IntProp), + Is.EqualTo(typeof(TestingClass).GetMember("IntProp")[0])); + Assert.That(ExpressionsHelper.DecodeMemberAccessExpression<TestingClass, bool>(x => x.BoolProp), + Is.EqualTo(typeof(TestingClass).GetMember("BoolProp")[0])); + Assert.That(ExpressionsHelper.DecodeMemberAccessExpression<TestingClass, IEnumerable<string>>(x => x.CollectionProp), + Is.EqualTo(typeof(TestingClass).GetMember("CollectionProp")[0])); + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |