POCO和实用方法

时间:2014-04-15 20:13:12

标签: c# poco

让我们假设我有一个包含foosbars的POCO类:

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;
}

在我的示例中,我需要能够添加和删除foosbars

public class Poco {
  public IList<Foo> Foos { get { return foos; } }
  public IList<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;
}

但是我要说我还需要(任意)约束,每个foo必须有一个bar,每个bar一个foo

public class NotAPocoAnyMore {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;

  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
}

我的问题是:我是否正在努力保持POCO简单而不给它任何实用方法?第一个例子POCO很好,因为它是不可变的,POCO还有其他优点。但是,我看不到一种方法可以让这个类成为一个POCO,并且仍然有办法以受控的方式访问和修改内容(至少不是一种似乎没有过度杀戮的方式)。

有人认为我有:

嵌套修改类

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }
  public PocoModifier Modifier { get { ... } }

  private List<Foo> foos;
  private List<Bar> bars;

  public class PocoModifier {
    private readonly Poco toModify;
    public void Add(Foo f, Bar b) {...}
    public void Remove(Foo f, Bar b) {...}
    ...
  }
}

公共嵌套类?不用了,谢谢!它实际上只是与非POCO类相同,只是更多的嵌套。

使用访问修饰符

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }
  public PocoModifier Modifier { get { ... } }

  internal List<Foo> foos;
  internal List<Bar> bars;
}

public class PocoModifier {
  private readonly Poco toModify;
  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
  ...
}

略好一些,但每个POCO需要整个部署单元。

3 个答案:

答案 0 :(得分:12)

听起来您的数据会更好地通过自然地将FooBar配对的内容进行建模。

public class Poco {
  public IList<Tuple<Foo, Bar>> FooBars { get { return fooBars; } }

  private List<Tuple<Foo, Bar>> fooBars;
}

除非出于某种奇怪的原因,FooBar是完全分开的,除非要求它们的计数相同。然后我喜欢你的第三个例子......

public class NotAPocoAnyMore {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;

  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
}
在我看来,

PocoModifier增加了不必要的复杂性。嵌套类通常不应该是公共的(所以如果你有这个类,那就像上一个例子中那样分开)。

如果您还需要POCO(例如,公开向使用您的代码作为库的人公开,同时保持其他逻辑内部),您可以创建一个普通的POCO,然后将其映射到{{1}与AutoMapper(或类似)。

NotAPocoAnyMore

答案 1 :(得分:2)

POCO仅代表一组数据/信息。一旦开始强制执行规则作为约束或更好地组织数据的方式,您就开始定义数据的行为。突然间,你不再处理POCO了,它变成了一个完整的数据结构。

如何实现这一点取决于您。如果您想使用POCO,您可以使用Helpers / Extensions或您想要的任何内容来隔离您的数据和行为,或者您可以通过在单个实体中组合数据及其行为来构建您自己的数据结构。

它们中的任何一个都没有错,虽然有些人更喜欢使用POCO,但我通常更喜欢使用数据结构来封装数据及其在单个实体中的行为。

答案 2 :(得分:0)

我使用存储库来处理持久的POCO(使用EF)。以下是通用存储库的示例:

public interface IRepository<T>
{
    void Add(T entity);
    void Remove(T entity);
    ...
}

public class Repository<T> : IRepository<T>
{   
    // dbset or list or whatever you're persisting to

    public void Add(T entity) {
       // add to dbSet
    }     
    public void Remove(T entity) {
       // remove from dbSet
    }
}

它的用法

var repo = new Repository<User>();
repo.Add(new User());

你现在并没有弄乱你的POCO并且有一个专门用来坚持你的POCO的对象。我不是通用存储库的粉丝 - 对于一个快速的例子来说是好的。您可以使用更具体的检索方法为每个实体创建特定的存储库。