windows-phone-7 - MvvmCross vNext : Using System. PCL 中的 IO.压缩

标签 windows-phone-7 xamarin.ios xamarin.android portable-class-library mvvmcross

我有一些模型代码需要 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 插件提供了一个小示例 - 它注册了所有 IMvxHttpFileDownloaderIMvxImageCacheIMvxLocalFileImageLoader .

这样做的缺点是:最终链接的 exe 大小 - 您可能会向每个应用程序添加不需要的代码。


显然,这种插件方法有一点学习曲线...并且它确实增加了一些项目维护 - 但好消息是这些插件可以在项目之间反复使用 - 并且可以在项目之间共享组织(至少,这是我的希望!)

有关创建插件的更多信息:

有关插件的示例(并非所有平台都可用),请参阅 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/

相关文章:

c# - 如何在列表框wp7中实现搜索?

windows-phone-7 - Windows Phone 7 不在应用程序栏按钮内显示图标

windows-phone-7 - ListBox 内的 WP7 TextBlock 不换行文本

c# - Web 请求突然不起作用

c# - 适用于 Android 的 ExpandableListView Mono

c# - 如何在应用不活动后更新 MPNS channel URI

ios - 我们可以从 swift 框架生成 Objective-C 静态库吗?

ios - 将 iOS 静态库绑定(bind)到 Xamarin.iOS 并使用 dll

android - 如何使用 Xamarin Visual Studio 2015 构建 Android App Bundle?

c# - 本地计算机上的 Azure 移动服务 Nodejs 推送时出错