使用存储库模式为从同一基础对象派生的聚合提供通用功能

发布于 2024-08-03 11:48:24 字数 1162 浏览 2 评论 0原文

我正在尝试使用存储库模式在现有的 DB2 模式上编写数据访问层。该模式具有多个聚合,所有聚合都具有“文档”的公共基本实体。在构建业务对象时,我将文档实体创建为抽象,并将聚合创建为从文档派生的实体。例如:

public abstract class Document
{
    public long Id{ get; set; }
    public int PageCount{ get; set; }
    public string Path{ get; set; }
}

public class LegalDocument : Document
{
    public int CaseNumber{ get; set; }
}

public class BillingDocument : Document
{
    public int InvoiceNumber{ get; set; }
    public double AmountDue{ get; set; }
}

现在,我想为 BillingDocument 创建一个存储库,但我知道我不想加载 BillingDocument 存储库中的所有文档基本属性,因此我创建了另一个带有泛型类型参数的抽象类对于此功能。但是,我让编码器块弄清楚如何返回抽象文档实体的实例,该实例将由我将为派生聚合实体编码的存储库使用。我可以通过反思来做到这一点,如下所示,但感觉完全不对。

abstract class DocumentRepositoryBase<TDocument>
{
    internal Document LoadDocumentBaseProperties(long documentId)
    {
        //Call the database and get the base properties and add them to....this?
        var documentBase = 
            (Document)typeof(TDocument).GetConstructor(Type.EmptyTypes).Invoke(null);
        //Set the documentBase properties
        return documentBase;
    }
}

我整个人都扭曲了有人可以向我保证这没问题,或者告诉我我是个白痴并告诉我更好的方法吗?

提前致谢。

I'm attempting to use the Repository Pattern to write a data access layer on an existing DB2 schema. This schema has several aggregates all having a common base entity of a "Document." When building the business objects, I created the Document entity as an abstract, and the aggregates as entities derived from Document. For example:

public abstract class Document
{
    public long Id{ get; set; }
    public int PageCount{ get; set; }
    public string Path{ get; set; }
}

public class LegalDocument : Document
{
    public int CaseNumber{ get; set; }
}

public class BillingDocument : Document
{
    public int InvoiceNumber{ get; set; }
    public double AmountDue{ get; set; }
}

Now, I want to create a Repository for BillingDocument, but I know that I don't want to load up all of the Document base properties in my BillingDocument repository, so I've created another abstract class with a generic type parameter for this functionality. However, I'm having coder's block figuring out how to return an instance of the abstract Document entity, which will be used by Repositories I will code for the derived aggregate entities. I can do it with reflection, as follows, but it feels all wrong.

abstract class DocumentRepositoryBase<TDocument>
{
    internal Document LoadDocumentBaseProperties(long documentId)
    {
        //Call the database and get the base properties and add them to....this?
        var documentBase = 
            (Document)typeof(TDocument).GetConstructor(Type.EmptyTypes).Invoke(null);
        //Set the documentBase properties
        return documentBase;
    }
}

I'm all twisted up. Can someone please assure me that this is OK, or tell me I'm an idiot and show me a better way?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

榕城若虚 2024-08-10 11:48:24

考虑在存储库类型中使用通用约束,如下所示:

abstract class DocumentRepositoryBase<TDocument>
  // requires it to be a document derivative and have default constructor
  where TDocument : Document, new() 
{
  internal Document LoadDocumentBaseProperties( long documentId )
  {
     var doc = new TDocument();
     return doc;
  }
}

顺便说一句,这不会返回抽象类的实例...它返回任何 TDocument 可能的实例(其中之一)衍生品),但通过对基本 Document 类型的引用。

Consider using a generic constraint in your repository type, like so:

abstract class DocumentRepositoryBase<TDocument>
  // requires it to be a document derivative and have default constructor
  where TDocument : Document, new() 
{
  internal Document LoadDocumentBaseProperties( long documentId )
  {
     var doc = new TDocument();
     return doc;
  }
}

By the way, this is not returning an instance of an abstract class ... it returns an instances of whatever TDocument may be (one of the derivatives) but via a reference to the base Document type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文