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

时间:2010-08-15 18:22:06

标签: c# sharepoint visual-studio-2010 dll c#-4.0

我正在开发一个SharePoint实用程序。这是一个适用于SharePoint 2007和2010的应用程序。当我引用SharePoint.dll的12.0.0.0版本时,该应用程序适用于SharePoint 2007,但不适用于2010.如果我引用版本14.0.0.0 dll,然后该应用程序适用于2010年,但不适用于2007年。

通过使用以下代码查看文件系统,在路径(SharePoint 2007)或14(SharePoint 2010)中检查12,我可以轻松地告诉我需要使用哪个.dll。

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

开发时,我在Visual Studio中进行引用,因此它可以在2007年或2010年构建。我希望能够在 BOTH 版本的SharePoint上发布适用的应用程序。因此,我需要一些方法来加载/使用任何.dll对运行应用程序的用户有意义。

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

5 个答案:

答案 0 :(得分:14)

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

针对Microsoft.SharePoint.dll v12进行编译,它将在2007年运行。

部署到2010年,它将“正常工作”(几乎在所有情况下),因为 SharePoint 2010已经具有绑定重定向设置,因此对v12的任何引用都将重定向到v14。

您无需采取任何配置方式。

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

  • 可以使用某些内容的实例 2007年但不是2010年(我不能 想想任何事情。)

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

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

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

缺点

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

优点

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

答案 1 :(得分:4)

你需要使用反射。请查看Assembly.LoadFileAssembly.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
        }

答案 2 :(得分:3)

通过AppDomain.AssemblyResolve,您可以检查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的任何计算机上动态工作。

答案 3 :(得分:2)

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

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

您可以使用'.net框架配置工具'来配置重定向。

答案 4 :(得分:-2)

对于使用UnityCastle Windsor之类的DI框架之一的依赖注入来说,这听起来很棒。那里还有其他人,但我只是提到这两个就已经冒着宗教战争的风险了。 :)