Выберите динамично во времени выполнения который версия .dll использовать

Я работаю над утилитой для SharePoint. Это - приложение, которое работает на оба SharePoint 2007 и 2010. Когда у меня есть ссылка на 12.0.0.0 версии SharePoint.dll, приложение работает на SharePoint 2007, но не на 2010. Если я ссылаюсь на версию 14.0.0.0 dll, то приложение работает отлично на 2010, но не на 2007.

Я могу легко сказать, какой .dll, который я должен использовать путем наблюдения файловой системы со следующим кодом, проверки на 12 в пути (SharePoint 2007) или 14 (SharePoint 2010).

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 во времени выполнения?

10
задан Ryan Hayes 15 August 2010 в 18:22
поделиться

5 ответов

Reflection? Инъекция зависимостей? Вы сами себе усложняете жизнь!

Скомпилируйте с Microsoft.SharePoint.dll v12 и он будет работать на 2007.

Разверните на 2010 и это будет "просто работать" (почти во всех случаях), так как SharePoint 2010 уже имеет настройки перенаправления привязки, поэтому любая ссылка на v12 будет перенаправлена на v14.

Вам не нужно ничего делать в плане конфигурации.

Единственные ситуации, в которых вам потребуется более сложная конфигурация, это

  • случаи, когда что-то работает в 2007, но не работает в 2010 (я не знаю, как это сделать). на 2007, но не работает на 2010 (я не могу не могу вспомнить ничего подобного).

  • Когда вы можете захотеть использовать специфические возможности 2010.

Если это так, то лично я бы сделал двойную компиляцию. Измените файл .csproj, чтобы получить две немного разные версии, используйте параметр и условную компиляцию (точно так же, как вы используете #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 и других конфигурационных файлах - отражение, инъекция зависимостей и т.д. здесь вам ничем не помогут.
  • По-прежнему есть одна версия исходного кода (с незначительной условной компиляцией)
  • Компилятор будет находить больше ошибок (он не сможет, например, выяснить во время компиляции, что та забавная штука, которую вы делаете с Reflection для вызова нового метода в v14, действительно будет работать)
14
ответ дан 3 December 2019 в 18:29
поделиться

Вам нужно использовать отражение. Взгляните на 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
        }
4
ответ дан 3 December 2019 в 18:29
поделиться

С помощью 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
ответ дан 3 December 2019 в 18:29
поделиться

Думаю, вам нужно посмотреть на перенаправление привязки сборок во фреймворке.

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

Вы можете использовать '.net framework configuration tool' для настройки перенаправления.

2
ответ дан 3 December 2019 в 18:29
поделиться

Звучит как отличный случай для внедрения зависимостей с использованием одной из структур DI, например Unity или Castle Windsor . Есть и другие, но я уже рискую начать религиозную войну, просто упомянув этих двоих. :)

-2
ответ дан 3 December 2019 в 18:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: