Динамически выбирайте во время выполнения, какую версию .dll использовать - PullRequest
10 голосов
/ 15 августа 2010

Я работаю над утилитой для SharePoint. Это приложение, которое работает как для SharePoint 2007, так и для 2010. Когда у меня есть ссылка на версию SharePoint.dll 12.0.0.0, приложение работает для 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 во время выполнения?

Ответы [ 5 ]

14 голосов
/ 16 августа 2010

Отражение? Внедрение зависимости? Ты усложняешь себе жизнь!

Компиляция с 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 и других конфигурационных файлах - отражение, внедрение зависимости и т. Д., Здесь вы ничего не сделаете.
  • По-прежнему имеется единственная версия исходного кода (с незначительной условной компиляцией)
  • Компилятор обнаружит больше ошибок (например, он не может выяснить во время компиляции, что та забавная вещь, которую вы делаете с Reflection, чтобы вызвать новый метод в v14, действительно будет работать)
4 голосов
/ 16 августа 2010

Вам нужно использовать отражение.Взгляните на 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 голосов
/ 15 августа 2010

Посредством 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.

2 голосов
/ 15 августа 2010

Я думаю, что вам нужно посмотреть на перенаправление привязки сборки в каркасе.

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

Вы можете использовать «.net Framework Configuration Tool» для настройки перенаправления.

0 голосов
/ 15 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...