我有一些模型代码需要 System.IO.Compression 命名空间中的一些方法。但是,当使用也针对 VMonoTouch 和 MonoAndroid 的 PCL 时,它不存在。我看到 MvvmCross 解决方案中有些东西是 TypeForwarded,尽管在创建类似的项目时我似乎无法找到如何使用它。
我创建了一个 MonoAndroid 库项目,并添加了一个包含以下内容的 Forward.cs 类:
using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(System.IO.Compression.CompressionMode))]
[assembly: TypeForwardedTo(typeof(System.IO.Compression.DeflateStream))]
[assembly: TypeForwardedTo(typeof(System.IO.Compression.GZipStream))]
我已将项目的命名空间设置为System.IO.Compression
。尝试将其添加为对我的模型代码的 PCL 项目的引用,其中包含 ViewModels、服务,当然它还表示它只能引用其他 PCL 项目和程序集。
我特别需要 GZipStream
并且我似乎不知道如何将它添加到我的项目中,所以问题是我该怎么做?
最佳答案
PCL延伸路线
如何通过扩展 PCL 来做到这一点...我不完全确定! PCL 的一位人员也许可以提供帮助。
插件路线
我的方法是在界面中定义我想要的功能并将代码包装在插件中。
例如,在 Cheesebaron.Plugins.Gzip.dll
中,您可以创建一个如下界面:
public interface IGZipStreamFactory
{
Stream Decompress(Stream binaryStream);
}
然后,该接口(interface)将被插入到仅包含该接口(interface)和插件管理器类的 PCL 库中。
然后,您的 PCL Core 项目可以引用此 PCL 插件库,并且您的 ViewModel 可以使用如下代码:
Cheesebaron.Plugins.GZip.PluginLoader.Instance.EnsureLoaded();
其次是
var service = this.GetService<IGZipStreamFactory>();
var unzipped = service.Decompress(inputStream);
对于每个实际的平台实现,您可以准备一个特定于平台的库,实现 GZip 工厂接口(interface),并提供一个简单的 Plugin
类实现。
例如,对于 Droid,您可以创建 Cheesebaron.Plugins.Gzip.Droid.dll
:
public class MyDroidGZipStreamFactory : IGZipStreamFactory
{
// the implementation
}
然后您可以添加:
public class Plugin
: IMvxPlugin
, IMvxServiceProducer
{
public void Load()
{
this.RegisterServiceInstance<IGZipStreamFactory>(new MyDroidGZipStreamFactory));
}
}
最后...将所有内容整合在一起,对于 MonoDroid,您可以在 UI 项目中引用 PCL 和特定于平台的实现 - 它应该可以正常工作!
注意,这里的幕后有一些基于约定的魔法 - 框架根据以下内容加载程序集 Cheesebaron.Plugins.Gzip.Droid.dll
PCL 插件命名空间为 Cheesebaron.Plugins.Gzip
(对于 WP7 和其他平台,还有一个额外步骤 - 有一种设置方法可以覆盖注册插件)
注意您可以在单个插件中注册任意数量的服务,并且您也可以执行额外的常见初始化/设置代码。这有助于减少一些项目维护开销:如果您愿意,您可以将 CheeseBaron IoC 对象放入一个 CheeseBaron.Plugins.Utils
项目中,然后在所有应用程序中共享这一插件。
DownloadCache
插件提供了一个小示例 - 它注册了所有 IMvxHttpFileDownloader
、IMvxImageCache
和 IMvxLocalFileImageLoader
.
这样做的缺点是:最终链接的 exe 大小 - 您可能会向每个应用程序添加不需要的代码。
显然,这种插件方法有一点学习曲线...并且它确实增加了一些项目维护 - 但好消息是这些插件可以在项目之间反复使用 - 并且可以在项目之间共享组织(至少,这是我的希望!)
有关创建插件的更多信息:
- MvvmCross vnext: merge plugins with monodroid
- http://slodge.blogspot.co.uk/2012/06/mvvm-mvvmcross-monodroid-monotouch-wp7.html
有关插件的示例(并非所有平台都可用),请参阅 https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins
其他路线
如果您不想使用插件 - 例如如果您很匆忙或者正在为不想重用的模块编写代码,那么还有其他选择:
- 您可以在共享 Core PCL 库中定义类似 IGZipStreamFactory 的接口(interface)。然后,您可以在每个 UI 项目中提供此接口(interface)的特定于平台的实现,然后可以在 ViewModel/Model/Service 层中使用正常的 IoC/DI,以便在运行时找到正确的实现。
或者...
- 您可以转储共享 PCL 核心库并创建单独的特定于平台的 DLL,然后手动链接到特定于平台的文件(我尽量不这样做,但其他人喜欢这样做)
关于windows-phone-7 - MvvmCross vNext : Using System. PCL 中的 IO.压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13086823/