diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs new file mode 100644 index 00000000000..8a7b44db545 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2067/Fixture.cs @@ -0,0 +1,186 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NHibernate.Proxy; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : TestCaseMappingByCode + { + private object domesticCatId; + private object catId; + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.JoinedSubclass(rc => + { + rc.Proxy(typeof(IDomesticCat)); + rc.Property(x => x.OwnerName); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + catId = session.Save(new Cat { Name = "Bob" }); + + domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"}); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // HQL Delete of entities with joins requires temp tables, which are not + // supported by all dialects: use in memory-delete instead. + session.Delete("from System.Object"); + + transaction.Commit(); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingBaseClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingBaseClassInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public void ThrowWhenTryToLoadDomesticCatUsingSealedClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + Assert.ThrowsAsync(() => session.LoadAsync(domesticCatId)); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingSealedClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = (IDomesticCat) await (session.LoadAsync(typeof(DomesticCat), domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public async Task CanLoadDomesticCatUsingSideInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(domesticCatId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public async Task CanLoadCatUsingClassAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(catId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public async Task CanLoadCatUsingInterfaceAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = await (session.LoadAsync(catId)); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs new file mode 100644 index 00000000000..1481b3b5b76 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Domain.cs @@ -0,0 +1,30 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + public interface ICat + { + Guid Id { get; set; } + string Name { get; set; } + } + + public class Cat : ICat + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } + + public interface IPet + { + string OwnerName { get; set; } + } + + public interface IDomesticCat : IPet, ICat + { + } + + public sealed class DomesticCat : Cat, IDomesticCat + { + public string OwnerName { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs new file mode 100644 index 00000000000..e0714225f9c --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2067/Fixture.cs @@ -0,0 +1,175 @@ +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NHibernate.Proxy; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2067 +{ + [TestFixture] + public class Fixture : TestCaseMappingByCode + { + private object domesticCatId; + private object catId; + + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.JoinedSubclass(rc => + { + rc.Proxy(typeof(IDomesticCat)); + rc.Property(x => x.OwnerName); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + catId = session.Save(new Cat { Name = "Bob" }); + + domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"}); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // HQL Delete of entities with joins requires temp tables, which are not + // supported by all dialects: use in memory-delete instead. + session.Delete("from System.Object"); + + transaction.Commit(); + } + } + + [Test] + public void CanLoadDomesticCatUsingBaseClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public void CanLoadDomesticCatUsingBaseClassInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + var domesticCat = (IDomesticCat) cat; + Assert.That(domesticCat.Name, Is.EqualTo("Tom")); + Assert.That(domesticCat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public void CanLoadDomesticCatUsingInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public void ThrowWhenTryToLoadDomesticCatUsingSealedClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + Assert.Throws(() => session.Load(domesticCatId)); + } + } + + [Test] + public void CanLoadDomesticCatUsingSealedClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = (IDomesticCat) session.Load(typeof(DomesticCat), domesticCatId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Tom")); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public void CanLoadDomesticCatUsingSideInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(domesticCatId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.OwnerName, Is.EqualTo("Jerry")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(DomesticCat))); + } + } + + [Test] + public void CanLoadCatUsingClass() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(catId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + + [Test] + public void CanLoadCatUsingInterface() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var cat = session.Load(catId); + Assert.That(cat, Is.Not.Null); + Assert.That(cat.Name, Is.EqualTo("Bob")); + var proxy = (INHibernateProxy) cat; + Assert.That(proxy.HibernateLazyInitializer.PersistentClass, Is.EqualTo(typeof(Cat))); + } + } + } +} diff --git a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs index abd159bf11b..1977b3f4049 100644 --- a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs +++ b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs @@ -176,7 +176,7 @@ protected virtual void GetObjectData(SerializationInfo info, StreamingContext co public void VerifyProxyForClassWithInternalInterface() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -202,7 +202,7 @@ public void VerifyProxyForClassWithAdditionalInterface() // having an additional interface in the interface list, instead of just having INHibernateProxy. // (Quite a loose semantic...) new HashSet { typeof(INHibernateProxy), typeof(IPublic) }, - null, null, null); + null, null, null, false); #if NETFX VerifyGeneratedAssembly( @@ -226,7 +226,7 @@ public void VerifyProxyForClassWithInterface() typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -266,7 +266,7 @@ public void VerifyProxyForClassWithExplicitInterface() typeof(PublicExplicitInterfaceTestClass).FullName, typeof(PublicExplicitInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -307,7 +307,8 @@ public void VerifyProxyForRefOutClass() new HashSet { typeof(INHibernateProxy) }, null, null, - null); + null, + true); #if NETFX VerifyGeneratedAssembly( @@ -350,7 +351,7 @@ public void VerifyProxyForAbstractClass() typeof(AbstractTestClass).FullName, typeof(AbstractTestClass), new HashSet { typeof(INHibernateProxy) }, - null, null, null); + null, null, null, true); #if NETFX VerifyGeneratedAssembly( @@ -370,7 +371,7 @@ public void VerifyProxyForAbstractClass() public void InitializedProxyStaysInitializedAfterDeserialization() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = factory.GetProxy(2, null); Assert.That(proxy, Is.Not.Null, "proxy"); Assert.That(NHibernateUtil.IsInitialized(proxy), Is.False, "proxy already initialized after creation"); @@ -399,7 +400,7 @@ public void InitializedProxyStaysInitializedAfterDeserialization() public void NonInitializedProxyStaysNonInitializedAfterSerialization() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(SimpleTestClass).FullName, typeof(SimpleTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = factory.GetProxy(2, null); Assert.That(proxy, Is.Not.Null, "proxy"); Assert.That(NHibernateUtil.IsInitialized(proxy), Is.False, "proxy already initialized after creation"); @@ -422,7 +423,7 @@ public void NonInitializedProxyStaysNonInitializedAfterSerialization() public void CanSerializeFieldInterceptorProxy() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(PublicInterfaceTestClass).FullName, typeof(PublicInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (PublicInterfaceTestClass) factory.GetFieldInterceptionProxy(); proxy.Id = 1; @@ -440,7 +441,7 @@ public void CanSerializeFieldInterceptorProxy() public void CanSerializeFieldInterceptorProxyWithISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (CustomSerializationClass) factory.GetFieldInterceptionProxy(); proxy.Id = 2; @@ -458,7 +459,7 @@ public void CanSerializeFieldInterceptorProxyWithISerializableEntity() public void CanSerializeFieldInterceptorProxyWithExplicitISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomExplicitSerializationClass).FullName, typeof(CustomExplicitSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomExplicitSerializationClass).FullName, typeof(CustomExplicitSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); var proxy = (CustomExplicitSerializationClass) factory.GetFieldInterceptionProxy(); proxy.Id = 2; @@ -476,7 +477,7 @@ public void CanSerializeFieldInterceptorProxyWithExplicitISerializableEntity() public void VerifyFieldInterceptorProxy() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(InternalInterfaceTestClass).FullName, typeof(InternalInterfaceTestClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -493,7 +494,7 @@ public void VerifyFieldInterceptorProxy() public void VerifyFieldInterceptorProxyWithISerializableEntity() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null); + factory.PostInstantiate(typeof(CustomSerializationClass).FullName, typeof(CustomSerializationClass), new HashSet {typeof(INHibernateProxy)}, null, null, null, true); #if NETFX VerifyGeneratedAssembly( () => @@ -521,7 +522,7 @@ public void VerifyFieldInterceptorProxyWithAdditionalInterface() // to an instance of the persistentClass, and so cannot implement interface methods if it does not // inherit the persistentClass. new HashSet {typeof(INHibernateProxy), typeof(IPublic)}, - null, null, null); + null, null, null, false); #if NETFX VerifyGeneratedAssembly( () => diff --git a/src/NHibernate/Proxy/AbstractProxyFactory.cs b/src/NHibernate/Proxy/AbstractProxyFactory.cs index 39dfd8cab2f..6639010ae46 100644 --- a/src/NHibernate/Proxy/AbstractProxyFactory.cs +++ b/src/NHibernate/Proxy/AbstractProxyFactory.cs @@ -18,16 +18,39 @@ public abstract class AbstractProxyFactory: IProxyFactory protected virtual MethodInfo GetIdentifierMethod { get; private set; } protected virtual MethodInfo SetIdentifierMethod { get; private set; } protected virtual IAbstractComponentType ComponentIdType { get; private set; } + protected virtual bool IsClassProxy { get; private set; } protected virtual bool OverridesEquals { get; set; } - protected bool IsClassProxy + public virtual void PostInstantiate( + string entityName, + System.Type persistentClass, + ISet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) { - get { return Interfaces.Length == 1; } +#pragma warning disable 618 + PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType); +#pragma warning restore 618 + IsClassProxy = isClassProxy; } - public virtual void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, - MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, - IAbstractComponentType componentIdType) + // Since v5.3 + [Obsolete("Override PostInstantiate method with isClassProxy parameter instead.")] + public virtual void PostInstantiate( + string entityName, + System.Type persistentClass, + ISet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType) { EntityName = entityName; PersistentClass = persistentClass; @@ -42,9 +65,9 @@ public virtual void PostInstantiate(string entityName, System.Type persistentCla SetIdentifierMethod = setIdentifierMethod; ComponentIdType = componentIdType; OverridesEquals = ReflectHelper.OverridesEquals(persistentClass); + IsClassProxy = interfaces.Count == 1; } - public abstract INHibernateProxy GetProxy(object id, ISessionImplementor session); // Since 5.3 diff --git a/src/NHibernate/Proxy/IProxyFactory.cs b/src/NHibernate/Proxy/IProxyFactory.cs index 5e75428a55b..809eb735ea3 100644 --- a/src/NHibernate/Proxy/IProxyFactory.cs +++ b/src/NHibernate/Proxy/IProxyFactory.cs @@ -38,6 +38,8 @@ public interface IProxyFactory /// Essentially equivalent to constructor injection, but contracted /// here via interface. /// + //Since v5.3 + [Obsolete("Use ProxyFactoryExtensions.PostInstantiate extension method instead.")] void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType); @@ -50,7 +52,7 @@ void PostInstantiate(string entityName, System.Type persistentClass, ISetIndicates problems generating requested proxy. INHibernateProxy GetProxy(object id, ISessionImplementor session); - // Since 5.3 + // Since v5.3 [Obsolete("Use ProxyFactoryExtensions.GetFieldInterceptionProxy extension method instead.")] object GetFieldInterceptionProxy(object instanceToWrap); } @@ -82,5 +84,41 @@ public static object GetFieldInterceptionProxy(this IProxyFactory proxyFactory) return proxyFactory.GetFieldInterceptionProxy(null); #pragma warning restore 618 } + + // 6.0 TODO: Move to IProxyFactory + public static void PostInstantiate( + this IProxyFactory pf, + string entityName, + System.Type persistentClass, + HashSet interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) + { + if (pf is AbstractProxyFactory apf) + { + apf.PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType, + isClassProxy); + } + else + { +#pragma warning disable 618 + pf.PostInstantiate( + entityName, + persistentClass, + interfaces, + getIdentifierMethod, + setIdentifierMethod, + componentIdType); +#pragma warning restore 618 + } + } } } diff --git a/src/NHibernate/Proxy/Map/MapProxyFactory.cs b/src/NHibernate/Proxy/Map/MapProxyFactory.cs index 1e6a1f18006..87fe9dc16f4 100644 --- a/src/NHibernate/Proxy/Map/MapProxyFactory.cs +++ b/src/NHibernate/Proxy/Map/MapProxyFactory.cs @@ -8,14 +8,27 @@ namespace NHibernate.Proxy.Map { public class MapProxyFactory : IProxyFactory { + //6.0 TODO: make readonly private string entityName; - #region IProxyFactory Members + //Since v5.3 + [Obsolete("Please use constructor accepting entityName instead.")] + public MapProxyFactory() + { + } + public MapProxyFactory(string entityName) + { + this.entityName = entityName; + } + + //Since v5.3 + [Obsolete("Please use constructor accepting entityName instead.")] public void PostInstantiate(string entityName, System.Type persistentClass, ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) { + //6.0 TODO: throw NotSupportedException in the new override this.entityName = entityName; } @@ -28,7 +41,5 @@ public object GetFieldInterceptionProxy(object getInstance) { throw new NotSupportedException(); } - - #endregion } } diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs index 69400454e7e..70f3af1e2c9 100644 --- a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -16,8 +16,16 @@ public sealed class NHibernateProxyFactoryInfo : ISerializable private readonly MethodInfo _getIdentifierMethod; private readonly MethodInfo _setIdentifierMethod; private readonly IAbstractComponentType _componentIdType; + private readonly bool _isClassProxy; - internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentClass, System.Type[] interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) + internal NHibernateProxyFactoryInfo( + string entityName, + System.Type persistentClass, + System.Type[] interfaces, + MethodInfo getIdentifierMethod, + MethodInfo setIdentifierMethod, + IAbstractComponentType componentIdType, + bool isClassProxy) { _entityName = entityName; _persistentClass = persistentClass; @@ -25,6 +33,7 @@ internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentCla _getIdentifierMethod = getIdentifierMethod; _setIdentifierMethod = setIdentifierMethod; _componentIdType = componentIdType; + _isClassProxy = isClassProxy; } internal System.Type PersistentClass => _persistentClass; @@ -32,7 +41,14 @@ internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentCla public IProxyFactory CreateProxyFactory() { var factory = new StaticProxyFactory(); - factory.PostInstantiate(_entityName, _persistentClass, new HashSet(_interfaces), _getIdentifierMethod, _setIdentifierMethod, _componentIdType); + factory.PostInstantiate( + _entityName, + _persistentClass, + new HashSet(_interfaces), + _getIdentifierMethod, + _setIdentifierMethod, + _componentIdType, + _isClassProxy); return factory; } @@ -44,6 +60,7 @@ private NHibernateProxyFactoryInfo(SerializationInfo info, StreamingContext cont _getIdentifierMethod = (MethodInfo) info.GetValue(nameof(_getIdentifierMethod), typeof(MethodInfo)); _setIdentifierMethod = (MethodInfo) info.GetValue(nameof(_setIdentifierMethod), typeof(MethodInfo)); _componentIdType = (IAbstractComponentType) info.GetValue(nameof(_componentIdType), typeof(IAbstractComponentType)); + _isClassProxy = (bool) info.GetValue(nameof(_isClassProxy), typeof(bool)); } [SecurityCritical] @@ -55,6 +72,7 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) info.AddValue(nameof(_getIdentifierMethod), _getIdentifierMethod); info.AddValue(nameof(_setIdentifierMethod), _setIdentifierMethod); info.AddValue(nameof(_componentIdType), _componentIdType); + info.AddValue(nameof(_isClassProxy), _isClassProxy); } } } diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index 278ac748212..fa324ea574a 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -43,9 +43,10 @@ public override void PostInstantiate( ISet interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, - IAbstractComponentType componentIdType) + IAbstractComponentType componentIdType, + bool isClassProxy) { - base.PostInstantiate(entityName, persistentClass, interfaces, getIdentifierMethod, setIdentifierMethod, componentIdType); + base.PostInstantiate(entityName, persistentClass, interfaces, getIdentifierMethod, setIdentifierMethod, componentIdType, isClassProxy); _proxyFactoryInfo = new NHibernateProxyFactoryInfo( EntityName, @@ -53,7 +54,8 @@ public override void PostInstantiate( Interfaces, GetIdentifierMethod, SetIdentifierMethod, - ComponentIdType); + ComponentIdType, + IsClassProxy); _cacheEntry = new ProxyCacheEntry(IsClassProxy ? PersistentClass : typeof(object), Interfaces); } diff --git a/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs index 9efd2af386f..07abc64fce3 100644 --- a/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/DynamicMapEntityTuplizer.cs @@ -60,21 +60,9 @@ protected override IInstantiator BuildInstantiator(PersistentClass mappingInfo) return new DynamicEntityInstantiator(mappingInfo); } - protected override IProxyFactory BuildProxyFactory(PersistentClass mappingInfo, IGetter idGetter, - ISetter idSetter) + protected override IProxyFactory BuildProxyFactory(PersistentClass mappingInfo, IGetter idGetter, ISetter idSetter) { - IProxyFactory pf = new MapProxyFactory(); - try - { - //TODO: design new lifecycle for ProxyFactory - pf.PostInstantiate(EntityName, null, null, null, null, null); - } - catch (HibernateException he) - { - log.Warn(he, "could not create proxy factory for:{0}", EntityName); - pf = null; - } - return pf; + return new MapProxyFactory(EntityName); } } } diff --git a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs index 79285ce1ea9..aaf9140290e 100644 --- a/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs +++ b/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs @@ -5,7 +5,6 @@ using NHibernate.Bytecode; using NHibernate.Classic; using NHibernate.Engine; -using NHibernate.Intercept; using NHibernate.Mapping; using NHibernate.Properties; using NHibernate.Proxy; @@ -108,10 +107,9 @@ protected override IInstantiator BuildInstantiator(PersistentClass persistentCla } } - protected override IProxyFactory BuildProxyFactory(PersistentClass persistentClass, IGetter idGetter, - ISetter idSetter) + protected override IProxyFactory BuildProxyFactory(PersistentClass persistentClass, IGetter idGetter, ISetter idSetter) { - bool needAccesorCheck = true; // NH specific (look the comment below) + bool isInterface = false; // determine the id getter and setter methods from the proxy interface (if any) // determine all interfaces needed by the resulting proxy @@ -120,19 +118,19 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla System.Type _mappedClass = persistentClass.MappedClass; System.Type _proxyInterface = persistentClass.ProxyInterface; - if (_proxyInterface != null && !_mappedClass.Equals(_proxyInterface)) + if (_proxyInterface != null && _mappedClass != _proxyInterface) { if (!_proxyInterface.IsInterface) { throw new MappingException("proxy must be either an interface, or the class itself: " + EntityName); } - needAccesorCheck = false; // NH (the proxy is an interface all properties can be overridden) + isInterface = true; proxyInterfaces.Add(_proxyInterface); } if (_mappedClass.IsInterface) { - needAccesorCheck = false; // NH (the mapped class is an interface all properties can be overridden) + isInterface = true; proxyInterfaces.Add(_mappedClass); } @@ -140,7 +138,7 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla { System.Type subclassProxy = subclass.ProxyInterface; System.Type subclassClass = subclass.MappedClass; - if (subclassProxy != null && !subclassClass.Equals(subclassProxy)) + if (subclassProxy != null && subclassClass != subclassProxy) { if (!subclassProxy.IsInterface) { @@ -155,7 +153,7 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla * - Check if the logger is enabled * - Don't need nothing to check if the mapped-class or proxy is an interface */ - if (log.IsErrorEnabled() && needAccesorCheck) + if (!isInterface && log.IsErrorEnabled()) { LogPropertyAccessorsErrors(persistentClass); } @@ -173,8 +171,16 @@ protected override IProxyFactory BuildProxyFactory(PersistentClass persistentCla IProxyFactory pf = BuildProxyFactoryInternal(persistentClass, idGetter, idSetter); try { - pf.PostInstantiate(EntityName, _mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod, - persistentClass.HasEmbeddedIdentifier ? (IAbstractComponentType) persistentClass.Identifier.Type: null); + pf.PostInstantiate( + EntityName, + _mappedClass, + proxyInterfaces, + proxyGetIdentifierMethod, + proxySetIdentifierMethod, + persistentClass.HasEmbeddedIdentifier + ? (IAbstractComponentType) persistentClass.Identifier.Type + : null, + !isInterface); } catch (HibernateException he) {