为了区分问题,在我当前的项目中,我决定在单独的程序集中完全分离我的DAL和BLL / Business对象。我希望将我的业务对象保持为简单的结构,而没有任何逻辑可以使事情变得非常简单。我想如果我可以将我的业务逻辑与我的DAL分开。所以我的应用程序将告诉我的DAL加载我的对象,我的DAL将运行到数据库并获取数据,用数据填充对象,然后将其传递回我的BLL。
问题 - 如何将DAL放在单独的程序集中并将数据推送到只读字段?
编辑:我注意到我可以有一个返回类型的ObjectBase,但实际上是返回一个对象或从ObjectBase派生的对象集合,所以对外界(在我的DAL之外)属性将是只读的,但我的派生类型(只能在我的DAL中访问)属性实际上是读/写。
答案 0 :(得分:7)
您可以通过构造函数设置只读属性。
答案 1 :(得分:1)
这是没有银弹的情况;最简单的选择是有限的或不符合您的要求,彻底的解决方案要么开始有气味,要么开始偏离简单。
也许最简单的选项是我在这里没有提到过的选项:保持字段/属性为私有,并将它们作为out
/ ByRef
参数传递给DAL。虽然它对大量字段不起作用,但对于少数字段来说很简单。
(我没有测试过,但我觉得值得探讨)。
public class MyObject()
{
private int _Id;
public int Id { get { return _Id; } } // Read-only
public string Name { get; set; }
// This method is essentially a more descriptive constructor, using the repository pattern for seperation of Domain and Persistance
public static MyObject GetObjectFromRepo(IRepository repo)
{
MyObject result = new MyObject();
return repo.BuildObject(result, out _Id);
}
}
public class MyRepo : IRepository
{
public MyObject BuildObject(MyObject objectShell, out int id)
{
string objectName;
int objectId;
// Retrieve the Name and Value properties
objectName = "Name from Database";
objectId = 42;
//
objectShell.Name = objectName;
Console.WriteLine(objectShell.Id); // <-- 0, as it hasn't been set yet
id = objectId; // Setting this out parameter indirectly updates the value in the resulting object
Console.WriteLine(objectShell.Id); // <-- Should now be 42
}
}
值得注意的是,尝试将域/业务对象保持在最低限度可能比您想象的要多。如果您打算对它们进行数据绑定,那么您将需要实现IPropertyNotifyChanged,这会阻止您使用自动实现的属性。您应该能够保持相当干净,但您必须为基本功能做出一些牺牲。
答案 2 :(得分:1)
这样可以很好地保存您的SoC模型,它不会增加太多的复杂性,它会阻止写入只读字段,您可以使用非常相似的模型来处理序列化问题。您的只读字段仍然可以由您的DAL写入,如果以类似的方式使用,您的序列化程序也可以写入 - 这意味着开发人员必须有意识地努力写入只读字段,以防止意外滥用。 / p>
模型项目
namespace Model
{
public class DataObject
{
public int id { get; protected set; }
public string name { get; set; }
}
}
数据项目
namespace Data
{
class DALDataObject : DataObject
{
public DALDataObject(int id, string name)
{
this.id = id;
this.name = name;
}
}
public class Connector
{
public static DataObject LoadDataObject(int objectId)
{
return new DALDataObject(objectId, string.Format("Dummy object {0}", objectId));
}
public static IEnumerable<DataObject> LoadDataObjects(int startRange, int endRange)
{
var list = new List<DataObject>();
for (var i = startRange; i < endRange; i++)
list.Add(new DALDataObject(i, string.Format("Dummy object {0}", i)));
return list;
}
}
}
答案 3 :(得分:0)
与它一起生活怎么样?
使用这些指南实施,但不要在模型中添加这样的硬约束。让我们说你这样做,但接下来需要序列化或做其他事情的另一个req,然后你就与它绑在一起。
正如你在其他评论中所说,你想要的是可互换的部分......所以,基本上你不需要与特定关系相关的东西。
更新1:或许“只是忍受它”太简单了,但我仍然要强调你不应该深入研究这些事情。使用简单的指导原则,保持代码清洁,并在开始时尽力使用SOLID。当一切都更加稳定时,重构不会妨碍进步。
毫无疑问,我根本不是一个没有任何思考就编写代码的人。但是,我已经采用了这样的方法,并且只有在少数情况下才会付出代价 - 没有任何迹象表明你不会通过简单和不断发展来获得类似的结果。
恕我直言,这个问题不适合需要在一开始就解决的重要架构问题。
先发制人的跟进:请注意,如果您不相信您的团队遵循简单的指导原则。还要确保从一些结构开始,选择一些场景,用真实的东西设置结构,当有简单时,团队会更好地了解他们的方式。
答案 4 :(得分:0)
在我看来,处理此问题的最佳方法是将业务对象和DAL放在由命名空间分隔的同一程序集中。这在逻辑上区分了这些问题,并允许您使用内部设置器。我想不出将它们分成自己的集合会有什么好处,因为没有另一个集合就没用了。