Nhibernate and medium trust

Being sick of all the hassles it took to keep my own server up and running I’ve moved it to a public hoster. Which does offer asp.net hosting but like many others code is only given medium trust. My site was using nHibernate. That does have serious problems under this trust level. I’ve been investigating and experimenting to get it up and running. Alas without success. Nevertheless a summary of what I’ve done. As most web references on this subject are either vague or not specific enough this can help get a better overview. Or perhaps somebody can point me to something I have overlooked.

Medium trust restricts the permissions given to your code. When googling a lot of the links mention the error message That assembly does not allow partially trusted callers. You can get it  when you sign the assemblies of your site. It depends on your hoster. You used to get that when hibernate tries to load a signed assembly with your domain objects. This can be fixed by setting the AllowPartiallyTrustedCallersAttribute on the loading assembly. This has been fixed on the recent production build of nHibernate; a lot of the posts still around deal with a previous version of nHibernate and are a dead end.

The main problem with medium trust is that it inhibits reflection. nHibernate depends heavily on reflection. For lazy load to work nHibernate generates proxies to the domain objects. These proxies are built by reflecting on the domain objects. You can configure nHibernate to work without lazy loading. I gave this path a full try and tried everything I could find on the web and could think of myself.

This is what I did to the configuration

  • Apply the requirepermission="false" in the web.config section of nHibernate
  • Set the hibernate.use_reflection_optimizer in the web.config to false
  • Set the hibernate.bytecode.provider in the web.config to null.

This is what I did in the mapping files

  • Set the lazy attribute of all classes to "false"
  • Set the lazy attribute of all collections to "false"
  • Remove the proxy attribute of all classes

In the domain classes I even made all public members non-virtual. In a normal scenario nHibernate will now completely trip over this, complaining it cannot create a proxy.

On my local machine the site still worked. But on the medium trust host it immediately crashed again on a security exception. The stack trace pointed to the initialization of the reflection optimizer. Huh ? This is where I gave up.

There is an approach on the web which promises a working lazy load even in medium trust. It is supposed to work by replacing the proxyfactory by one which provides pre generated proxies instead of generating them on the fly via reflection. Alas providing you own proxyfactory takes nHibernate 2.0. Which is still in alpha phase. From a maintainability point of view beyond consideration.

Googling around getting nHibernate to work under medium trust is considered important but still takes a lot of effort, also in 2.0. I really hope it is going to work but for me it’s back to basics for this project. Not all work has to be done again, the domain model is clear, all I have to do is rewrite the implementation of the repositories. To the UI it’s not important how I gets the data as long as it gets them.

The main reason for needing persistence on my site is an index on a selection of my publications. Reading through the results it sometimes does make my toes curl. A lot of the work is pretty old by now and my techniques have really grown over the years. Time for a good update of the contents of the underlying db.

This entry was posted in Data. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Proxy generator requires NH 2.0
    At the time I wrote this post the proxy generator didn’t work as promissed Perhaps it does now..

  • dev

    Use NH Proxy Generators, it solves the problem:
    http://nhforge.org/wikis/proxygenerators10/introduction.aspx

  • me
  • Mario

    Hi,

    I also had the problem making NHibernate work with medium trust and this is what I did:

    First..you need some sort of hosting that allows reflection in your server…There are some like crystaltech.com which will allow you to use reflection (in shared hosting) as long as it is used for assemblies within your designated app folder.

    Second…

    Download the Castle.DynamicProxy-vs2005 project. NHibernate ships with the dll, but you will need to modify the assembly to allow lazy loading under medium trust. Once you have the assembly, make sure nhibernate references this assembly and not the old dll.

    Open the Castle.DynamicProxy-vs2005 project and look for the ModuleScope.cs file (it is right in the main directory). There look for the method:
    private AssemblyName GetAssemblyName (bool signStrongName)
    In there comment out the following code:

    if (signStrongName)
    {
    byte[] keyPairStream = GetKeyPair();

    if (keyPairStream != null)
    {
    assemblyName.KeyPair = new StrongNameKeyPair(keyPairStream);
    }
    }

    Now give it a shot.

    Mario

  • http://blog.symbiotic-development.com Symon Rottem

    Of course, now that I’ve read it more slowly I can see you’ve already seen Willam’s post. Duh.

  • http://blog.symbiotic-development.com Symon Rottem

    I did a post on this a little while ago when I found some code William C. Pierce put up to help get you running under medium trust with proxies: http://blog.symbiotic-development.com/2008/03/22/nhibernate-proxy-generator/