.NET如何解决层间所需的泛型

vxqlmq5t  于 2023-11-20  发布在  .NET
关注(0)|答案(2)|浏览(263)

我有一个问题,可能是相当琐碎的一些。我正在做一个应用程序在.NET中,我试图有分裂层。应用(仅限抽象)和基础结构(执行)。我的问题是,我想使用Azure TableClient存储来自Azure存储表的数据。但要存储的方法需要在该实体上实现ITableEntity接口。我只是不能在应用程序层的存储方法,因为我会使一个依赖Azure.数据.表,我不想这样。我真的不知道如何写我的接口与此,然后“覆盖”它,我猜。
适用范围:

  1. public interface ITableStorage
  2. {
  3. public Task SaveItemsAsync<T>(IEnumerable<T> entites, string tableName = nameof(T)) where T : ITableEntity; // where T : ITableEntity is problem
  4. }

字符串
基础设施:

  1. public async Task SaveItemsAsync<T>(IEnumerable<T> entites, string tableName = nameof(T)) where T : ITableEntity
  2. {
  3. var tableClient = _tableServiceClient.GetTableClient(tableName);
  4. ......
  5. }


提前感谢您的建议。

roejwanj

roejwanj1#

解决方案是使用“实体”的多种表示。应用程序使用包括方法,逻辑等的规范表示。然后将其转换为适合在Azure中存储的类型,或存储实体的其他类型。
这确实需要相同数据的多个表示,但它确实增加了一些灵活性。如果您更改数据模型,则可以保留旧的Azure表示,以便您可以读取旧数据,同时在保存时使用新的实体类型。这类似于Data Transfer Object的概念。
要在类型之间进行转换,有几个选项:
1.在类型上使用开关
1.使用visitor pattern。这有一个好处,你可以 * 强制 * 为每一个应用程序类型创建一个azure类型。所以忘记的机会更少。
您可能希望为应用程序端的实体提供一些公共接口,这样编译器就可以帮助确保您只保存那些设计为要保存的对象。
一个非常简单的例子来说明这个想法:

  1. public interface IMyEntity{}
  2. public class MyEntity {};
  3. public interface IEntityStorage{
  4. void Save(IMyEntity entity);
  5. }
  6. public class MyEntityAzure : ITableEntity {
  7. public MyEntityAzure(MyEntity entity){
  8. // copy properties etc.
  9. }
  10. public MyEntity ToModel(){
  11. // Convert back to application entity
  12. }
  13. }
  14. public class AzureStorage : IEntityStorage{
  15. private AzureStorage storage;
  16. public void Save(IMyEntity entity){
  17. switch(entity){
  18. case MyEntity myEntity:
  19. storage.Save(new MyEntityAzure(myEntity));
  20. break;
  21. // All other entity classes
  22. }
  23. }
  24. }

字符串

展开查看全部
myzjeezk

myzjeezk2#

让你的界面完全基于你想让它实现什么,而不考虑实现。

  1. public interface ICustomerService
  2. {
  3. public Task AddNewCustomerAsync<T>(Customer customer);
  4. }

字符串
一旦你完成了这一点,添加实现。

  1. public class TableStorageCustomerService : ICustomerService
  2. {
  3. public async<Task> AddNewCustomerAsync<T>(Customer customer)
  4. {
  5. //map your customer class to your table entity
  6. //save the table entity to your table storage
  7. }
  8. }


正如你所看到的,在你的接口中根本没有实现细节,因为你只使用Customer,所以你可以自由地将它Map到你的服务实现中的数据库所需要的任何类。

展开查看全部

相关问题