views:

1615

answers:

4

We have a Fluent NHibernate mapping test that is passing on our local machines, but when we check in to TFS, the tests are failing on the build server. We are using MSTest. The error we get is:

NHibernate.Bytecode.UnableToLoadProxyFactoryFactoryException: Unable to load type 'NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle' during configuration of proxy factory class. Possible causes are: - The NHibernate.Bytecode provider assembly was not deployed. - The typeName used to initialize the 'proxyfactory.factory_class' property of the session-factory section is not well formed.

Solution: Confirm that your deployment folder contains one of the following assemblies: NHibernate.ByteCode.LinFu.dll NHibernate.ByteCode.Castle.dll ---> System.IO.FileNotFoundException: Could not load file or assembly 'NHibernate.ByteCode.Castle' or one of its dependencies. The system cannot find the file specified.WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

We have checked the drop folder, and the NHibernate.Bytecode.Castle.dll is there. We have dlls and references to Castle.Core, Castle.DynamicProxy2, Iesi.Collections, log4net, NHibernate and NHibernate.ByteCode.Castle. We have run the tests via MSBuild with the command prompt in the drop folder, and the error still occurs. Our fluent mappings look like this (NHibernateConfig.MappingConfiguration()) calls the actual mappings, automapped):

Fluently.Configure() .Database(SQLiteConfiguration.Standard.ShowSql().InMemory()) .Mappings(NHibernateConfig.MappingConfiguration()) .BuildConfiguration();

Any ideas why this might be?

A: 

Have you added references to NHibernate.ByteCode.LinFu.dll NHibernate.ByteCode.Castle.dll?

Burt
We are not using LinFu. I've updated the post with all the references.
JontyMC
+3  A: 

If I recall how the bytecode assemblies work, you don't actually make a useful reference to them. That is you don't specifically use one of their classes in your code. As a result, the "smart" reference copying causes these to not be pulled in. (I might be making this up, sorry).

To deal with this you can: a) make the appropriate bytecode assembly a Copy Always content reference (meh) or b) create a silly little class (private static) that references any single class in your actual bytecode assembly (meh+1).

I'm sure there is another alternative regarding forcing the reference to be honored, but those two should be the easiest, 20 second solutions.

Ryan Cromwell
Thanks, using the static class worked. This seems like a bit of a hack though. I tried using a testrunconfig to pull in the dlls, but I couldn't get that to work.
JontyMC
Great. The confusion comes about because the MSBuild tasks which VS uses to resolve references is lazier than that of Team Build. I haven't looked into reconciling the two, personally.
Ryan Cromwell
A: 

Had same problem, had to add reference in the class that did the Fluently.Configure.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Automapping;
using FluentNHibernate.Conventions.Helpers;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using FluentNHibernate.MappingModel;
using FluentNHibernate;
**using NHibernate.ByteCode.Castle;**

namespace CESP_NotifyLib
{
    class SessionFactoryController
    {

        public SessionFactoryController()
        {

        }

        public ISessionFactory GiveFactory()
        {
            return CreateSessionFactory();
        }

        **private static void ReferByteCode(){

            //Just to make sure the ByteCodeCastle is loaded
            ProxyFactory fake = new ProxyFactory();
        }**

        private static ISessionFactory CreateSessionFactory()
        {
            ReferByteCode();

            var cfg = new NotifyFluentNhibernateConfiguration();

            return Fluently.Configure()
              .Database(
               FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
                    .ConnectionString("Server=[MYSERVERIPADRESS]\\DBSERVER;Database=NotifyTest;User ID=NHibernateTester;Password=[MYPASSWORD];Trusted_Connection=False;")
              )

              .Mappings(m => {
                  m.AutoMappings
                    .Add(AutoMap.AssemblyOf<SubscriptionManagerRP>(cfg));

              } )

              .BuildSessionFactory();
        }



    }
}
Simply G.
A: 

Actually, the 'ReferByteCode' method is needed, only a reference doesn't help. Its a hack worthy of McGyver, but it works.

Simply G.