在服务层中使用私有setter构建业务集合

时间:2011-01-19 20:32:29

标签: c#

通常我认为这段代码是一个很好的设计:

查看该集合的私人二传手。所以没有人可以从schoolclass对象之外分配一个新的集合。

public class Schoolclass
    {
        public Schoolclass()
        {
            Pupils = new List<Pupil>();
        }            

        public int SchoolclassId { get; set; }
        public string SchoolclassCode { get; set; }

        public List<Pupil> Pupils { get; private set; }
    }

关于这种风格,我的数据提取方法不再起作用了:

服务层执行对SQLite数据提供程序的调用:

BL:

public IEnumerable<Schoolclass> GetAdministrationData()
        {
            var schoolclasses = adminDataProvider.GetSchoolclassList();
            foreach (Schoolclass s in schoolclasses)
            {
                var pupils = adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
                s.Pupils = pupils;

                foreach (Pupil p in pupils)
                {
                    var documents = adminDataProvider.GetDocumentsByPupilId(p.Id);
                    p.Documents = documents;
                }
            }
            return schoolclasses;
        }

如果我现在有一个私人的定位器,上面的聚合将不起作用。

我还有另一种选择吗?或者我应该坚持我的装载技术?

2 个答案:

答案 0 :(得分:1)

是的,你有很多选择:

将学生添加到已创建的列表中。

var pupils = adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
s.Pupils.AddRange(pupils);

foreach (Pupil p in pupils)
{
   var documents = adminDataProvider.GetDocumentsByPupilId(p.Id);
   p.Documents.AddRange(documents);
}

请注意,公开List<T>是一种不好的形式 - 最好公开Collection<T>,但是您必须逐个添加项目。

如果你写这样的人:

public class Schoolclass
{
    public Schoolclass()
    {
        Pupils = new BindingList<Pupil>(); 
            // binding list descends from Collection<T> 

    }            

    public int SchoolclassId { get; set; }
    public string SchoolclassCode { get; set; }

    public Collection<Pupil> Pupils { get; private set; }
}

当然,有1000,000种方式甚至更多来编写这个和装载机。我喜欢懒惰加载自己。然后,当你有人要求学生时,你只加载它们。

答案 1 :(得分:1)

这是immutability的问题。您的List<Pupil>属性仍然是可变的,即使使用私有的setter也是如此。

我无法直接设置您的Pupils属性:

myclass.Pupils = new List<Pupil>();

...但我可以修改

var myClass = new SchoolClass();
myClass.Pupils.Add(new Pupil());

这是一篇很好的文章,讨论C#中不同类型的不变性:

http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx