What is Castle proxy factory in NHibernate? - nhibernate

What is Castle proxy factory in NHibernate? What is its task? What does proxy mean in this case?

Castle can be used (amongst others, you have the choice, you can also use LinFu, Spring.NET, ...) to create dynamic proxies of your entities.
By default, NHibernate uses dynamic proxies to represent your entities; by doing so, it is able to return an object to you when you retrieve some entity from the DB, without all properties being populated. By using a dynamic proxy, it will only populate the entity once you really refer to a property.
(So it is some kind of lazy loading; not to be confused with lazy loading of collections / associations though).
This behaviour is the reason why NHibernate wants you to create every property as virtual by default: NHibernate will create a new class using this Castle (or LinFu, ...) proxy provider which inherits from your entity, and it will override all the properties so that it can 'inject' the code that is necessary to retrieve the necessary data from the DB.
You can disable this behaviour by specifying 'lazy=false' in your entity mapping. (Although, I do think that even if you disable this feature, NHibernate will still require that you use one of the proxy factories).

When you are selecting an entity from ISession you are getting not real entity instance - you are getting proxy object.
This proxy object inherits your entity and used by NHibernate to track changes made to the fields.

see it: http://en.wikipedia.org/wiki/Proxy_pattern

Related

Entity Framework with POCO Serializable Classes and Lazy Loading

I have set up my POCO classes with ICollection for related objects. They are in a WCF Service, so I have decorated them with DataContract/DataMember. I do not use virtual properties for the related objects, because they create a proxy that won't serialize (I get a seemingly unrelated message, "The underlying connection was closed", but when I remove the virtual modifier, that goes away.)
What I am having trouble understanding is how to lazy-load the collections for related objects. I don't think the POCO's can do that for themselves, because they don't have access to the context.
For example, I have a Company class, which has an ICollection<Principals> property. I usually don't want to load all the Principals when I retrieve a Company, but I would like a reference to Company.Principals to go get them. Clearly, Company simply can't do that on its own.
What are folks doing to combine the desires to have (1) POCO objects, (2) typical WCF Serialization, and (3) lazy-loaded related properties?
Lazy loading requires proxies and virtual navigation properties. If you don't have proxies you must handle loading in different way. For example by using eager loading:
var companies = context.Companies.Include("Principals").ToList();
or with EF 4.1
var companies = context.Companies.Include(c => c.Prinicpals).ToList();
You know which operation should load related principals as well so using eager loading is not a problem. Using lazy loading in WCF service with serialization will always result to load whole object graph.

Can I control the insert/update-command of (fluent) nhibernate to call a webservice instead of writing into the DB?

I want to use fluent-nhibernate to query my data, but when a entity gets saved, it should not be written into the database via insert/update. Instead, I want to (better: have to) serialize that object and send it to a webservice (which will map that object to a 3rd-party class that will trigger some important business-logic).
Is such behaviour possible to implement with nhibernate (call a custom method instead of update on saving)?
I would recommend creating a IRepository interface and hiding the webservice and Nhibernate functionality behind that. You could possibly use NHibernate interceptors for this, but it doesn't sound like a clean solution. Personally, I would hate to find Web service code hidden in one of Nhibernate interceptors.
We decided to use a SaveOrUpdateEventListener for this task.

wcf and ADO entity framework

We are using Linq to Entities in WCF service. We created a edmx file which contains auto generated entities. While creating proxy the entities are not appearing in the proxy class even the data contract and datamember attributes are there. We found that the problem is because of the auto generated entities are inheriting from something called System.Data.Objects.DataClasses.EntityObject But if we create a class without any inheritance that class is appearing in the proxy. Is there any way to resolve this?
Regards
Sekar
The way we do this is:
Auto generate entity framework entities
Create separate classes to be used in the data contracts
Write mapping code to convert from one contract classes to entity classes, and back
This may be a bit cumbersom but it works (it also isolates your services from changes in your database). This should become much easier in the next version of entity framework.

Returning NHibernate mapping classes from WCF services

I have a server that handles the database access and a client that consumes the information. The communication from the client to the server is through a WCF service.
When the NHibernate POCO is returned from the service are all the objects in the object graph serialized? If so, is there a way to change it?
I'm also thinking of not returning the NHibernate POCO and instead return an object with only the essential information.
What do you do in these cases?
Use data-transfer objects to move the data from the server to the client. Your business (domain model) objects should not necessarily be exposed outside the core of the application, but should be considered a protected asset.
You can use AutoMapper to automate the translation from business objects to data-transfer objects.
Yeah, you probably want a DTO for this. It's usually considered better to not pass your data objects to the outside world, but also passing hibernate objects directly out of a service can give you some weird behavior, especially if you have lazily loaded collections.

Getting real instance from proxy under Unity Interception with NHibernate

I'm using Unity to resolve types dynamically for a pluggable architecture. I'm also using interception to apply business rule validation via AOP (using ValidationAspects). Finally, I'm using NHibernate as an ORM to persist domain objects.
In order for AOP to work, we use the VirtualMethodInterceptor, as interface interception doesn't work with NHibernate. I have a facade over ISession that handles casting between interface and real types for repository operations.
To make sure that all objects in the graph fetched via NHibernate are properly proxied for AOP, I made an NH IInterceptor implementation and overrode the Instantiate() method, so I could supply NH with created objects rather than have it call new(). I then use Container.Resolve() to get back proxied objects with the validation injected, and give this back to NH to populate. This works OK.
The problem comes when the session flush occurs. NHibernate gets upset because the objects it sees in the graph are of the proxy type rather than the real type. The way we're mapping (all via property, all virtual) NH should be able to get all the values it needs via the proxy, if I could override the type-checking.
What I need to know is: given a transparently proxied object created by Unity with Interception enabled, is there a) any way to obtain a direct reference to the 'real' instance it's proxying, or b) to override NH and tell it to treat objects of a proxy type as if it were of a known mapped type, dynamically at runtime?
We use interception for caching. So in our class, that implements ICallHandler we have code like this:
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
//...
var nextHandler = getNext();
var realReturn = nextHandler(input, getNext);
var cacheRefreshingItemParameters = new CacheRefreshingItemParameters
{
InterfaceMethod = input.MethodBase,
InterfaceType = input.MethodBase.DeclaringType,
TargetType = input.Target.GetType() //remember original type
};
_cacheProvider.Add(cacheKey, realReturn.ReturnValue, cacheRefreshingItemParameters);
//...
return (cachedReturn);
}
We put cacheRefreshingItemParameters in cache UpdateCallback and then resolve original service:
var service = _unityContainer.Resolve(parameters.TargetType);