C# 如何防止在指定对象时懒散地加载模型属性?

C# 如何防止在指定对象时懒散地加载模型属性?,c#,lazy-loading,variable-assignment,getter,C#,Lazy Loading,Variable Assignment,Getter,我试图在客户端的模型上实现一些延迟加载逻辑 我试图将逻辑放在这些属性的getter中,但现在我意识到,当对象被创建并分配给变量时,它会触发属性的所有getter,从而触发延迟加载逻辑 模型类: 公共类产品结构 { 公共重写Guid Id{get;set;} 私有列表子节点; 公共覆盖列表子节点 { 得到 { //延迟加载逻辑,包括设置子节点的API调用 返回子节点; } 设置 { 子节点=值; } } } API: 公共异步任务GetLightProductStructure(Guid Id)

我试图在客户端的模型上实现一些延迟加载逻辑

我试图将逻辑放在这些属性的getter中,但现在我意识到,当对象被创建并分配给变量时,它会触发属性的所有getter,从而触发延迟加载逻辑

模型类:

公共类产品结构
{
公共重写Guid Id{get;set;}
私有列表子节点;
公共覆盖列表子节点
{
得到
{
//延迟加载逻辑,包括设置子节点的API调用
返回子节点;
}
设置
{
子节点=值;
}
}
}
API:

公共异步任务GetLightProductStructure(Guid Id) { if(Id==Guid.Empty) 返回null; 字符串uri=ServiceUri+$“ProductStructures/Light/{Id}”; 使用(var client=new HttpClient()) { HttpResponseMessageResponse=client.GetAsync(uri).Result; 如果(!response.issucessStatusCode) { 返回null; } 其他的 { string content=wait response.content.ReadAsStringAsync(); 尝试 { JsonSerializerSettings设置=新建JsonSerializerSettings() { 格式化=格式化。无, TypeNameHandling=TypeNameHandling.Auto, SerializationBinder=new CustomJsonSerializer(“R3.ProductStructureSDK.DataModel”、“R3.ProductStructureSDK”) }; 返回JsonConvert.DeserializeObject(内容、设置); } 捕获(例外e) { 返回null; } } } } 触发懒散加载的赋值(单元测试的一部分)

ProductStructure-LightProduct=await-ProductStructureManager.Instance.GetLightProductStructure(RootId);
从服务器下载ProductStructure时,其子节点为空。但将API返回的ProductStructure分配给变量“LightProduct”的简单事实将触发子节点的getter。API使用异步方法,因此我不能使用ref


有没有一种常见的方法可以延迟加载对象的属性?

只要使用

返回JsonConvert.DeserializeObject(内容、设置)

然后创建数百个子节点并将其加载到内存中。您不能在ProductStructure中为您的场景延迟加载任何内容。 您应该做的是创建一个“LightProductStructure”类

如果需要不包含子节点的对象,请使用LightProductStructure对象反序列化服务器的响应。如果需要使用子节点,则使用ProductStructureObject反序列化服务器的响应

为了使代码更干净,还应该像这样重构ProductStructure对象

public class ProductStructure : LightProductStructure
{
    private List<AbstractStructureNode> subNodes;

    public override List<AbstractStructureNode> SubNodes
    {
        get
        {
            // Lazy loading logic including API calls to set subNodes
            return subNodes;
        }
        set
        {
            subNodes = value;
        }
    }
 }
公共类ProductStructure:LightProductStructure
{
私有列表子节点;
公共覆盖列表子节点
{
得到
{
//延迟加载逻辑,包括设置子节点的API调用
返回子节点;
}
设置
{
子节点=值;
}
}
}
编辑: 另一种不用继承的方法是——在某些情况下——将子节点作为字符串存储在ProductStructure对象中。这样,您就不必无需加载数百个对象,只需在内存中加载一个字符串。
然后,当需要这些对象时,调用ProductStructure对象上的方法,该方法将反序列化该字符串,并将结果分配给Subnodes属性。我认为这是与您在该场景中所说的延迟加载方法最接近的方法。

不。这是一种反模式

您正在ProductStructure类中隐藏IO/Api调用。消费者不知道这些电话的费用

除非您有令人信服的理由使用facade模式(这是您在这里实现的),否则我会将其分解为两个单独的调用

-> Product
-> ProductDetails 

这将使您的代码更干净,并且使维护您的代码的开发人员更容易理解

我不明白你想要达到的目标。对您来说,“延迟加载”模型属性值的意义是什么?子节点属性可以包含数百个对象。当应用程序需要检索ProductStructure时,它不立即需要其子节点属性。我简化了模型的代码,实际上它还包含一个描述字符串和其他属性,这是我们首先需要的。我明白你的意思,但因为我不希望每次请求ProductStructure时服务器都包含子节点,所以API中有几个路由。其中一个(ProductStructures/Light/{Id})已经返回了一个没有子节点的Light产品。反序列化部分工作正常,GetLightProductStructure返回的对象不包含我认为合适的任何子节点。在这种情况下,调用“light”API的方法应该返回一个“light”对象。每当您需要访问“full”对象时,再次调用“full”API以检索“full”对象。不要让这种逻辑停留在你的模型中。在应用程序的业务/逻辑层中处理这些问题。一个模型应该是一个“愚蠢”的数据容器,具有非常简单的逻辑,在独立的情况下听起来更好,我会考虑一下itOk,所以如果我做得好,应用程序将不得不自己调用细节。我最初是
-> Product
-> ProductDetails