can you act as a C# expert and explain the following class, a specialist in C# Clean Architecture and explain the Following customer entity that uses Domain Driven Design, please review all methods and analyze them and notice how they follow a very good model, this entity is not an anemic model, please explain as much as possible all the good parts, also notice the NuGet libraries that the class uses :
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Ardalis.GuardClauses;
using uInvoice.Core.Events;
using uInvoiceDDD.SharedKernel;
using uInvoiceDDD.SharedKernel.Interfaces;

namespace uInvoice.Core.Entities
{

 public class Customer : BaseEntityEv, IAggregateRoot
 {
 [Key]
 public Guid CustomerId { get; private set; }

 public string CustomerCode { get; private set; }

 public string CustomerDocument { get; private set; }

 public string Nrc { get; private set; }

 public string FullName { get; private set; }

 public string? CommercialName { get; private set; }

 public bool IsActive { get; private set; }

 public string? SpecificationJson { get; private set; }

 public void SetCustomerCode(string customerCode)
 {
 CustomerCode = Guard.Against.NullOrEmpty(customerCode, nameof(customerCode));
 }

 public void UpdateBranchOfficeForCustomer(Guid newBranchOfficeId)
 {
 Guard.Against.NullOrEmpty(newBranchOfficeId, nameof(newBranchOfficeId));
 if (newBranchOfficeId == BranchOfficeId)
 {
 return;
 }

 BranchOfficeId = newBranchOfficeId;
 }
 public void UpdateCustomerDocumentTypeForCustomer(Guid newCustomerDocumentTypeId)
 {
 Guard.Against.NullOrEmpty(newCustomerDocumentTypeId, nameof(newCustomerDocumentTypeId));
 if (newCustomerDocumentTypeId == CustomerDocumentTypeId)
 {
 return;
 }

 CustomerDocumentTypeId = newCustomerDocumentTypeId;
 }

 public void SetCustomerDocument(string customerDocument)
 {
 CustomerDocument = Guard.Against.NullOrEmpty(customerDocument, nameof(customerDocument));
 }
 

 public void SetSpecificationJson(string specificationJson)
 {
 SpecificationJson = specificationJson;
 }
 

 public Guid BranchOfficeId { get; private set; }

 

 public Guid CustomerDocumentTypeId { get; private set; }

 

 public Guid EconomicActivityId { get; private set; }

 

 public Guid PaymentMethodId { get; private set; }

 

 public Guid PersonTypeId { get; private set; }

 private readonly List \_customerAddresses = new();

 public IEnumerable CustomerAddresses => \_customerAddresses.AsReadOnly();
 private readonly List \_customerEmailAddresses = new();

 public IEnumerable CustomerEmailAddresses => \_customerEmailAddresses.AsReadOnly();
 private readonly List \_customerPhoneNumbers = new();

 public IEnumerable CustomerPhoneNumbers => \_customerPhoneNumbers.AsReadOnly();
 private readonly List \_customerPriceLists = new();

 public IEnumerable CustomerPriceLists => \_customerPriceLists.AsReadOnly();
 private readonly List \_invoices = new();

 public IEnumerable Invoices => \_invoices.AsReadOnly();
 public void AddNewCustomerAddress(Guid customerId, Guid addressId, Guid addressTypeId)
 {
 
 Guard.Against.NullOrEmpty(customerId, nameof(customerId));
 Guard.Against.NullOrEmpty(addressId, nameof(addressId));
 Guard.Against.NullOrEmpty(addressTypeId, nameof(addressTypeId));
 
 var newCustomerAddress = new CustomerAddress( customerId, addressId, addressTypeId);
 Guard.Against.DuplicateCustomerAddress(\_customerAddresses, newCustomerAddress, nameof(newCustomerAddress));
 \_customerAddresses.Add(newCustomerAddress);
 }

