MvvmCross vNext:在PCL中使用System.IO.Compression

时间:2012-10-26 12:19:28

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

我有一些Model代码需要System.IO.Compression命名空间中的一些方法。但是,当使用针对VSMonoTouch和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,Services以及当然不能说它只能引用其他PCL项目和程序集。

我特别需要GZipStream而我似乎无法找到如何将其添加到我的项目中,所以问题是我该怎么做?

1 个答案:

答案 0 :(得分:2)

PCL扩展路线

如何通过扩展PCL来做到这一点...我不完全确定!其中一个PCL人员可能会提供帮助。


插件路线

我采用的方法是在界面中定义我想要的功能,并将代码包装在插件中。

例如,在Cheesebaron.Plugins.Gzip.dll中,您可以创建如下界面:

public interface IGZipStreamFactory
{
     Stream Decompress(Stream binaryStream);
}

然后,此接口将插入一个仅包含此接口和pluginmanager类的PCL库中。

您的PCL Core项目可以引用此PCL插件库,您的ViewModel可以使用以下代码:

 Cheesebaron.Plugins.GZip.PluginLoader.Instance.EnsureLoaded();

接着是

 var service = this.GetService<IGZipStreamFactory>();
 var unzipped = service.Decompress(inputStream);

对于每个实际的平台实现,然后准备一个特定于平台的库,实现GZip工厂接口,并提供一个简单的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和平台特定的实现 - 它应该都可以工作!

注意这里有一些基于约定的基于魔法的魔法 - 框架根据PCL插件命名空间Cheesebaron.Plugins.Gzip.Droid.dll加载程序集Cheesebaron.Plugins.Gzip

(对于WP7和其他平台,还有一个额外的步骤 - 有一个覆盖注册插件的设置方法)


注意您可以在单个PlugIn中注册任意数量的服务,并且您也可以执行额外的常见初始化/设置代码。这有助于减少一些项目维护开销:如果您愿意,可以将您的CheeseBaron IoC对象放在一个CheeseBaron.Plugins.Utils项目中,然后在所有应用程序中共享这一个插件。

DownloadCache插件提供了一小部分内容 - 它会注册所有IMvxHttpFileDownloaderIMvxImageCacheIMvxLocalFileImageLoader

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


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

有关在以下位置创建插件的更多信息:

有关插件的示例(并非所有平台上都提供),请参阅https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins


其他路线

如果您不想使用插件 - 例如如果您匆忙或者您正在编写一个您不想重复使用的模块的代码,那么还有其他选择:

  • 您可以在共享Core PCL库中定义类似IGZipStreamFactory的界面。然后,您可以在每个UI项目中提供此接口的特定于平台的实现,然后可以在ViewModel / Model / Service层中使用普通的IoC / DI,以便在运行时找到正确的实现。

或者...

  • 您可以转储共享的PCL核心库并创建单独的特定于平台的DLL,然后在其中手动链接特定于平台的文件(我尝试从不这样做,但其他人喜欢它)