洋葱架构-接口中的DTO

时间:2020-07-19 00:02:47

标签: asp.net-identity domain-driven-design onion-architecture

我是Onion Architecture的新手,正在尝试将其应用到ASP.NET项目中。我目前正在实现ASP.NET Identity,并希望使用其UserManager类来存储用户。

根据我对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);
    }
}

问题

我的问题是,我也想从UserManager.CreateAsync(...)返回可能的错误,而不是返回void的返回类型。看起来像这样:

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接口的一部分,但是我不确定这是否是正确的方法。从我发现的开源项目中,我看不到它们在域层中使用DTO,而且人们似乎在说DTO通常是应用程序方面的问题,但我可能会对此深思熟虑。也许我已经对目前的方式采取了错误的方法?

1 个答案:

答案 0 :(得分:1)

从软件体系结构的角度来看,接口不仅是实际的interface定义(即您的IUserManager),而且还是两个组件之间契约的一部分,例如功能,输入和输出DTO,以及实现可能引发的异常和调用者必须能够捕获的异常。

在.NET中,您需要在同一项目中定义所有这些内容,以便在必要时可以将其作为软件包分发。在洋葱架构中,从技术上讲,它们是核心的一部分,但这并不意味着整个核心需要在单个项目中定义。如果您将核心实现与合同分开,则可以分发合同,而无需同时分发实施。

相关问题