中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

NHibernate2.1新特性之Tuplizers怎么用

發布時間:2021-12-03 10:37:26 來源:億速云 閱讀:133 作者:小新 欄目:編程語言

這篇文章主要為大家展示了“NHibernate2.1新特性之Tuplizers怎么用”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“NHibernate2.1新特性之Tuplizers怎么用”這篇文章吧。

Tuplizers?這個單詞在英文字典里沒有解釋,和元組(tuple)這個單詞有點相似,在NHibernate中應該翻譯為元組片斷,Tuplizers只在映射中提供,所以叫元組片段映射比較合適。

我們平時一般使用Domain Entity,然后使用< class>來映射,對Domain Entity操作。在NHibernate中,對于Domain Entity的Entity Mode為POCO類型,這時對應的tuplizer知道通過其構造方法來創建一個POCO,再通過其屬性訪問器來訪問POCO屬性。

Tuplizers,其完整命名空間是NHibernate.Tuple.Tuplizer,它就是根據給定的NHibernate.EntityMode,來復現片斷數據。如果給定的片斷數據被認為其是一種數據結構,"tuplizer"就是一個知道如何創建這樣的數據結構,以及如何給這個數據結構賦值的東西。

在NHibernate中有NHibernate.Tuple.Entity.IEntityTuplizer和NHibernate.Tuple.Component.IComponentTuplizer兩個接口,IEntityTuplizer負責管理上面提到的實體的契約,而IComponentTuplizer則是針對組件的。

下面從NHibernate源碼中摘取一個典型的例子來說明Tuplizer的用法。

典型實例

我想映射一個接口,對這個接口按照POCO實體模型進行持久化操作。首先想到應該可以New出來這個接口,使用工廠可以產生出來。在初始化這個接口的時候要重寫一些NHibernate默認的POCO行為,在對這個接口賦值的時候攔截一些操作,記錄下這個接口。獲取接口時候同樣也需要攔截。

1.Domain

public interface IUser  {      int Id { get; set; }      string Name { get; set; }  }

我們需要映射這個接口,但是NHibernate只會去映射類,我們怎么去改寫代碼讓NHibernate可以像類那樣去映射接口呢?這就是Tuplizers的功能。

2.代理標記proxy marker

由于這里是特殊需要,我對其這個代理做個標記,如果某個實體可以轉換為這個代理標記接口就說明是我重寫定義的Domain,

/// < summary>  /// 代理標記  /// 對象實例是代理的一個實例  /// < /summary>  public interface IProxyMarker  {      DataProxyHandler DataHandler { get; }  }


3.DataProxy

利用Castle的攔截器IInterceptor接口對這個代理數據進行攔截,例如在獲取這個代理數據的時候,讓NHibernate按照POCO那樣去把其數據保存到一個字典中。

/// < summary>  /// 利用Castle的攔截器,代理數據DataProxy  /// < /summary>  public sealed class DataProxyHandler:IInterceptor  {      private readonly Dictionary< string, object> data = new Dictionary< string, object>(50);      private readonly string entityName;       public DataProxyHandler(string entityName, object id)      {          this.entityName = entityName;          data["Id"] = id;      }       public string EntityName      {          get { return entityName; }      }       public IDictionary< string, object> Data      {          get { return data; }      }       public void Intercept(IInvocation invocation)      {          invocation.ReturnValue = null;          string methodName = invocation.Method.Name;           if ("get_DataHandler".Equals(methodName))          {              invocation.ReturnValue = this;          }          else if (methodName.StartsWith("set_"))          {              string propertyName = methodName.Substring(4);              data[propertyName] = invocation.Arguments[0];          }          else if (methodName.StartsWith("get_"))          {              string propertyName = methodName.Substring(4);              object value;              data.TryGetValue(propertyName, out value);              invocation.ReturnValue = value;          }          else if ("ToString".Equals(methodName))          {              invocation.ReturnValue = EntityName + "#" + data["Id"];          }          else if ("GetHashCode".Equals(methodName))          {              invocation.ReturnValue = GetHashCode();          }       }  }

4.實體初始化

在映射文件中定義< tuplizers>映射,NHibernate提供的IInstantiator接口實現負責初始化實體實例,這里就是使用Castle.DynamicProxy.ProxyGenerator的public object CreateInterfaceProxyWithoutTarget(System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, params Castle.Core.Interceptor.IInterceptor[] interceptors )方法創建一個接口代理。

/// < summary> /// 利用NH2.1新特性Tuplizers提供的IInstantiator接口實現負責初始化實體/組件實例  /// < /summary> public class EntityInstantiator : IInstantiator  {      private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();      private readonly Type t;       public EntityInstantiator(Type entityType)      {          t = entityType;      }       public object Instantiate()      {          return Instantiate(null);      }       public object Instantiate(object id)      {          return              proxyGenerator.CreateInterfaceProxyWithoutTarget(t, new[] { typeof(IProxyMarker), t }, new DataProxyHandler(t.FullName, id));      }      /// < summary>     /// 判斷是否實例化      /// < /summary>     /// < param name="obj">< /param>     /// < returns>< /returns>     public bool IsInstance(object obj)      {          try          {              return t.IsInstanceOfType(obj);          }          catch (Exception e)          {              throw new Exception("could not get handle to entity-name as interface : " + e);          }      }  }

