首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MAUI+ASP.NET DTO

MAUI+ASP.NET DTO
EN

Stack Overflow用户
提问于 2022-11-19 15:20:43
回答 1查看 52关注 0票数 0

我有一个由两部分组成的项目:

  • ASP.NET API使用Entity Framework
  • .NET MAUI客户端应用程序

我使用DTOs与API进行通信,以避免公开实体的其他属性。由于这种方法,我能够将从API中发送的实体数据和数据分离开来。

起初,我也在DTOs UI中使用了这些MAUI。但是过了一段时间,我开始注意到它们包含了与UI相关的属性、属性或方法,这些属性或方法与API本身无关,因此它们在请求中是多余的。

示例:

1- API将收到MAUI的请求,以便根据它的名称进行练习

2- ExerciseService返回:ExerciseEntityExerciseController使用AutoMapper映射ExerciseEntity -> ExerciseDto ommiting ExerciseId字段(只有管理员可以在DB中看到此信息),并在API响应中返回该信息。

3- MAUI从API ExerciseDto接收。但是在客户端,它还想知道来自ExerciseDto的数据是否在UI中折叠。因此,我将IsCollapsed属性添加到ExerciseDto中。但是现在这是API的一个冗余属性,因为我不想将这些信息保存在数据库中。

问题:

我是否应该将这些DTOs映射到客户端的新对象?

或者如何处理这个问题?

是否有更容易的方法来实现分离?

因为拥有另一个映射层将增加DTOs和那些新客户端对象之间的额外复杂性和许多重复属性。

EN

回答 1

Stack Overflow用户

发布于 2022-11-19 16:04:09

通常,如果您使用干净的体系结构方法,那么DTO应该不包含仅与某些项目相关的属性和其他特定数据,以便其他项目能够以依赖的形式自由使用。

然后在xamarin/maui应用程序中使用不同的DTO方法,例如:

方法1.将(当然)映射到适合UI的类中。这里有一些选项,使用手动映射,编写使用反射的自己的代码,或者使用相同的反射使用第三方库。就我个人而言,当谈到第三方libs时,Mapster为api和移动客户端向我展示了非常好的效果。

方法2. DTO子类。其基本思想是将dto反序列化为派生类,然后调用Init();如果需要的话。在反序列化器/映射器弹出之后,您用OnPropertyChanged手动实现的所有属性都将更新绑定,并且您也有一个调用RaiseProperties()的备份计划;对于所有的支持,甚至那些没有OnPropertyChanged的人,如果有的话,他们也可以更新绑定。

例子:我们的Api DTO

代码语言:javascript
复制
 public class SomeDeviceDTO
    {
        public int Id { get; set; }
        public int Port { get; set; } 
        public string Name { get; set; } 
    }

我们的派生类用于移动客户端:

代码语言:javascript
复制
  public class SomeDevice : SomeDeviceDTO, IFromDto
        {
        // we want to be able to change this Name property in run-time and to 
        // reflect changes so we make it bindable (other props will remain without 
        // OnPropertyChanged BUT we can always update all bindings in code if needed 
        // using RaiseProperties();):
        
            private string _name;
            public new string Name
            {
                get { return _name; }
                set
                {
                    if (_name != value)
                    {
                        _name = value;
                        OnPropertyChanged();
                    }
                }
            }  

       // ADD any properties you need for UI
       // ...

       #region IFromDto

            public void Init()
            {
                //put any code you'd want to exec after dto's been imported
                // for example to fill any new prop with data derived from what you received 

            }
    
            public void RaiseProperties()
            {
                var props = this.GetType().GetProperties();
                foreach (var property in props)
                {
                    if (property.CanRead)
                    {
                        OnPropertyChanged(property.Name);
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }

#endregion
        
        }
    
      public interface IFromDto : INotifyPropertyChanged
        {
            //
            // Summary:
            //     Can initialize model after it's being loaded from dto
            void Init();
    
            //
            // Summary:
            //     Notify all properties were updated
            void RaiseProperties();
        }

我们可以像这样:var device = JsonConvert.DeserializeObject<SomeDevice>(jsonOfSomeDeviceDTO);

如果需要的话我们可以打电话给Init();

可以随意编辑这个答案来添加更多的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74501223

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档