 public void DeleteCustomerAddress(Guid customerId, Guid addressId)
 {
 Guard.Against.NullOrEmpty(customerId, nameof(customerId));
 Guard.Against.NullOrEmpty(addressId, nameof(addressId));
 
 var customerAddressToDelete = \_customerAddresses
 .Where(ca1 => ca1.CustomerId == customerId)
 .Where(ca2 => ca2.AddressId == addressId)
 .FirstOrDefault();
 
 if (customerAddressToDelete != null)
 {
 \_customerAddresses.Remove(customerAddressToDelete);
 }
 }

 
 public void AddNewInvoice(Invoice invoice)
 {
 Guard.Against.Null(invoice, nameof(invoice));
 Guard.Against.NullOrEmpty(invoice.InvoiceId, nameof(invoice.InvoiceId));
 Guard.Against.DuplicateInvoice(\_invoices, invoice, nameof(invoice));
 \_invoices.Add(invoice);
 }

 public void DeleteInvoice(Invoice invoice)
 {
 Guard.Against.Null(invoice, nameof(invoice));
 var invoiceToDelete = \_invoices
 .Where(i => i.InvoiceId == invoice.InvoiceId)
 .FirstOrDefault();
 if (invoiceToDelete != null)
 {
 \_invoices.Remove(invoiceToDelete);
 }
 }

 private Customer() {} // EF required

