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


Я работаю над утилитой для 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 во время выполнения?


10


источник


Ответы:


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

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

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
        }

4



В порядке 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



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

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

Для настройки перенаправления можно использовать «.configure framework tool».


2



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


-2