是否有可能在C#中有额外的(忽略)属性?
我有一个DocumentDb
数据库的存储库。我的文档都有一组共同属性,所以所有文档都实现了IDocumentEntity接口。是否有可能在C#中有额外的(忽略)属性?
public interface IDocumentEntity {
[JsonProperty("id")]
Guid Id { get; set; }
[JsonProperty("documentClassification")]
DocumentClassification DocumentClassification { get; set; }
}
public class KnownDocument : IDocumentEntity {
[JsonProperty("id")]
Guid Id { get; set; }
[JsonProperty("documentClassification")]
DocumentClassification DocumentClassification { get; set; }
[JsonProperty("knownProperty")]
string KnownProperty { get; set; }
}
public class BaseDocumentRepository<T> where T : IDocumentEntity {
public Set(T entity) {
// ... stuff
}
}
这工作正常与KnownDocument
我知道所有的属性。但是,当然,对于一个Document Db来说最棒的是我不需要知道所有的属性(并且在很多情况下我不会)。
所以我的客户端提交有点像这个 -
{unknownProperty1: 1, unknownProperty2: 2}
而且我想这UPSERT使用我的文档库。
public OtherDocumentService() {
_otherDocumentService = new OtherDocumentRepository();
}
public UpsertDocument(dynamic entity) {
entity.id = new Guid();
entity.documentClassification = DocumentClassification.Other;
_otherDocumentRepository.Set(entity);
}
,但我得到一个InvalidCastException从dynamic
到IDocumentEntity
。我认为这是因为动态对象上存在的额外属性,但不在IDocumentEntity
接口上?
我想要做的事情是让我的文档实体处于动态状态,但依靠一些属性来维护它们。
传递给UpsertDocument的实体参数应该明确地实现IDocumentEntity,以使代码有效,仅仅具有Id属性是不够的。
一些选项:
1)代理可以应用于:
public class ProxyDocumentEntity : IDocumentEntity
{
public dynamic Content { get; private set; }
public ProxyDocumentEntity(dynamic @content)
{
Content = @content;
}
public Guid Id
{
get { return Content.Id; }
set { Content.Id = value; }
}
}
...用
public void UpsertDocument(dynamic entity)
{
entity.Id = new Guid();
repo.Set(new ProxyDocumentEntity(entity));
}
所存储的文件将具有嵌套的对象属性,这可能是不能接受的
2)有一个lib https://github.com/ekonbenefits/impromptu-interface它创建代理dynamica lly 并且不会像上面的解决方案那样产生额外的属性。 缺点是性能不佳。
技术上讲,它可能是2种方法:
public void UpsertDocument(IDocumentEntity entity){...}
public void UpsertDocument(dynamic entity){...}
所以第一个(快)将为其实现IDocumentEntity和第二(慢)的其余对象的对象。 但是这是一个猜测,因为我不知道你所拥有的项目的整个代码库的细节。
如果你有一定的灵活性,以如何命名的动态属性,你可以把它们塞进你的对象上的字典属性:
public Dictionary<string, dynamic> extra { get; set; }
这是不幸的,但似乎是它必须要走的路 –