Ссылка на проект и ссылки на файлы в многоцелевых проектах Mono

Я видел несколько дискуссий по этой проблеме, но я еще не видел четких ответов, особенно для MonoTouch/Mono для Android.

Я разрабатываю многоцелевое решение на основе Xamarin, и, естественно, у меня много общего кода. В идеале этот код должен находиться в «общем» стандартном проекте библиотеки классов .NET (или проекте). Когда я ссылаюсь на этот проект в проекте для конкретной платформы, я получаю предупреждение «На проект «Общий» нельзя ссылаться. Ссылочный проект предназначен для другого семейства фреймворков (.NETFramework)», но решение по-прежнему успешно скомпилировано.

По сути, я спрашиваю, должен ли я использовать подход со ссылками на файлы, когда мой общий код обращается к нескольким целям. Более подробно мои вопросы:

  1. Верен ли описанный выше подход, когда мои «общие» проекты ссылаются только на сборки, которые поддерживаются целями Mono*?
  2. Если ответ на вышеприведенный ответ да: скажем, я ссылаюсь на стороннюю библиотеку .NET (в форме DLL, а не проекта) в своем «общем» проекте, и эта библиотека имеет разные сборки для разных целей (но это не ссылается на сборку, не поддерживаемую Mono*), могу ли я по-прежнему ссылаться на версию сборки для Windows, и мне это сойдет с рук?

person ury    schedule 10.09.2012    source источник


Ответы (2)


Есть что-то, называемое переносимыми библиотеками классов, которые уже некоторое время находятся в процессе разработки. Начиная с Visual Studio 2012 (выпущенного 12 сентября 2012 г.), теперь он является первоклассным гражданином Visual Studio, поэтому вы можете обмениваться библиотеками между Windows 8, Windows Phone, Silverlight, Windows ‹ 8 и т. д.

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

В то же время вы должны создать один проект для каждой платформы, даже если ссылка на одни и те же исходные файлы. Я нашел это лучшим решением:

Файлы проекта с такими именами

MyCompany.MyProduct.MyModule.Ios.csproj
MyCompany.MyProduct.MyModule.Android.csproj
MyCompany.MyProduct.MyModule.WinPhone.csproj

Пространства имен во всех проектах только MyCompany.MyProduct.MyModule.

Вы связываете одни и те же cs-файлы из проектов с общей папкой.

Если вам нужно предоставить какой-то дополнительный класс в версии для iOS, вы просто добавляете этот файл в проект iOS (не связанный) и добавляете .Ios в пространство имен, так как вы хотите, чтобы межплатформенное пространство имен не было загромождено специфическими для платформы вещами.

Вот структура папок, которая не сломает проблему длины пути Windows:

/MyCompany/MyProduct/

Здесь вы помещаете файлы решений для всех целевых платформ с такими именами:

MyCompany.MyProduct.Ios.sln
MyCompany.MyProduct.Wpf.sln
...

Папка для каждой сборки:

/MyCompany/MyProduct/MyModule/

Здесь вы помещаете одну папку «Общие» и одну папку для каждой платформы, поэтому:

/MyCompany/MyProduct/MyModule/Shared/

Только кроссплатформенный код (ссылка из каждого файла проекта)!!!

/MyCompany/MyProduct/MyModule/Android/
/MyCompany/MyProduct/MyModule/Ios/
/MyCompany/MyProduct/MyModule/WinPhone/
/MyCompany/MyProduct/MyModule/Wpf/
/MyCompany/MyProduct/MyModule/Mac/
...

Здесь вы размещаете файлы проекта для каждой платформы для модуля, а также там, где вы размещаете любые файлы cs для конкретной платформы, которые необходимы для реализации модуля на конкретной платформе.

Это работает очень хорошо для нас.

person Ricky Helgesson    schedule 13.09.2012

MonoTouch, как и Mono для Android, предоставляет подмножество обычной (настольной) платформы .NET.

Это подмножество на самом деле является надмножеством библиотек базовых классов (BCL), поставляемых для Silverlight (то, что мы тогда называли FX 2.1).

У вас возникнут проблемы с 1 или 2, если ваши двоичные файлы ссылаются на типы, методы (любые метаданные), которых нет в MonoTouch (или Mono для Android).

С MonoTouch вы обнаружите такие проблемы при сборке для устройств, поскольку используется компиляция AOT (с опережением). Отсутствующие символы IOW будут найдены во время сборки. Обратите внимание, что для симулятора iOS используется JIT, поэтому отсутствующие символы не будут находиться до тех пор, пока они не потребуются во время выполнения.

Mono для Android использует JIT (как на устройствах, так и на эмуляторах), поэтому любые отсутствующие метаданные с большей вероятностью будут найдены во время выполнения, т. е. управляемый компоновщик также найдет отсутствующие элементы и не сможет создавать новые сборки меньшего размера, если символы не могут быть разрешены.

Так что нет этот подход недействителен (как в случае со 100% безопасностью), если только вы не перекомпилируете свой код с помощью сборок SDK (BCL), поставляемых с продуктами.

person poupou    schedule 10.09.2012
comment
Спасибо @poupou, но... 1. Как я уже сказал, вы можете предположить, что я использую только подмножество BCL в своем общем проекте. 2. Возможно ли иметь общий проект библиотеки классов BCL для использования всеми целевыми объектами? 3. А как насчет моего второго вопроса, если исходить из предположения о безопасности BCL? - person ury; 10.09.2012
comment
1. Сам компилятор может использовать символы (например, Type новый оператор == в .NET 4), недоступные в более ранних платформах — это нарушает ваше предположение. 2. наилучший способ — создать на основе наименьшего подмножества (например, создать общий код для сборок MonoTouch SDK) и использовать его в более новых платформах. 3. Не существует безопасного способа, если вы не перекомпилируете код, т. е. вы не можете знать, какой компилятор использовался предварительно скомпилированными третьими лицами. Может сработать, может не сработать. - person poupou; 10.09.2012