洋葱架构 - 接口中的 DTO
Onion Architecture - DTOs in interfaces
我是 Onion Architecture 的新手,正在尝试将其应用到 ASP.NET 项目中。我目前正在实施 ASP.NET Identity 并希望使用其 UserManager
class 来存储用户。
根据我从 Onion Architecture 中了解到的情况,我应该在域层中创建一个接口,该接口可用于包装 UserManager
。
public interface IUserManager
{
public Task CreateAsync(string username, string password);
}
然后在基础架构层中,我将实现自己的 UserManager
来包装 ASP.NET 身份 UserManager
。
using Microsoft.AspNetCore.Identity;
public class MyUserManager : IUserManager
{
private readonly UserManager<IdentityUser> _userManager;
public UserManager(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task CreateAsync(string username, string password)
{
var user = new IdentityUser { UserName = username };
await _userManager.CreateAsync(user, password);
}
}
问题
我的问题是我还想 return 来自 UserManager.CreateAsync(...)
的可能错误,而不是 void
return 类型。看起来像这样:
public class IdentityResult
{
public bool Succeeded { get; set; }
public IEnumerable<string> Errors { get; set; } // Some Error type instead of a string would be better
}
我必须在域层中定义此 DTO,因为它们必须是 IUserManager
接口的一部分,但我不确定这是否是正确的方法。从我发现的开源项目中,我看到 none 他们在域层中使用 DTO,人们似乎在说 DTO 通常是一个应用程序问题,但我可能只是想得太多了。也许我已经用我目前的方式采取了错误的方法?
从软件架构的角度来看,接口不仅是实际的 interface
定义(即您的 IUserManager
),而且是两个组件之间契约的一部分,例如函数的输入和输出 DTO 以及实现可能抛出且调用者必须能够捕获的异常。
在 .NET 中,您可以在同一个项目中定义所有这些,以便在必要时可以将其作为一个包进行分发。在洋葱架构中,技术上这些是核心的一部分,但这并不意味着整个核心需要在单个项目中定义。如果将核心实现与合同分开,则可以在不分发实现的情况下分发合同。
我是 Onion Architecture 的新手,正在尝试将其应用到 ASP.NET 项目中。我目前正在实施 ASP.NET Identity 并希望使用其 UserManager
class 来存储用户。
根据我从 Onion Architecture 中了解到的情况,我应该在域层中创建一个接口,该接口可用于包装 UserManager
。
public interface IUserManager
{
public Task CreateAsync(string username, string password);
}
然后在基础架构层中,我将实现自己的 UserManager
来包装 ASP.NET 身份 UserManager
。
using Microsoft.AspNetCore.Identity;
public class MyUserManager : IUserManager
{
private readonly UserManager<IdentityUser> _userManager;
public UserManager(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task CreateAsync(string username, string password)
{
var user = new IdentityUser { UserName = username };
await _userManager.CreateAsync(user, password);
}
}
问题
我的问题是我还想 return 来自 UserManager.CreateAsync(...)
的可能错误,而不是 void
return 类型。看起来像这样:
public class IdentityResult
{
public bool Succeeded { get; set; }
public IEnumerable<string> Errors { get; set; } // Some Error type instead of a string would be better
}
我必须在域层中定义此 DTO,因为它们必须是 IUserManager
接口的一部分,但我不确定这是否是正确的方法。从我发现的开源项目中,我看到 none 他们在域层中使用 DTO,人们似乎在说 DTO 通常是一个应用程序问题,但我可能只是想得太多了。也许我已经用我目前的方式采取了错误的方法?
从软件架构的角度来看,接口不仅是实际的 interface
定义(即您的 IUserManager
),而且是两个组件之间契约的一部分,例如函数的输入和输出 DTO 以及实现可能抛出且调用者必须能够捕获的异常。
在 .NET 中,您可以在同一个项目中定义所有这些,以便在必要时可以将其作为一个包进行分发。在洋葱架构中,技术上这些是核心的一部分,但这并不意味着整个核心需要在单个项目中定义。如果将核心实现与合同分开,则可以在不分发实现的情况下分发合同。