NHibernate实现延迟加载的主要结构:

📅 2026/7/6 4:13:05
NHibernate实现延迟加载的主要结构:
BuildSessionFactory的时候1. 根据proxyfactory.factory_class的配置创建IProxyFactoryFactory对象2. 如果use_proxy_validator配置为true默认为true加载实体映射元数据之后对需要代理的实体使用IProxyFactoryFactory的ProxyValidator进行验证例如要求实体有默认构造器、方法属性必须为virtual类型等3. 为需要代理的实体类型创建IProxyFactory并调用IProxyFactory对象的PostInstantiate方法对每一个需要代理的实体类型都会创建一个IProxyFactory对象并缓存创建代理对象则通过IProxyFactory的GetProxy方法完成AbstractProxyFactory主要是实现PostInstantiate方法这个方法主要是将创建代理对象所需的信息记录下来例如EntityName字符串的实体类名、PersistentClass代理对象的System.Type、Interfaces代理对象需要额外实现的接口例如INHibernateProxy其他几个记录的属性则为单主键和组合主键id的get、set方法ProxyFactory则主要实现GetProxy方法使用Castle或者LinFu等动态代理库以及上述信息创建代理对象创建代理对象IProxyFactory.GetProxy方法完成1. 创建一个LazyInitializer对象。LazyInitializer实现了各个动态代理类库的拦截器接口2. 通过Castle、LinFu、Spring等动态代理库创建class proxy或者interface proxy的代理对象创建代理对象时INHibernateProxy作为一个mixin的接口NHibernate内部用这个接口来区分代理对象和真实对象。对这个接口的方法调用则在拦截器中处理延迟加载创建代理对象时均使用NHibernate.ByteCode.LinFu或者NHibernate.ByteCode.Castle中的LazyInitializer类作为拦截器因此对代理对象的方法调用都在LazyInitializer中拦截处理ILazyInitializer接口主要用于延迟加载的相关处理首先对代理对象某些方法的调用不会触发延迟加载行为比如读取主键的值、组合类型属性的主键值、没有override的情况下调用Object基类的一些方法以及Dispose方法等这些逻辑在BasicLazyInitializer的Invoke方法中处理当调用代理对象的其他方法时触发延迟加载行为。加载处理在AbstractLazyInitializer的Initialize方法中完成加载实体所需要的信息主要有session、id、实体的类型在创建LazyInitializer对象时均已经提供加载过程仍然使用一级缓存、二级缓存、数据库这样一个加载顺序加载的实体对象与代理对象是两个独立的对象NHibernate并没有将加载后的实体属性值设置到代理对象上估计一是考虑到有interface proxy存在的情况另外实际加载过程是比较独立的他会重新创建一个真实的实体对象会放入一级、二级缓存中还有一点这种处理方式NHibernate以及client都可以通过代理对象来得到加载后的真实对象。真实的实体对象保存在AbstractLazyInitializer的Target属性中完成加载以后拦截器中通过反射来调用target对象的方法下面代码示例怎么由代理对象得到真实对象非NHibernate官方公布的方法慎用12345678910111213141516ISessionFactory sf newConfiguration().Configure().BuildSessionFactory();using(ISession session sf.OpenSession()){//仅创建代理对象没有实际加载MyUser proxy session.LoadMyUser(11);Console.WriteLine(proxy.GetType().FullName);//因为override了ToString方法因此下面这个调用将触发加载行为Console.WriteLine(proxy.ToString());//获取真实对象NHibernate.Proxy.INHibernateProxy nhProxy proxyasINHibernateProxy;MyUser real nhProxy.HibernateLazyInitializer.GetImplementation()asMyUser;Console.WriteLine(real.GetType().FullName);Console.WriteLine(real.ToString());}sf.Close();Console.ReadKey();下面是运行结果分类: NHibernate