Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild task to build load my assembly and build a serialised NHibernate Configuration

Tags:

c#

msbuild

What I hoped would be an hour or two of work has now turned into quite the debacle with no result in sight.

Problem: I am trying to serialise a copy of my NHibernate Configuration and store it in... the project that was used to generate it!

Current manual solution: I have a project Foo that

  • contains a series of DomainObject.Map.cs files
  • References an "nhconfig.bin" file for embedding as a resource.
  • Contains a static method FooGenerateNHConfig that create a Configuration object and serialise it to nhconfig.bin.

To generate it, I:

  1. (first time only: create an empty nhconfig.bin that acts as placeholder).
  2. Build Foo.
  3. Call a unit test that calls FooGenerateNHConfig.
  4. Rebuild Foo.
  5. Deploy application.

I'm trying to automate this, and thought it would be a simple matter:

  1. Create a project Foo.BuildSupport that referenced Foo.
  2. Define a Task X in it which would call FooGenerateNHConfig.
  3. Setup an AfterCompile target that would call X.

Unfortunately I'm now getting 2 errors.

  1. Firstly, a somewhat odd exception:

    FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
    ---> System.Runtime.Serialization.SerializationException: Unable to find assembly 'FluentNHibernate, Version=1.1.0.685, Culture=neutral, PublicKeyToken=8aa435e3cb308880'.
    

    I think that's FluentNHibernate complaining that it can't find the FluentNHibernate assembly?

  2. Once I run the Task from visual studio the first time, visual studio (devenv.exe) locks my Foo.BuildSupport.dll AND my Foo.exe (presumably because it just sees them as support libraries and not the actual build libraries), so I can't rebuild them. Generally, this is because vs assumes (and probably rightfully so) that the BuildSupport library is fairly static and does not rely

What's a good way to automate a process such as this? I only have some preliminary thoughts right now but the only thing I can think of is building an entirely seperate executable to be run by msbuild (saw a task to do the equivalent of this, can't find it now), or something rather involved involving a seperate appdomain and manually calling the function via reflection. But before I went further down this path, am I missing something easier and more obvious?

like image 264
fostandy Avatar asked Nov 04 '22 23:11

fostandy


1 Answers

I had a problem very similar to this one. My problem had something to do with MSBuild deserializing Xml to classes contained in a third-party assembly. It could not resolve the assembly needed for the serialization to work, even though the assemblies were part of the project and it had no problem resolving them outside of serialization. Can't give a more technical description of the problem than that, but I found this bit of code that fixed the issue for me,

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly ayResult = null;
            string sShortAssemblyName = args.Name.Split(',')[0];
            Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly ayAssembly in ayAssemblies)
            {
                if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0])
                {
                    ayResult = ayAssembly;
                    break;
                }
            }
            return ayResult;
        }

        public Constructor()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }

I think the reason this works for me is because my application resolves the Assemblies outside of serialization so I override the AssemblyResolution callout to point it back at the good Assemblies that it for some reason wont use on its own.

Hope this is useful!

like image 135
Boog Avatar answered Nov 12 '22 16:11

Boog