 [SetsRequiredMembers]
 public Customer(Guid customerId, Guid branchOfficeId, Guid customerDocumentTypeId, Guid economicActivityId, Guid paymentMethodId, Guid personTypeId, string customerCode, string customerDocument, string nrc, string fullName, string? commercialName, bool isActive, string? specificationJson)
 {
 
 CustomerId = Guard.Against.NullOrEmpty(customerId, nameof(customerId));
 BranchOfficeId = Guard.Against.NullOrEmpty(branchOfficeId, nameof(branchOfficeId));
 CustomerDocumentTypeId = Guard.Against.NullOrEmpty(customerDocumentTypeId, nameof(customerDocumentTypeId));
 EconomicActivityId = Guard.Against.NullOrEmpty(economicActivityId, nameof(economicActivityId));
 PaymentMethodId = Guard.Against.NullOrEmpty(paymentMethodId, nameof(paymentMethodId));
 PersonTypeId = Guard.Against.NullOrEmpty(personTypeId, nameof(personTypeId));
 CustomerCode = Guard.Against.NullOrWhiteSpace(customerCode, nameof(customerCode));
 CustomerDocument = Guard.Against.NullOrWhiteSpace(customerDocument, nameof(customerDocument));
 Nrc = Guard.Against.NullOrWhiteSpace(nrc, nameof(nrc));
 FullName = Guard.Against.NullOrWhiteSpace(fullName, nameof(fullName));
 CommercialName = commercialName;
 IsActive = Guard.Against.Null(isActive, nameof(isActive));
 SpecificationJson = specificationJson;

 }

 }
}
C# 전문가로 활동하며 다음 클래스를 설명하고 C# 클린 아키텍처 전문가이며 도메인 중심 디자인을 사용하는 다음 고객 엔터티를 설명하십시오. 모든 메소드를 검토하고 분석하고 매우 좋은 모델을 따르는 방법에 주목하십시오.이 엔터티는 빈혈 모델이 아니며 가능한 한 모든 좋은 부분을 설명하십시오, 또한 클래스가 사용하는 NuGet 라이브러리도 확인하십시오 :using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Diagnostics.CodeAnalysis;using System.Linq;using Ardalis.GuardClauses;using uInvoice.Core.Events;using uInvoiceDDD.SharedKernel;사용 uInvoiceDDD.SharedKernel.Interfaces;네임스페이스 uInvoice.Core.엔티티{ public class Customer : BaseEntityEv, IAggregateRoot { [Key] public Guid CustomerId { get; private set; } public string CustomerCode { get; private set; } public string CustomerDocument { get; private set; } public string Nrc { get; private set; } public string FullName { get; private set; } 공개 문자열? CommercialName { get; private set; } public bool IsActive { get; private set; } public string? SpecificationJson { get; private set; } public void SetCustomerCode(문자열 customerCode) { CustomerCode = Guard.Against.NullOrEmpty(customerCode, nameof(customerCode)); } public void UpdateBranchOfficeForCustomer(Guid newBranchOfficeId) { Guard.Against.NullOrEmpty(newBranchOfficeId, nameof(newBranchOfficeId)); if (newBranchOfficeId == BranchOfficeId) { return; } BranchOfficeId = newBranchOfficeId; } public void UpdateCustomerDocumentTypeForCustomer(Guid newCustomerDocumentTypeId) { Guard.Against.NullOrEmpty(newCustomerDocumentTypeId, nameof(newCustomerDocumentTypeId)); if (newCustomerDocumentTypeId == CustomerDocumentTypeId) { return; } CustomerDocumentTypeId = 새로운 고객 문서 유형 ID; } public void SetCustomerDocument(문자열 customerDocument) { CustomerDocument = Guard.Against.NullOrEmpty(customerDocument, nameof(customerDocument)); }  public void SetSpecificationJson(문자열 specificationJson) { SpecificationJson = specificationJson; }  public Guid BranchOfficeId { get; private set; }  public Guid CustomerDocumentTypeId { get; private set; }  public Guid EconomicActivityId { get; private set; }  public Guid PaymentMethodId { get; private set; }  public Guid PersonTypeId { get; private set; } 비공개 읽기 전용 List \_customerAddresses = new(); public IEnumerable CustomerAddresses => \_customerAddresses.AsReadOnly(); 비공개 읽기 전용 List \_customerEmailAddresses = new(); public IEnumerable CustomerEmailAddresses => \_customerEmailAddresses.AsReadOnly(); 비공개 읽기 전용 목록 \_customerPhoneNumbers = new(); public IEnumerable CustomerPhoneNumbers => \_customerPhoneNumbers.AsReadOnly(); 비공개 읽기 전용 List \_customerPriceLists = new(); public IEnumerable CustomerPriceLists => \_customerPriceLists.AsReadOnly(); 비공개 읽기 전용 목록 \_인보이스 = new(); public IEnumerable Invoices => \_invoices.AsReadOnly(); public void AddNewCustomerAddress(Guid customerId, Guid addressId, Guid addressTypeId) {  Guard.Against.NullOrEmpty(customerId, nameof(customerId)); Guard.Against.NullOrEmpty(addressId, nameof(addressId)); Guard.Against.NullOrEmpty(addressTypeId, nameof(addressTypeId));  var newCustomerAddress = new CustomerAddress( customerId, addressId, addressTypeId); Guard.Against.DuplicateCustomerAddress(\_customerAddresses, newCustomerAddress, nameof(newCustomerAddress)); \고객 주소 추가(새로운 고객 주소); } public void DeleteCustomerAddress(Guid customerId, Guid addressId) { Guard.Against.NullOrEmpty(customerId, nameof(customerId)); Guard.Against.NullOrEmpty(addressId, nameof(addressId));  var customerAddressToDelete = \_customerAddresses .Where(ca1 => ca1.CustomerId == customerId) .Where(ca2 => ca2.AddressId == addressId) .FirstOrDefault();  if (customerAddressToDelete != null) { \_customerAddresses.Remove(customerAddressToDelete); } }  public void AddNewInvoice(송장 인보이스) { Guard.Against.Null(invoice, nameof(invoice)); Guard.Against.NullOrEmpty(invoice.InvoiceId, nameof(invoice.InvoiceId)); Guard.Against.DuplicateInvoice(\_인보이스, 인보이스, nameof(인보이스)); \_invoices.Add(invoice); } public void DeleteInvoice(송장 인보이스) { Guard.Against.Null(invoice, nameof(invoice)); var invoiceToDelete = \_invoices .Where(i => i.InvoiceId == invoice.InvoiceId) .FirstOrDefault(); if (invoiceToDelete != null) { \_invoices.Remove(invoiceToDelete); } } private Customer() {} // EF 필수 [SetsRequiredMembers] public Customer(Guid customerId, Guid branchOfficeId, Guid customerDocumentTypeId, Guid economicActivityId, Guid paymentMethodId, Guid personTypeId, 문자열 customerCode, 문자열 customerDocument, 문자열 nrc, 문자열 fullName, 문자열? commercialName, bool isActive, 문자열? specificationJson) {  CustomerId = Guard.Against.NullOrEmpty(customerId, nameof(cust