我可以在 RavenDB 中使用构造函数重载吗?

Posted

技术标签:

【中文标题】我可以在 RavenDB 中使用构造函数重载吗?【英文标题】:Can I use constructor overload with RavenDB? 【发布时间】:2019-11-01 13:30:36 【问题描述】:

我一直在尝试编写一个聪明的解决方案来解决我的问题,但我失败了。我需要在我的域中以我的身份进行构造函数重载,首先是一个对象实例,另一个是 RavenDB 填充。这没什么大不了的,对吧?但是 RavenDB 不能使用多个构造函数,消息如何显示:

Message = "无法找到用于类型的构造函数 项目.域.业务.用户.用户。一个类应该有一个 默认构造函数,一个带参数的构造函数或一个构造函数 用 JsonConstructor 属性标记。路径“登录”。”

这个想法是在我的身份中保留一些域规则,当有人创建对象实例时这是必要的。我们如何在以下示例中看到:

我的身份用户:

namespace Project.Domain.Business.Users

    public class User
    
        public string Id  get; private set; 
        public string Login  get; private set; 
        public string Password  get; private set; 
        public string Role  get; private set; 
        public string Token  get; private set; 
        public string RecoveryToken  get; private set; 
        public string GoogleClientId  get; private set; 
        public string GoogleClientSecret  get; private set; 
        public string FacebookAppId  get; private set; 
        public string FacebookAppSecret  get; private set; 
        public Person Person  get; private set; 

        public User(string login, string password, string googleClientId, string googleClientSecret, string facebookAppId, string facebookAppSecret, Person person)
        
            Id = Guid.NewGuid().ToString();
            Login = login;
            Password = SecurityHolder.EncryptPassword(password);
            Role = "Common";
            Token = SecurityHolder.GetHash_HMACSHA256(login + "_" + password);
            RecoveryToken = SecurityHolder.GetHash_HMACSHA256(login);
            GoogleClientId = googleClientId;
            GoogleClientSecret = googleClientSecret;
            FacebookAppId = facebookAppId;
            FacebookAppSecret = facebookAppSecret;
            Person = person;
        

    

在我的服务中创建的对象(或其他任何东西,例如可以在控制器中):

var emailObject = new Email(email);
            var cellPhoneNumberObject = new Phone(cellPhoneNumber);

            var naturalPerson = new NaturalPerson(name, gender, birth, emailObject, cellPhoneNumberObject, description);
            var user = new User(login, password, googleClientId, googleClientSecret, facebookAppId, facebookAppSecret, naturalPerson);

            var userResults = _userValidation.IsValid(user);

            if (userResults.IsValid)
            
                _userRepository.Create(user);
            
            else
            
                throw new Exception(userResults.ToString("~"));
            

我正在考虑使用创建设计模式来创建我的对象的实例,也许是工厂,并将身份属性设置为公共的。因此,RavenDB 也应该可以正常工作。但是,我不知道这是否正确。

编辑:

正如加雷问我的那样。 create 方法在 UserRepository 中实现:

public class UserRepository : IUserRepository

    private readonly IUnitOfWork _unitOfWork;

    public UserRepository(IUnitOfWork unitOfWork)
    
        _unitOfWork = unitOfWork;
    

    public User GetById(string id)
    
        var session = _unitOfWork.OpenSession();
        return session.Load<User>(id);
    

    public void Create(User user)
    
        var session = _unitOfWork.OpenSession();
        session.Store(user);
        session.SaveChanges();
    

    public void Edit(User user)
    
        var session = _unitOfWork.OpenSession();
        session.SaveChanges();
    

工作单元模式用于将 raven 状态会话保持在范围内。让用户在我的服务中进行选择和更新非常重要。

unitOfWork 代码:

public class UnitOfWork : IUnitOfWork

    private readonly IDocumentStore _documentStore;
    private IDocumentSession _documentSession;

    public UnitOfWork(IDocumentStoreHolder documentStoreHolder)
    
        _documentStore = documentStoreHolder.DocumentStore;
        _documentSession = null;
    

    public IDocumentSession OpenSession()
    
        return _documentSession ?? (_documentSession = _documentStore.OpenSession());
    

【问题讨论】:

您所说的异常不是来自 RavenDB ,我也没有看到任何 RavenDB 客户端代码。 RavenDB 接收初始化的实体,它不关心使用什么 ctor 来创建它。 Create() 方法中有什么? 对,我将编辑并展示 create() 方法。 【参考方案1】:

经过一番研究,我找到了解决方案。可以在 RavenDB 的构造函数中使用标签 [Json Constructor] 来序列化它。

例子:

    [JsonConstructor]
    public User(string id, string login, string password, string role, string token, string recoveryToken, string googleClientId, string googleClientSecret, string facebookAppId, string facebookAppSecret, Person person)
    
        Id = id;
        Login = login;
        Password = password;
        Role = role;
        Token = token;
        RecoveryToken = recoveryToken;
        GoogleClientId = googleClientId;
        GoogleClientSecret = googleClientSecret;
        FacebookAppId = facebookAppId;
        FacebookAppSecret = facebookAppSecret;
        Person = person;
    

所以,它允许使用构造函数重载。

在RavenDb 文档中了解更多信息。

【讨论】:

以上是关于我可以在 RavenDB 中使用构造函数重载吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 PHP 中重载构造函数?

为啥 TypeScript 中没有重载的构造函数实现?

拷贝构造函数——重载赋值运算符

我们可以重载malloc()吗?

我可以使用构造函数动态创建用户控件吗?

STL详解—— list的模拟实现