领域建模 - 实现属性接口或 POCO?

发布于 2024-10-16 01:20:55 字数 731 浏览 1 评论 0原文

我正在制作一个工具原型,该工具将通过 SOAP api 将文件导入到基于 Web 的应用程序,并对我尝试通过 C# 接口导入的内容进行建模,以便我可以将 Web 应用程序的模型数据包装在我可以处理的内容中。

public interface IBankAccount
{
    string AccountNumber { get; set; }
    ICurrency Currency { get; set; }
    IEntity Entity { get; set; }
    BankAccountType Type { get; set; }
}

internal class BankAccount
{
    private readonly SomeExternalImplementation bankAccount;

    BankAccount(SomeExternalImplementation bankAccount)
    {
        this.bankAccount = bankAccount;
    }

    // Property implementations
}

然后,我有一个返回 IBankAccount 或其他集合的存储库,以及一个工厂类,用于在我需要时为我创建 BankAccount。

我的问题是,这种方法会给我带来很多痛苦,创建 POCO 会更好吗?我想将所有这些放在一个单独的程序集中,并将数据访问和业务逻辑完全分离,只是因为我正在处理一个关于数据在线存储位置的移动目标。

I'm prototyping a tool that will import files via a SOAP api to an web based application and have modelled what I'm trying to import via C# interfaces so I can wrap the web app's model data in something I can deal with.

public interface IBankAccount
{
    string AccountNumber { get; set; }
    ICurrency Currency { get; set; }
    IEntity Entity { get; set; }
    BankAccountType Type { get; set; }
}

internal class BankAccount
{
    private readonly SomeExternalImplementation bankAccount;

    BankAccount(SomeExternalImplementation bankAccount)
    {
        this.bankAccount = bankAccount;
    }

    // Property implementations
}

I then have a repository that returns collections of IBankAccount or whatever and a factory class to create BankAccounts for me should I need them.

My question is, it this approach going to cause me a lot of pain down the line and would it be better to create POCOs? I want to put all of this in a separate assembly and have a complete separation of data access and business logic, simply because I'm dealing with a moving target here regarding where the data will be stored online.

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

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

发布评论

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

评论(1

柠檬 2024-10-23 01:20:55

这正是我使用的方法,而且我从未遇到过任何问题。在我的设计中,来自数据访问层的任何内容都被抽象为接口(我将它们称为数据传输契约)。然后,在我的域模型中,我有静态方法从这些数据传输对象创建业务实体。

interface IFooData
{
    int FooId { get; set; }
}

public class FooEntity
{
    static public FooEntity FromDataTransport(IFooData data)
    {
        return new FooEntity(data.FooId, ...);
    }
}

当您的域模型实体从多个数据契约收集数据时,它非常方便:

public class CompositeEntity
{
    static public CompositeEntity FromDataTransport(IFooData fooData, IBarData barData)
    {
        ...
    }
}

与您的设计相反,我不提供工厂创建数据传输契约的具体实现,而是提供委托来写入值并让存储库担心创建具体对象的

public class FooDataRepository
{
    public IFooData Insert(Action<IFooData> insertSequence)
    {
        var record = new ConcreteFoo();

        insertSequence.Invoke(record as IFooData);

        this.DataContext.Foos.InsertOnSubmit(record); // Assuming LinqSql in this case..

        return record as IFooData;
    }
}

使用:

IFooData newFoo = FooRepository.Insert(f =>
    {
        f.Name = "New Foo";
    });

尽管在我看来,工厂实现是一个同样优雅的解决方案。为了回答你的问题,根据我对非常类似方法的经验,我从未遇到过任何重大问题,我认为你在这里走在正确的轨道上:)

This is exactly the approach I use and I've never had any problems with it. In my design, anything that comes out of the data access layer is abstracted as an interface (I refer to them as data transport contracts). In my domain model I then have static methods to create business entities from those data transport objects..

interface IFooData
{
    int FooId { get; set; }
}

public class FooEntity
{
    static public FooEntity FromDataTransport(IFooData data)
    {
        return new FooEntity(data.FooId, ...);
    }
}

It comes in quite handy where your domain model entities gather their data from multiple data contracts:

public class CompositeEntity
{
    static public CompositeEntity FromDataTransport(IFooData fooData, IBarData barData)
    {
        ...
    }
}

In contrast to your design, I don't provide factories to create concrete implementations of the data transport contracts, but rather provide delegates to write the values and let the repository worry about creating the concrete objects

public class FooDataRepository
{
    public IFooData Insert(Action<IFooData> insertSequence)
    {
        var record = new ConcreteFoo();

        insertSequence.Invoke(record as IFooData);

        this.DataContext.Foos.InsertOnSubmit(record); // Assuming LinqSql in this case..

        return record as IFooData;
    }
}

usage:

IFooData newFoo = FooRepository.Insert(f =>
    {
        f.Name = "New Foo";
    });

Although a factory implementation is an equally elegant solution in my opinion. To answer your question, In my experience of a very similar approach I've never come up against any major problems, and I think you're on the right track here :)

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