4
votes

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?

7
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

7 Answers

11
votes

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.

6
votes

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



    }
}
3
votes

A couple of helpful hints.

You can put a DeploymentItem attribute on your test class. This will copy over the DLL's you need. You would also have to reference the DLL's in the projects references.

    [TestClass]
[DeploymentItem("NHibernate.ByteCode.LinFu.dll")]
[DeploymentItem("NHibernate.ByteCode.LinFu.xml")]
public class Accounts

You can find missing DLL's by comparing the /[myapp]/bin/debug folder to the /TestResults/[TestRunDate] folder.

I am using VS 2012. This is for MSTest.

2
votes

Adding the reference to NHibernate.ByteCode.Castle.dll fixed this issue for me.

2
votes

From Fluent NHibernate wiki: ProxyFactory configuration missing

The database configuration inside CreateSessionFactory is missing the ProxyFactoryFactory invocation. Since issue 154 is a wontfix, a line

.ProxyFactoryFactory("NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle") will be need to be added to database configuration call. Mine looks like this:

return Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.UsingFile("firstProject.db")
    .ProxyFactoryFactory("NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"))
1
votes

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

0
votes

Guys if You having this issue I suggest You to download other package of Castle. In my case problem was that in package I`ve downloaded there was really not implemented Interface (IProxyFactory or something like that) so I have deleted NHibernate.ByteCode.Castle and NHibernate.ByteCode.Search and installed NHibarnate.Castle package which solve my all-day problem. I am using NuGet Package Manager!

and remember Fusion Log is You`re friend!