代码之家  ›  专栏  ›  技术社区  ›  Ryan Hayes

在运行时动态选择要使用的.dll版本

  •  10
  • Ryan Hayes  · 技术社区  · 14 年前

    我正在为SharePoint开发实用程序。这是一款同时适用于SharePoint2007和2010的应用程序。当我引用SharePoint.dll的12.0.0.0版本时,该应用程序适用于SharePoint 2007,但不适用于2010。如果我引用的是14.0.0.0版的dll,那么这个应用程序在2010年会很好地工作,但在2007年不会。

    通过使用以下代码查看文件系统,检查路径(SharePoint2007)中的12个或14个(SharePoint2010),我可以很容易地判断需要使用哪个.dll。

    System.IO.File.Exists(
                        Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + 
                        @"\Microsoft Shared\web server extensions\14\ISAPI\Microsoft.SharePoint.dll"));
    

    在开发时,我在Visual Studio中引用了它,因此它构建于2007年或2010年。我想能够发布它工作的应用程序 两个 SharePoint版本。所以,我需要一些方法来加载/使用任何运行应用程序的用户有意义的.dll。

    如何在运行时动态选择和加载.dll?

    5 回复  |  直到 13 年前
        1
  •  14
  •   Ryan    14 年前

    反思?依赖注入?你让自己的生活变得艰难!

    根据microsoft.sharepoint.dll v12编译,它将在2007年运行。

    部署到2010年,它将“仅在几乎所有情况下”起作用 SharePoint2010已经有绑定重定向设置,因此对v12的任何引用都将重定向到v14。

    您不需要做任何配置方面的工作。

    唯一需要比这更复杂的情况是

    • 有什么东西可以用的实例 2007年而不是2010年(我不能 想点什么就动手吧)。

    • 您可能希望利用2010年的特定功能。

    如果是这样的话,那么我个人会做的就是双重编译。修改.csproj文件以生成2个稍有不同的版本,必要时为特定于产品的代码版本使用参数和条件编译(就像在调试时使用一样)。也可以在.csproj中的引用中使用这些条件,例如

     <Reference Include="Microsoft.SharePoint">
        <HintPath Condition="'$(SP2010)'!='true'">PathToV12\Microsoft.SharePoint.dll</HintPath>
        <HintPath Condition="'$(SP2010)'=='true'">PathToV14\Microsoft.SharePoint.dll</HintPath>        
     </Reference>
    

    缺点

    • 你最终得到了两个版本的 程序

    优势

    • 你最终得到了两个版本的程序!在2010版本中,您可能希望进行的许多更改都在manifet.xml、feature.xml和其他配置文件中—反射、依赖注入等—在这里不会为您做任何事情。
    • 仍然有单一版本的源代码(有少量条件编译)
    • 编译器会发现更多的错误(例如,它不能在编译时弄清楚,在v14中调用一个新方法的反射所做的那些奇怪的事情实际上会起作用)。
        2
  •  4
  •   Incognito    14 年前

    你需要运用反思。看一看 Assembly.LoadFile Assembly.Load .

    如果需要在其中使用类方法,可以这样使用:

            Assembly u = Assembly.LoadFile(path);
            Type t = u.GetType(class title);
            if (t != null)
            {
                MethodInfo m = t.GetMethod(method);
                if (m != null)
                {
                    if (parameters.Length >= 1)
                    {
                        object[] myparam = new object[1];
                        myparam[0] = ......;
                        return (string)m.Invoke(null, myparam);
                    }
                    else
                    {
                        return (string)m.Invoke(null, null);
                    }
                }
            }
            else
            {
                 // throw exception. type not found
            }
    
        3
  •  3
  •   Tim Cooper    13 年前

    通过 AppDomain.AssemblyResolve ,您可以检查是否存在该dll,并返回任何存在的dll:

    AppDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
    {
        if (e.Name == "Microsoft.SharePoint")
        {
            // do your check here and return the appropriate Assembly
            // or maybe just skip an explicit check and instead return either
            // Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0") or
            // Assembly.Load("Microsoft.SharePoint, Version=12.0.0.0"), whichever works first
            // but beware of recursion!
        }
    };
    

    在这种情况下,程序集绑定重定向对您不起作用,因为它在配置文件中是静态的,并且您希望它在任何具有SP2007或SP2010的计算机上动态工作。

        4
  •  2
  •   SoftwareGeek    14 年前

    我认为您需要查看框架中的程序集绑定重定向。

    http://msdn.microsoft.com/en-us/library/2fc472t2.aspx

    可以使用“.NET Framework配置工具”配置重定向。

        5
  •  -2
  •   Robaticus    14 年前

    这听起来是一个很好的依赖注入案例,使用类似这样的DI框架之一 Unity Castle Windsor . 外面还有其他人,但我已经冒着宗教战争的危险简单地提到了这两个。:)