分配对象时如何防止模型 属性 延迟加载?

How to prevent lazyloading of model property when assigning object?

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

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

型号class:

    public class ProductStructure
    {
        public override Guid Id { get; set; }

        private List<AbstractStructureNode> subNodes;

        public override List<AbstractStructureNode> SubNodes
        {
            get
            {
                // Lazy loading logic including API calls to set subNodes
                return subNodes;
            }
            set
            {
                subNodes = value;
            }
        }
     }

API :

public async Task<ProductStructure> GetLightProductStructure(Guid Id)
        {
            if (Id == Guid.Empty)
                return null;

            string uri = ServiceUri + $"ProductStructures/Light/{Id}";
            using (var client = new HttpClient())
            {
                HttpResponseMessage response = client.GetAsync(uri).Result;

                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }
                else
                {
                    string content = await response.Content.ReadAsStringAsync();
                    try
                    {
                        JsonSerializerSettings settings = new JsonSerializerSettings()
                        {
                            Formatting = Formatting.None,
                            TypeNameHandling = TypeNameHandling.Auto,
                            SerializationBinder = new CustomJsonSerializer("R3.ProductStructureSDK.DataModel", "R3.ProductStructureSDK")
                        };

                        return JsonConvert.DeserializeObject<ProductStructure>(content, settings);
                    }

                    catch (Exception e)
                    {
                        return null;
                    }
                }
            }
        }

触发延迟加载的赋值(单元测试的一部分)

ProductStructure LightProduct = await ProductStructureManager.Instance.GetLightProductStructure(RootId);

从服务器下载 ProductStructure 时,其子节点为空。但是将 API 返回的 ProductStructure 分配给变量 'LightProduct' 的简单事实将触发子节点的 getter。 API 使用异步方法,所以我不能使用 ref.

是否有延迟加载对象属性的通用方法?

只要您使用

反序列化您的数据

return JsonConvert.DeserializeObject<ProductStructure>(content, settings);

然后数百个子节点被创建并加载到内存中。您不能为您的场景延迟加载 ProductStructure 中的任何内容。 你应该做的是创建一个 "LightProductStructure" class

public class LightProductStructure
{
    public override Guid Id { get; set; }
}

如果您需要 没有 子节点的对象,请使用 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 对象中。这样你就不会在没有需要的情况下加载数百个对象,你在内存中只有一个字符串。 然后,当您需要这些对象时,在您的 ProductStructure 对象上调用一个方法来反序列化该字符串,并将结果分配给您的子节点 属性。我认为这是您在那种情况下所谈论的延迟加载方法中最接近的方法。

没有。这是一个反模式。

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

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

-> Product
-> ProductDetails 

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