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

时间:2011-02-02 10:01:08

标签: c# design-patterns repository

我正在构建一个工具,它将通过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的集合或者其他工厂类,以便在需要时为我创建BankAccounts。

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

1 个答案:

答案 0 :(得分:4)

这正是我使用的方法,我从来没有遇到任何问题。在我的设计中,从数据访问层出来的任何东西都被抽象为一个接口(我将它们称为数据传输合同)。在我的域模型中,我有静态方法从这些数据传输对象创建业务实体。

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";
    });

虽然我认为工厂实施同样是一个优雅的解决方案。要回答你的问题,根据我对非常类似方法的经验,我从来没有遇到任何重大问题,我认为你在这里正确的方向:)