c# - Clean Architecture 中的用户实体

标签 c# .net asp.net-identity domain-driven-design clean-architecture

我正在使用 Jason Taylor Clean Architecture template创建一个新的 Web 应用程序。我的应用程序必须支持 post 和 user 实体,并且这些实体是相互关联的。一个用户可以创建多个帖子。
现在我想实现这个用户实体,以便使用我的应用程序的人可以使用这些用户登录。通常我只会使用 ASP.NET Core Identity,但由于我需要在域项目中引用该引用,并且该项目应该独立于任何框架,所以我不能这样做。
在这种情况下我该怎么办?

最佳答案

如果您 引用用户实体 在某些域实体中通过使用唯一标识符(例如 GUID、用户名、电子邮件等),为什么您的域模型中会有框架依赖项?
只是不要使用框架层中的某些身份类作为类成员(字段),而是使用原始类型(例如字符串),或者甚至更好,一些自定义 value object 而不是代表我提到的用户身份唯一标识符的类。例如,您可以将其称为 UserId。
这样,您已经将身份框架(可以被视为基础设施层的一部分)与域层完全分离。
例如,如果您有一个 Order 域模型实体,它需要知道 Customer(或买家),则您不使用身份层中的 ApplicationUser 类,而只使用与框架无关的用户 ID 类型 UserId。
您可以查看 Microsoft eshopOnWeb 例如,如何做到这一点。
此示例显示 Order domain entity :

public class Order : BaseEntity, IAggregateRoot
{
    private Order()
    {
        // required by EF
    }

    public Order(string buyerId, Address shipToAddress, List<OrderItem> items)
    {
        Guard.Against.NullOrEmpty(buyerId, nameof(buyerId));
        Guard.Against.Null(shipToAddress, nameof(shipToAddress));
        Guard.Against.Null(items, nameof(items));

        BuyerId = buyerId;
        ShipToAddress = shipToAddress;
        _orderItems = items;
    }

    public string BuyerId { get; private set; }
    public DateTimeOffset OrderDate { get; private set; } = DateTimeOffset.Now;
    public Address ShipToAddress { get; private set; }

    // DDD Patterns comment
    // Using a private collection field, better for DDD Aggregate's encapsulation
    // so OrderItems cannot be added from "outside the AggregateRoot" directly to the collection,
    // but only through the method Order.AddOrderItem() which includes behavior.
    private readonly List<OrderItem> _orderItems = new List<OrderItem>();

    // Using List<>.AsReadOnly() 
    // This will create a read only wrapper around the private list so is protected against "external updates".
    // It's much cheaper than .ToList() because it will not have to copy all items in a new collection. (Just one heap alloc for the wrapper instance)
    //https://msdn.microsoft.com/en-us/library/e78dcd75(v=vs.110).aspx 
    public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();

    public decimal Total()
    {
        var total = 0m;
        foreach (var item in _orderItems)
        {
            total += item.UnitPrice * item.Units;
        }
        return total;
    }
}
在这里你可以看到,对用户的引用只是由一个字符串引用,这里是 买家 ID 属性 ,它不会将任何身份框架依赖项引入域层。如果在应用程序中的某个点需要用户身份对象,则可以从订单实体中查询此买家 ID,然后可以从域层之外的基础设施中请求用户身份对象。
在 Order 实体中应用的相同模式也可以应用于您的 发帖实体 ,例如通过具有引用用户的 AuthorId 属性之类的东西,它可以是域层中定义的某个字符串或自定义类(值对象)。

关于c# - Clean Architecture 中的用户实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63956730/

相关文章:

.net - 百分比编码的斜线 ("/") 在请求调度之前被解码

.net - 是否应该将 "Using"用于异步对象?

c# - WPF:自动截断 TextBlock 中的文本

asp.net-core - ASP.NET Core修改密码后登录失败

使用 LDAP 的 Asp.Net Identity 个人用户帐户

c# - SqlDependency OnChange 事件为数据库中的每个事件触发多次

c# - WPF 使用 .Net 3.1 - Process.Start Excel 文件错误 : "The specified executable is not a valid application for this OS platform."

c# - 我如何在 .Net 中操作 token 权限?

c# - 如何检测 Control.Click 事件是由鼠标、键盘还是其他原因引起的?

encryption - Bearer token (OAuth2) 是如何创建的?