Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the Tuplizers of NHibernate2.1 's new features

2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly shows you "how to use the new features of NHibernate2.1 Tuplizers", the content is easy to understand, clear, hope to help you solve your doubts, the following let the editor lead you to study and learn "how to use the Tuplizers of new features of NHibernate2.1" this article.

Tuplizers? This word is not explained in the English dictionary and is somewhat similar to the word tuple. It should be translated into tuple fragments in NHibernate, and Tuplizers is only provided in mapping, so it is more appropriate to call tuple fragment mapping.

We usually use Domain Entity, and then use

< class>

To map and operate on Domain Entity. In NHibernate, the Entity Mode for Domain Entity is of type POCO, and the corresponding tuplizer knows to create a POCO through its constructor, and then access the POCO property through its property accessor.

Tuplizers, whose full namespace is NHibernate.Tuple.Tuplizer, replicates fragment data based on a given NHibernate.EntityMode. If a given piece of data is considered to be a data structure, "tuplizer" is something that knows how to create such a data structure and how to assign values to it.

There are NHibernate.Tuple.Entity.IEntityTuplizer and NHibernate.Tuple.Component.IComponentTuplizer interfaces in NHibernate, IEntityTuplizer is responsible for managing the contracts of the entities mentioned above, and IComponentTuplizer is for components.

Let's take a typical example from the NHibernate source code to illustrate the use of Tuplizer.

Typical example

I want to map an interface that is persisted according to the POCO entity model. First of all, it should be possible to New this interface, which can be generated by using the factory. Override some of NHibernate's default POCO behavior when initializing the interface, intercept some operations when assigning values to the interface, and record the interface. You also need to intercept when getting an interface.

1.Domain

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

We need to map this interface, but NHibernate only maps classes. How do we rewrite the code so that NHibernate can map interfaces like classes? This is what Tuplizers does.

two。 Proxy tag proxy marker

Because of the special needs here, I mark this agent. If an entity can be converted to this proxy tag interface, it means that I rewrite the defined Domain.

/ / /

< summary>

/ / Agent tag / / object instance is an instance of the agent /

< /summary>

Public interface IProxyMarker {DataProxyHandler DataHandler {get;}}

3.DataProxy

Use Castle's interceptor IInterceptor interface to intercept the proxy data, for example, when getting the proxy data, let NHibernate save its data in a dictionary as POCO does.

/ / /

< summary>

/ / using the interceptor of Castle, proxy data 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. Entity initialization

Defined in the mapping file

< tuplizers>

Mapping. The IInstantiator interface implementation provided by NHibernate is responsible for initializing the entity instance. Here, an interface proxy is created using the public object CreateInterfaceProxyWithoutTarget (System.Type interfaceToProxy, System.Type [] additionalInterfacesToProxy, params Castle.Core.Interceptor.IInterceptor [] interceptors) method of Castle.DynamicProxy.ProxyGenerator.

/ / /

< summary>

/ / using the IInstantiator interface implementation provided by Tuplizers, the new feature of NH2.1, is responsible for initializing entity / component instances /

< /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>

/ / determine whether to instantiate /

< /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. Rewrite PocoEntityTuplizer

This is our really customized Tuplizer, which is used in the mapping to override the initialization method of POCO's PocoEntityTuplizer provided by NHibernate and return the creation of an interface proxy completed by the above entity initialization class.

/ / /

< summary>

/ rewrite 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. Physical interception

NHibernate can use the NHibernate.IInterceptor implementation to intercept this entity: you can intercept us to create an System.Type proxy that will have unpredictable values, where I only return the entity name of the IProxyMarker tag data defined above and null for other types of entities.

/ / /

< summary>

/ / use NHibernate.IInterceptor to intercept this entity /

< /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

We create a physical factory, the so-called factory is a manufacturing factory where New comes out of the entity. We can var user = entityFactory.NewEntity

< IUser>

() initialize an entity in this way.

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));}}

The above sections act as a prelude to the use of tuplizer, so we can use our custom Tuplizer in the mapping.

8. Mapping

This is the time to map this interface, using the

< tuplizer>

Mapping, which has two attributes, class and entity-mode. In this example, I map to a custom EntityTuplizer implementation based on the POCO entity model in IUser.

< class name="IUser">

< tuplizer class="EntityTuplizer" entity-mode="poco"/>

< id name="Id">

< generator class="hilo"/>

< /id>

< property name="Name"/>

< /class>

9. test

Let's test our results. Create, query, and delete operations respectively.

[Test]

Public void UserCrud () {object savedId; var user = entityFactory.NewEntity

< IUser>

(); user.Name = "Li Yongjing"; 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 ("Li Yongjing"); 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 ();}}

Conclusion

Due to the lack of NHibernate information, I found this example from the source code to explain a little bit. If you have any good ideas for Tuplizer, you can reply and discuss it. I think the extension of this function is that if NHibernate Domain is combined with WPF, I need to implement the INotifyPropertyChanged interface in all Domain, and I need to re-implement DataProxyHandler.

The above is all the content of the article "how to use Tuplizers for NHibernate2.1 's new features". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report