Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该如何设计我的对象模型,以便我的DAL可以填充只读字段?_C#_.net_Asp.net - Fatal编程技术网

C# 我应该如何设计我的对象模型,以便我的DAL可以填充只读字段?

C# 我应该如何设计我的对象模型,以便我的DAL可以填充只读字段?,c#,.net,asp.net,C#,.net,Asp.net,为了分离关注点,在我当前的项目中,我决定在单独的程序集中完全分离DAL和BLL/业务对象。我希望将我的业务对象保持为简单的结构,而不使用任何逻辑来保持事情极其简单。我希望我能将我的业务逻辑与DAL分开。因此,我的应用程序将告诉我的DAL加载我的对象,我的DAL将运行到数据库并获取数据,用数据填充对象,然后将其传递回我的BLL 问题-如何将DAL放在单独的程序集中,并将数据推送到只读字段中 如果我将getter设置为protected,那么继承的对象可以访问它,这并不是我真正想要的,因为我将返回

为了分离关注点,在我当前的项目中,我决定在单独的程序集中完全分离DAL和BLL/业务对象。我希望将我的业务对象保持为简单的结构,而不使用任何逻辑来保持事情极其简单。我希望我能将我的业务逻辑与DAL分开。因此,我的应用程序将告诉我的DAL加载我的对象,我的DAL将运行到数据库并获取数据,用数据填充对象,然后将其传递回我的BLL

问题-如何将DAL放在单独的程序集中,并将数据推送到只读字段中

  • 如果我将getter设置为protected,那么继承的对象可以访问它,这并不是我真正想要的,因为我将返回继承的对象类型,而不是原始的对象类型
  • 如果我将getter设置为internal,那么我的DAL必须与我不想要的BLL驻留在同一个程序集中
  • 如果我将getter设置为public,那么任何人都可以在它应该是只读的时候读/写它

编辑:我注意到,我可以使用ObjectBase的返回类型,但实际上是返回从ObjectBase派生的对象或对象集合,因此到外部世界(在我的DAL外部),属性将是只读的,但我的派生类型(仅在我的DAL内部可访问)属性实际上是读/写的。

您可以通过构造函数设置只读属性。

如何使用它

使用这些指导原则来实现,但不要在模型中添加这样一个硬约束。假设您这样做了,但随后出现另一个req,您需要序列化它或执行其他操作,然后您就与它绑定在一起了

正如你在其他评论中所说,你想要的是可以互换的部件。。。所以,基本上你不想要与特定关系有关的东西


更新1:也许“接受它”太简单了,但我还是要强调的是,你不应该深入这些事情。使用简单的指导原则,保持代码干净和坚实,这是您在开始时所能做的最好的事情。当一切都变得更加稳定时,它不会妨碍重构的进程,这并不难

别搞错了,我根本不是一个不假思索地写代码的人。但是,我已经采用了这种方法,只有在少数情况下,它们才有回报——没有任何迹象表明,通过简单化和进化,你不会得到类似的结果

IMHO这一点不适合在一开始就需要解决的重要架构问题


先发制人的跟进:如果您不能信任您的团队遵循简单的指导原则,请小心。也要确保从一些结构开始,选择几个场景,用真实的东西设置一个结构,当那里有简单的东西时,团队会更好地了解他们的方式。

这是一个没有银弹的情况;最简单的选择是有限的或不符合您的要求,彻底的解决方案要么开始有味道,要么开始偏离简单性

也许最简单的选择是我在这里没有提到的:将字段/属性保持私有,并将它们作为
out
/
ByRef
参数传递给DAL。虽然它对大量字段不起作用,但对少量字段则很简单

(我还没有测试过,但我认为值得探索)

公共类MyObject()
{
私人内部Id;
公共int-Id{get{return{u-Id;}}//只读
公共字符串名称{get;set;}
//该方法本质上是一个更具描述性的构造函数,使用存储库模式分离域和持久性
公共静态MyObject GetObjectFromRepo(IRepository repo)
{
MyObject结果=新的MyObject();
返回repo.BuildObject(结果,out\u Id);
}
}
公共类MyRepo:IRepository
{
公共MyObject BuildObject(MyObject objectShell,out int id)
{
字符串objectName;
int objectId;
//检索名称和值属性
objectName=“数据库中的名称”;
objectId=42;
//
objectShell.Name=objectName;

Console.WriteLine(objectShell.Id);//这样可以很好地保持SoC模型,不会增加太多的复杂性,它可以防止写入只读字段,并且您可以使用非常类似的模型进行序列化。您的只读字段仍然可以由DAL写入,如果以类似的方式使用,您的序列化程序也可以这样做-这意味着必须采取有意识的措施由开发人员写入只读字段,以防止意外误用

模型项目

数据项目

命名空间数据
{
类DALDataObject:DataObject
{
公共数据对象(int-id,字符串名)
{
this.id=id;
this.name=名称;
}
}
公共类连接器
{
公共静态数据对象LoadDataObject(int objectId)
{
返回新的DALDataObject(objectId,string.Format(“伪对象{0}”,objectId));
}
公共静态IEnumerable LoadDataObjects(int startRange、int endRange)
{
var list=新列表();
对于(变量i=startRange;i
在我看来,处理这一问题的最佳方法是让业务对象和DAL在同一个程序集中按名称空间分隔。这在逻辑上分隔了关注点,并允许您使用内部setter。我想不出将它们分隔为自己的程序集有什么好处,因为一个没有另一个就没有用处了。

有ason,如果你想做出正确的决定
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
    }
}
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;
        }
    }
}