适用于MonoDroid和MonoTouch的共享库

5
我的公司完全使用C# .Net环境,因此我们自然而然地考虑使用Mono进行移动开发。我们有一个非常广泛的Windows平台库,我已经将其中大部分作为Android类库移植了过去。我们的想法是这个Android类库将成为我们的移动平台库,并在未来可以重复使用于MonoTouch(尚未测试,但据说MonoTouch项目只要没有特定于Android的代码就可以引用Android类库)。但在库中,有很多日志记录语句,在Windows环境下只是跟踪语句(包装在自定义帮助器类中)。我们想保留这些日志记录语句,并根据当前的环境(iOS或Android),将其转换为本机日志记录。
我计划在移动平台库中使用partial声明记录,并让Android和iOS特定的库包含这些partial记录方法的实现。但当我意识到分部在程序集之间不起作用时,这个想法就破灭了。
现在我不确定该怎么做。我能想到的唯一办法就是有两个独立的iOS和Android平台库,并链接相同的文件。(Xamarin可能有一个日志记录类可以做到这一点,但我们仍需要为任何其他未来的抽象制定模式)
欢迎提出任何建议。由于我们仍处于试验/规划阶段,所以有可能我们会忽略某些东西,请让我们知道。
谢谢。
编辑 假设我有以下简单的静态类。
public static class TraceHelper
{
    public static void WriteLine(string message)
    {
        // Validation and preprocessing
        Trace.WriteLine(message);
    }
}

我有数百个在移动平台库中调用此方法的请求。现在假设我在我的Android应用程序中引用了这个库,有没有办法在不修改库本身的情况下覆盖TraceHelper.WriteLine()的实现?

更新
我们最终创建了Android和iOS库,实现了缺失的.NET功能。只需在相同的.NET命名空间和类中包装本机等效功能即可。例如:

using Android.Util;

namespace System.Diagnostics
{
    public static class Trace
    {
        #region Non-Public Data Members

        private const string Tag = "Trace";

        #endregion

        public static void WriteLine(string message)
        {
            Log.WriteLine(LogPriority.Verbose, Tag, message);
        }
    }
}

5
由于您不希望更改记录语句,我不确定能否提供具体建议。在我们公司,我们将代码共享到Windows / Silverlight / Android / Unity3D等平台上,并使用可重用接口来抽象化我们的日志记录实现。作为应用程序引导的一部分,我们在后台附加特定于平台的记录器。因此,我们所有访问记录器的代码都通过静态工厂命中可重用的“ILog”接口,并且没有了解正在使用的平台细节。(还可以在同一平台上随意附加不同的记录器) - Chris Sinclair
1
当然,这可能意味着您需要更改从业务逻辑记录日志的方式。也许您应该发布一个代码示例,展示您的业务/UI层当前如何记录日志以及在多大程度上(如果有)您愿意更改它。 - Chris Sinclair
Chris - 我完全同意你的评论 - 你应该把它写成一个答案。 - Stuart
2个回答

2
在mvvmcross中,我使用接口解决了这个问题。
我声明了一个通用的IMvxTrace接口,然后添加了它的单例实现,如下所示:

https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Platform/Diagnostics/MvxTrace.cs

这个单例使用了一个基础的_realTrace实现。
在droid上,_realTrace是:

https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Platform/MvxDebugTrace.cs

并且在触摸时,_realTrace 是:

https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Touch/Platform/MvxDebugTrace.cs

同样,在wpf、win8和wp上也有定制的实现。
我曾经使用文件链接(在主分支中)以及最近使用混合PCL和特定平台的库来完成这个任务。个人偏好PCL,因为我喜欢使用重构工具——这些工具与PCL的兼容性比#if代码要好得多。此外,随着我的代码从1个平台增长到6个平台,我发现维护6组#if语句过于复杂。
请注意,上面的代码还使用了依赖注入和IOC技术。我发现这对跨平台代码共享非常有帮助。有几个可移植的IOC库可用,包括tinyioc、xplatutils、opennetcf和mvvmcross的简单IOC。

0
最简单的解决方法是设置一个iOS项目,你基本上只需要这样做:
public static class TraceHelper
{
    public static void WriteLine(string message)
    {
#if MONOTOUCH
        Console.WriteLine(message);//or something else
#else
        Trace.WriteLine(message);
#endif
    }
}

你可以创建一个MonoTouch类库项目,并将所有文件从原始的Mono for Android项目“链接”进来。然后,如果需要特定的iOS或Android代码,您可以设置MONOTOUCH编译器标志。
我们经常采用这种方法,并且有时候更喜欢它,因为它更灵活,而不是使用PCL(可移植类库)。

如果我添加Android和iOS特定的代码,那么这是否意味着我将无法在任何一个项目中引用此库?拥有两个库(iOS和Android)并在它们之间“链接”文件似乎不是最理想的选择。谢谢。 - Alex
如果您有任何特定于平台的代码,那么您将不得不在某种程度上执行该操作。使用PCL是一个好主意(就像Stuart所建议的那样),但您仍然需要在每个平台上存根接口。 - jonathanpeppers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接