我有使用C#
,WPF
,ASP.NET WebAPI
和Entity Framework
一个客户机/服务器溶液。客户端和服务器端在他的项目中共享模型。现在我试图创建一个新的客户端,使用Xamarin Forms并共享模型,但实体框架属性(MaxLength
,Index
,NotMapped
等),不兼容PCL。所以这是我试过的东西:Xamarin形式和的EntityFramework属性兼容性
导入Microsoft.EntityFrameworkCore到PCL模式
如上所述here,你应该能够使用实体框架与Xamarin的形式,所以我转换PCL到NetStandard 1.3,它工作,每个EntityFramework属性都是允许的。但是现在服务器项目与该标准不兼容,我不能在模型项目中添加像prism和Newtonsoft.Json这样的包。
模拟使用偷梁换柱伎俩
我已经想尽了办法描述here的基础上,创建自定义模型中的PCL属性,并在类库重新定义他们Xamarin形式的属性。 MyClient.Droid和MyClient.UWP重新定义了属性,使它们为空,MyServer将使用实体框架功能重新定义它们。
定制IndexAttribute - 型号PCL:
namespace Model.Compatibility
{
public class IndexAttribute : Attribute
{
public IndexAttribute()
{
}
}
}
定制IndexAttribute - 服务器端:
[assembly: TypeForwardedToAttribute(typeof(Model.Compatibility.IndexAttribute))]
namespace Model.Compatibility
{
public class MockedIndexAttribute : System.ComponentModel.DataAnnotations.Schema.IndexAttribute
{
public MockedIndexAttribute()
{
}
}
}
我测试这种形式给出调用var attribute = new Model.Compatibility.IndexAttribute();
。 MockedIndexAttribute构造函数永远不会被调用。
创建相反PCL
的共享项目这种方式是多了几分凌乱,但看起来像它的工作原理。刚刚创建的模型一个新的共享项目,以及使用条件的标志是这样的:
#if !__MOBILE__
[NotMapped, Index]
#endif
public Guid Id { get; set; }
我还没有完全部署在目前这种做法,但如果我不能没有的前两种方式的工作,我将与此一起去。
编辑 - 设法使“偷梁换柱属性”的方式工作
由于@AdamPedley sugested和this线程,我已经重新定义IndexAttribute在新PCL(Xamarin.Compatibility),使用与原来的名称空间相同:
namespace System.ComponentModel.DataAnnotations.Schema
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute() { }
}
}
现在,我的PCL模型包含对Xamarin的引用。兼容性,所以我可以在我的模特属性使用索引属性:
[Index]
public Guid Id { get; set; }
然后,从我的服务器项目,我打电话的代码来检查叫什么构造,自定义属性,或者通过定义的下一行的EntityFramework:
PropertyInfo prop = typeof(MyClass).GetProperty("Id");
object[] attributes = prop.GetCustomAttributes(true);
称为构造函数是自定义的,所以这是行不通的,因为它必须调用通过的EntityFramework定义的属性。多数民众赞成是我不知道的是什么机制,使我的模型的PCL选择自定义属性或EF属性取决于调用程序集。
我也是在我的服务器项目添加一个文件,叫TypeForwarding.Net.cs(如sugested here),包含:
[assembly: TypeForwardedTo(typeof(IndexAttribute))]
但仍然没有工作。
什么是与偷梁换柱技术问题,分享项目。有什么不适合你吗?它是这个问题的最干净的解决方案。 –
@AdamPedley问题是我无法使它工作。正如我所说的,当我从我的服务器端的类中创建Model.Compatibility.IndexAttribute实例时,MockedAttribute构造函数未被调用,因此它不起作用。我应该做错了什么,你能向我展示一个应用于重新定义属性的诱饵和切换技术的例子吗? – Jose
属性构造函数只有在实际获取该模型的属性并尝试读取它们时才会运行。它不一定会在你打电话时运行。通过调用typeof(MyModel).GetCustomAttributes(true)来测试它;在实际上具有附加属性的模型上。 –