Выбирайте динамически во время выполнения, какую версию .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 BOTH. Итак, мне нужно каким-то образом загрузить/использовать любой .dll, который имеет смысл для пользователя, запускающего приложение.
Как я могу динамически выбирать и загружать DLL во время выполнения?
Ответы
Ответ 1
Отражение? Внедрение зависимости? Вы делаете жизнь тяжело для себя!
Скомпилируйте файл 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, действительно будет работать)
Ответ 2
Вам нужно использовать отражение. Посмотрите 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
В качестве 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.
Ответ 4
Я думаю, вам нужно посмотреть перенаправление привязки сборки в рамках.
http://msdn.microsoft.com/en-us/library/2fc472t2.aspx
Чтобы настроить перенаправление, вы можете использовать инструмент настройки .net framework.
Ответ 5
Это звучит как отличный случай для Injection Dependency с использованием одной из фреймворков DI, таких как Unity или Замок Виндзор. Есть и другие, но я уже рискую религиозной войной, просто упомянув об этих двух.:)