5.重寫PocoEntityTuplizer

這才是我們真正自定義的Tuplizer,在映射中使用,重寫NHibernate提供的POCO的PocoEntityTuplizer的初始化方法,返回上面實體初始化類完成的創建一個接口代理。

/// < summary>  /// 重寫PocoEntityTuplizer  /// < /summary>  public class EntityTuplizer : PocoEntityTuplizer  {      public EntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) : base(entityMetamodel, mappedEntity) { }       protected override IInstantiator BuildInstantiator(PersistentClass persistentClass)      {          return new EntityInstantiator(persistentClass.MappedClass);      }  }

6.實體攔截

NHibernate可以利用NHibernate.IInterceptor實現攔截這個實體:可以去攔截我們創建一個System.Type代理將出現無法預測的值,在這里我僅僅返回上面定義的IProxyMarker標記數據的實體名稱,對于其他類型的實體則返回空值。

/// < summary>  /// 利用NHibernate.IInterceptor對這個實體實現攔截  /// < /summary>  public class EntityNameInterceptor : EmptyInterceptor  {      public override string GetEntityName(object entity)      {          return ExtractEntityName(entity) ?? base.GetEntityName(entity);      }       private static string ExtractEntityName(object entity)      {          // Our custom Proxy instances actually bundle their appropriate entity name,           //so we simply extract it from there if this represents one of our proxies; otherwise, we return null           var pm = entity as IProxyMarker;          if (pm != null)          {              var myHandler = pm.DataHandler;              return myHandler.EntityName;          }          return null;      }   }

7.EntityFactory

我們創建一個實體工廠,所謂工廠就是New出來實體的一個制造工廠。我們可以var user = entityFactory.NewEntity< IUser>()這樣初始化一個實體。

public class EntityFactory  {      private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();       public T NewEntity< T>()      {          Type t = typeof(T);          return             (T)              proxyGenerator.CreateInterfaceProxyWithoutTarget(t, new[] { typeof(IProxyMarker), t },                                                               new DataProxyHandler(t.FullName, 0));      }  }

上面那些部分相當于一個前奏,為使用tuplizer做準備,我們可以在映射中使用我們自定義的Tuplizer了。

8.映射

這時需要映射這個接口了,使用< tuplizer>映射,這個映射有兩個屬性,分別為class和entity-mode。在這個例子中我在IUser中按照POCO實體模型自定義EntityTuplizer實現來映射。

< class name="IUser">     < tuplizer class="EntityTuplizer" entity-mode="poco"/>     < id name="Id">         < generator class="hilo"/>     < /id>     < property name="Name"/> < /class>

9.測試

測試一下我們的結果吧。分別創建、查詢、刪除操作吧。

[Test]

public void UserCrud()  {      object savedId;      var user = entityFactory.NewEntity< IUser>();      user.Name = "李永京";       using (var session = sessions.OpenSession())      using (var tx = session.BeginTransaction())      {          savedId = session.Save(user);          tx.Commit();      }       using (var session = sessions.OpenSession())      using (var tx = session.BeginTransaction())      {          user = session.Get< IUser>(savedId);          Assert.That(user, Is.Not.Null);          Assert.That(user.Name, Is.EqualTo("李永京"));          session.Delete(user);          tx.Commit();      }       using (var session = sessions.OpenSession())      using (var tx = session.BeginTransaction())      {          user = session.Get< IUser>(savedId);          Assert.That(user, Is.Null);          tx.Commit();      }  }

結語

由于NHibernate資料很少,所以我從源碼中找到這個例子稍微說明下,大家對Tuplizer有什么好的想法可以回復討論下咯,我想這個功能的擴展就是如果NHibernate Domain與WPF結合,我需要在所有Domain中實現INotifyPropertyChanged接口,就需要重新實現DataProxyHandler。

以上是“NHibernate2.1新特性之Tuplizers怎么用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

无棣县| 新源县| 个旧市| 射洪县| 西和县| 临汾市| 扎囊县| 镇平县| 长寿区| 科技| 齐河县| 蚌埠市| 保山市| 凭祥市| 漾濞| 杭州市| 桂阳县| 团风县| 腾冲县| 太康县| 通海县| 长沙县| 平乐县| 安丘市| 青州市| 交口县| 出国| 嘉黎县| 独山县| 临澧县| 讷河市| 临海市| 霞浦县| 微山县| 桐庐县| 吴桥县| 巧家县| 永嘉县| 城固县| 临汾市| 恩施市|