If you reference a user entity in some domain entity by using a unique identifier (e.g. a GUID, username, email, etc.) why would you then have a framework dependency in your domain model?
Just don't use some identity class from the framework layer as a class member (field) but use a primitive type (e.g. a string), or even better, some custom value object class instead that represents that user identity unique identifier I mentioned. You could, for instance, call it UserId.
With that you have completely decoupled the identity framework (which can be considered as part of the infrastructure layer) from your domain layer.
For instance, if you have an Order domain model entity which needs to know the Customer (or buyer) you do not use the ApplicationUser class from the identity layer but rather use just the framework independent user id type UserId.
You can look into the Microsoft eshopOnWeb for some example how this can be done.
This example shows the 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;
}
}
Here you can see, that the reference to the user is simply referenced by a string, here the BuyerId property, which does not introduce any identity framework dependencies into the domain layer. If the user identity object is required at some point in the application this buyer id can be queried from the order entity and than the user identity object can be requested from the infrastructure outside the domain layer.
The same pattern applied in the Order entity can also be applied to your Post entity, e.g. by having something like an AuthorId property referencing the user which can either be some string or custom class (value object) defined in the domain layer.