MSBuild任务构建加载我的程序集并构建一个序列化的NHibernate配置

时间:2011-04-18 07:39:53

标签: c# msbuild

我希望一两个小时的工作现在已经变成了一场彻头彻尾的崩溃,但没有任何结果。

问题:我正在尝试序列化我的NHibernate配置的副本并将其存储在...用于生成它的项目中!

当前的手动解决方案:我有一个项目Foo

  • 包含一系列DomainObject.Map.cs文件
  • 引用“nhconfig.bin”文件以嵌入资源。
  • 包含一个静态方法FooGenerateNHConfig,它创建一个Configuration对象并将其序列化为nhconfig.bin。

要生成它,我:

  1. (仅限第一次:创建一个空的nhconfig.bin作为占位符)。
  2. Build Foo。
  3. 调用调用FooGenerateNHConfig的单元测试。
  4. 重建Foo。
  5. 部署应用程序。
  6. 我正在尝试自动执行此操作,并认为这将是一件简单的事情:

    1. 创建一个引用Foo的项目Foo.BuildSupport。
    2. 在其中定义一个任务X,它将调用FooGenerateNHConfig。
    3. 设置一个可以调用X的AfterCompile目标。
    4. 不幸的是,我现在收到2个错误。

      1. 首先,有点奇怪的例外:

        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'.
        

        我认为FluentNHibernate抱怨它无法找到FluentNHibernate程序集?

      2. 第一次从visual studio运行Task时,visual studio(devenv.exe)锁定了我的Foo.BuildSupport.dll和我的Foo.exe(可能是因为它只是将它们视为支持库而不是实际构建库),所以我无法重建它们。通常,这是因为vs假定(并且可能是正确的)BuildSupport库是相当静态的并且不依赖

      3. 自动执行此类流程的好方法是什么?我现在只有一些初步的想法,但我能想到的唯一一件事就是构建一个完全独立的可执行文件,由msbuild运行(看到一个相当于这个的任务,现在找不到它),或者其他相关的东西涉及单独的appdomain并通过反射手动调用该函数。但在我走上这条道路之前,我错过了一些更容易和更明显的东西吗?

1 个答案:

答案 0 :(得分:2)

我遇到的问题非常类似于此问题。我的问题与MSBuild反序列化Xml到第三方程序集中包含的类有关。它无法解决序列化工作所需的程序集,即使程序集是项目的一部分,并且在序列化之外解决它们也没有问题。无法对此问题进行更多技术性描述,但我发现这段代码可以解决我的问题,

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

我认为这对我有用的原因是因为我的应用程序在序列化之外解析了程序集,因此我重写了AssemblyResolution标注,将其指向好的程序集,由于某些原因它不会单独使用。

希望这很有用!