使 PCL Xamarin (MonoDroid/MonoTouch) 兼容的问题

Posted

技术标签:

【中文标题】使 PCL Xamarin (MonoDroid/MonoTouch) 兼容的问题【英文标题】:Troubles making PCL Xamarin (MonoDroid/MonoTouch) compliant 【发布时间】:2013-11-28 02:41:12 【问题描述】:

我们创建了一个相当强大的 PCL,我们希望通过 Xamarin 在一些 Droid/Touch 应用程序中使用它。

截至今天,我已经安装了最新版本的 Xamarin,并将我们的 PCL 设置为 use Profile 158。

然后我进入了我们的项目并更新了目标程序集

.NET Framework 4.5 Windows Phone 8 .NET 用于 Windows 应用商店应用 Xamarin.android Xamarin.ios

这样做之后,我遇到了一些编译失败

full size image here

我是否需要将 System dll 替换为 Xamarin 附带的那个,或者我需要做些什么才能让这些东西正常工作?

注意:如果我在上面不清楚,在添加 Xamarin 目标之前 PCL 没有任何问题。


根据要求,这是构建输出

1>------ Build started: Project: MyApplication.AppCore, Configuration: Debug Any CPU ------
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(25,29,25,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(25,43,25,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(53,29,53,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(53,43,53,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(55,38,55,71): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(55,52,55,67): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(85,29,85,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(85,43,85,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(102,29,102,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(102,43,102,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(120,29,120,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(120,43,120,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(144,29,144,61): error CS1502: The best overloaded method match for 'MyApplication.AppCore.Data.DbProviderExtensions.GetTableName(System.Reflection.MemberInfo)' has some invalid arguments
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(144,43,144,57): error CS1503: Argument 1: cannot convert from 'System.Type' to 'System.Reflection.MemberInfo'
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(171,41,171,54): error CS1061: 'System.Type' does not contain a definition for 'GetProperties' and no extension method 'GetProperties' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Data\DbProviderExtensions.cs(239,25,239,38): error CS1061: 'System.Type' does not contain a definition for 'GetInterfaces' and no extension method 'GetInterfaces' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\AutoMapper.cs(18,54,18,67): error CS1061: 'System.Type' does not contain a definition for 'GetProperties' and no extension method 'GetProperties' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\AutoMapper.cs(47,54,47,67): error CS1061: 'System.Type' does not contain a definition for 'GetProperties' and no extension method 'GetProperties' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\AutoMapper.cs(78,50,78,63): error CS1061: 'System.Type' does not contain a definition for 'GetProperties' and no extension method 'GetProperties' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\AutoMapper.cs(100,50,100,63): error CS1061: 'System.Type' does not contain a definition for 'GetProperties' and no extension method 'GetProperties' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\MigrationRunner.cs(61,40,61,48): error CS1061: 'System.Type' does not contain a definition for 'Assembly' and no extension method 'Assembly' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Infrastructure\MigrationRunner.cs(62,77,62,93): error CS1061: 'System.Type' does not contain a definition for 'IsAssignableFrom' and no extension method 'IsAssignableFrom' accepting a first argument of type 'System.Type' could be found (are you missing a using directive or an assembly reference?)
1>P:\MyApplication.AppCore\MyApplication.AppCore\Repositories\RepositoryBase.cs(60,30,60,50): error CS0117: 'System.Reflection.Assembly' does not contain a definition for 'GetExecutingAssembly'
2>------ Build started: Project: MyApplication.AppCore.Tests, Configuration: Debug Any CPU ------
2>  P:\MyApplication.AppCore\MyApplication.AppCore.Tests\x86\sqlite3.dll
2>  1 File(s) copied
2>  P:\MyApplication.AppCore\MyApplication.AppCore.Tests\x64\sqlite3.dll
2>  1 File(s) copied
2>  MyApplication.AppCore.Tests -> P:\MyApplication.AppCore\MyApplication.AppCore.Tests\bin\Debug\MyApplication.AppCore.Tests.dll
========== Build: 1 succeeded, 1 failed, 4 up-to-date, 0 skipped ==========

不确定查看一些代码行是否会有所帮助,但是,这里是

    public static void Create<TModel> ( this IDbProvider dbProvider, TModel model ) where TModel : class, new()
    

        var tableName = GetTableName( typeof( TModel ) ); // LINE 25

    
foreach ( 
    var collection in model.GetType()
                           .GetProperties() // LINE 171
                           .Where(
                               property =>
                               property.GetCustomAttributes( typeof( ManyToManyAttribute ), true ).Any() ) )

        if ( !IsGenericList( collection.PropertyType ) )  // LINE 176
            throw new ArgumentException( "The property must be an ICollection<>" );

    private static bool IsGenericList ( Type type )
    
        if ( type == null )
            throw new ArgumentNullException( "type" );

        return type.GetInterfaces() // LINE 239
                   .Where( i => i.IsGenericType )
                   .Any( i => i.GetGenericTypeDefinition() == typeof( ICollection<> ) );
    

【问题讨论】:

是否强制您使用新的反射 API? @atomaras 我不知道有一个新的反射 API。 请显示一些代码,例如 DbProviderExtensions.cs 中的第 25、171 和 239 行。 我添加了几行代码,但我不确定它们是否会有所帮助。正如我所说,在尝试将 Xamarin 目标添加到 PCL 之前,这一切都有效。 @AndersGustafsson 我已经发布了一些代码......不确定它是否有用。 【参考方案1】:

Profile158 除了您列出的其他目标外,还针对 Silverlight 5。在添加 Xamarin 支持之前,您的目标是什么配置文件?

要尝试的一件事是针对 Profile78,它应该是您列出的平台集。

如果这不起作用,您能否使用从构建输出中复制的错误更新您的答案?屏幕截图中的错误很难阅读,不清楚它们是否都来自同一个项目。

【讨论】:

之前的 Profile 是 104。所有错误都来自同一个项目,并且在屏幕截图下方有一个指向完整尺寸图像的链接。 @ChaseFlorell 您可以尝试将其更改回 Profile104 并查看它是否仍能成功编译吗?此外,PCL 不应该有任何对 .NET Framework 程序集(例如 System.DLL 或 mscorlib)的显式引用,因此如果您的项目中有任何这些,请尝试删除它们。 我实际上已经开始重构项目以使用为 WinRT 应用程序指定的反射。似乎正在取得进展……将发布调查结果。

以上是关于使 PCL Xamarin (MonoDroid/MonoTouch) 兼容的问题的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin Monodroid:WP7 => Android 和自定义控件?

Monodroid 和 adMob 插页式广告

Monodroid 和 adMob 插页式广告

来自 PCL 的 Xamarin WebAPI 调用

忽略 Xamarin.Forms (PCL) 中的 SSL 证书错误

在 monotouch/monodroid 中使用 mocks 进行单元测试