C# MonoDroid和MonoTouch共享库

C# MonoDroid和MonoTouch共享库,c#,xamarin.ios,shared-libraries,xamarin.android,xamarin,C#,Xamarin.ios,Shared Libraries,Xamarin.android,Xamarin,因此,我的公司来自一个完全C#Net的环境,所以我们自然会将Mono用于移动开发。我们有一个非常广泛的windows平台库,我可以将它的大部分移植为Android类库。我们的想法是,这个Android类库将是我们的移动平台库,将来可以在MonoTouch中重用(尚未测试,但阅读到MonoTouch项目可以引用Android类库,只要没有特定于Android的代码)。不过,在库中有大量的日志记录语句,对于windows环境,这些语句最终只是跟踪语句(包装在自定义帮助程序类中)。我们希望保留日志记录

因此,我的公司来自一个完全C#Net的环境,所以我们自然会将Mono用于移动开发。我们有一个非常广泛的windows平台库,我可以将它的大部分移植为Android类库。我们的想法是,这个Android类库将是我们的移动平台库,将来可以在MonoTouch中重用(尚未测试,但阅读到MonoTouch项目可以引用Android类库,只要没有特定于Android的代码)。不过,在库中有大量的日志记录语句,对于windows环境,这些语句最终只是跟踪语句(包装在自定义帮助程序类中)。我们希望保留日志记录语句,并基于当前环境(iOS或Android),将其转换为本机日志记录

我计划在移动平台库中使用部分声明进行日志记录,并让特定于Android和iOS的库包含这些部分日志记录方法的实现。但当我意识到程序集之间的部分不起作用时,这一点就分崩离析了

所以现在我不知道该怎么做。如果有两个独立的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);
        }
    }
}

解决这一问题的最简单方法是设置一个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项目中的所有文件。然后,您可以设置一个
MONOTOUCH
编译器标志,以便在需要时使用特定的iOS或Android代码


我们一直都采用这种方法,而且由于其灵活性,有时更喜欢使用PCLs(可移植类库)。

在mvvmcross中,我使用接口解决了这一问题

我声明了一个通用的IMVXStrace接口,然后添加了它的单例实现,如:

此单例使用底层的_realTrace实现

在droid上,比赛是:

在触摸屏上,这场比赛是:

同样,wpf、win8和wp上也有自定义实现

我使用文件链接(在master中)完成了这项工作,但最近使用了pcl和平台特定库的混合。我个人喜欢PCL,因为我喜欢使用重构工具——PCL比#if代码更适合这些工具。此外,当我将代码从1个平台扩展到6个平台时,我发现6组#if语句过于复杂,无法维护


请注意,上面的代码还使用依赖项注入和IOC技术。我发现这对跨平台代码共享非常有用。有几个可移植的IOC库可用,包括tinyioc、xplatutils、opennetcf和mvvmcross的简单IOC。

不确定我是否可以提供具体建议,因为您不想更改日志记录语句。在我的公司,我们也在Windows/Silverlight/Android/Unity3D之间共享代码,但我们已经用一个可重用的界面抽象了我们的日志实现。作为应用程序引导的一部分,我们在后台附加了一个特定于平台的记录器。因此,我们访问记录器的所有代码都通过静态工厂访问可重用的
ILog
接口,并且不知道所使用的平台细节。(也有助于根据需要在同一平台内连接不同的记录器)(续)当然,这可能意味着您必须改变从业务逻辑记录日志的方式。也许你应该发布一个代码示例,说明你的业务/UI层当前如何记录日志,以及你愿意在多大程度上(如果有的话)进行更改。Chris-100%同意你的评论-你应该将其作为一个答案来写。如果我添加Android和iOS特定的代码,这是否意味着我将无法在两个项目中引用此库?拥有两个库(iOS和Android)以及它们之间的“链接”文件似乎不太理想。谢谢。如果您有任何特定于平台的代码,您将不得不在某种程度上这样做。使用PCLs是一个好主意(如Stuart所建议的),但您仍然需要在每个平台上删除接口。