定义可扩展的Grails3.0插件域类

定义可扩展的Grails3.0插件域类,grails,groovy,grails-plugin,grails-domain-class,grails-3.0,Grails,Groovy,Grails Plugin,Grails Domain Class,Grails 3.0,开发Grails 3.0插件时: 应该如何定义域,以便应用程序可以使用插件对其进行扩展 插件如何引用扩展类的实例 例如,安全插件可以有如下类: User.groovy package com.example.plugins.security class User { String email String hash Boolean enabled = true } package com.example.plugins.security import org.sp

开发Grails 3.0插件时:

  • 应该如何定义域,以便应用程序可以使用插件对其进行扩展
  • 插件如何引用扩展类的实例
  • 例如,安全插件可以有如下类:

    User.groovy

    package com.example.plugins.security
    
    class User {
    
       String  email
       String  hash
       Boolean enabled = true
    
    }
    
    package com.example.plugins.security
    
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
    
    class SecurityService {
    
       def authenticate(String email, String password) {
          def user = User.findByEmail(email)  //instance of BookstoreUser???
          def encoder = new BCryptPasswordEncoder()
          return user && encoder.matches(password, user.hash) ? user : null
          }
    
    }
    
    package org.example.bookstore
    
    import org.bson.types.ObjectId
    import org.example.plugins.security.User
    
    class BookstoreUser extends User {
    
       ObjectId id
       String   firstName
       String   lastName
    
       static mapWith = "mongo"
    
    }
    
    SecurityService.groovy

    package com.example.plugins.security
    
    class User {
    
       String  email
       String  hash
       Boolean enabled = true
    
    }
    
    package com.example.plugins.security
    
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
    
    class SecurityService {
    
       def authenticate(String email, String password) {
          def user = User.findByEmail(email)  //instance of BookstoreUser???
          def encoder = new BCryptPasswordEncoder()
          return user && encoder.matches(password, user.hash) ? user : null
          }
    
    }
    
    package org.example.bookstore
    
    import org.bson.types.ObjectId
    import org.example.plugins.security.User
    
    class BookstoreUser extends User {
    
       ObjectId id
       String   firstName
       String   lastName
    
       static mapWith = "mongo"
    
    }
    
    应用程序将有一个域,例如:

    grails-app/domain/com/example/bookstore/BookstoreUser.groovy

    package com.example.plugins.security
    
    class User {
    
       String  email
       String  hash
       Boolean enabled = true
    
    }
    
    package com.example.plugins.security
    
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
    
    class SecurityService {
    
       def authenticate(String email, String password) {
          def user = User.findByEmail(email)  //instance of BookstoreUser???
          def encoder = new BCryptPasswordEncoder()
          return user && encoder.matches(password, user.hash) ? user : null
          }
    
    }
    
    package org.example.bookstore
    
    import org.bson.types.ObjectId
    import org.example.plugins.security.User
    
    class BookstoreUser extends User {
    
       ObjectId id
       String   firstName
       String   lastName
    
       static mapWith = "mongo"
    
    }
    
    代码的其余部分位于:

    如何定义域,以便可以通过 使用插件的应用程序

    与定义任何其他域类的方式相同。在
    grailsapp/domain/
    下声明Groovy源文件

    插件如何引用扩展类的实例

    您在问题中显示的代码可以正常工作

    package com.example.plugins.security
    
    class SecurityService {
    
       def disableUser(User user) {  //the instance should be a BookstoreUser
              user.enabled = false
              user.save()
          }
    }
    

    如果应用程序编写了一个类,如
    BookstoreUser
    ,它扩展了
    User
    类,那么
    BookstoreUser
    的一个实例可以传递到
    disableUser
    方法中,并且该方法将按照您可能期望的方式运行。该方法将
    enabled
    属性设置为
    false
    ,然后保存更新的实例。

    我的坏。。。
    disableUser()
    示例过于简单化。我用
    authenticate()
    方法更新了这个问题,这个方法更有趣,没有传入
    user
    。服务如何知道在
    书店用户
    上而不是在
    用户
    上查找邮箱?
    我的坏。。。disableUser()示例过于简单。
    -根据问题中没有的其他因素(如系统中是否有其他
    用户
    类型,以及
    电子邮件
    在这些类型中是否唯一),您所展示的解决方案可能会起作用。我不得不否决你的问题。发布一个问题,得到一个专门针对该问题的答案,然后将问题改为其他问题,这是不负责任的。你在积极地浪费那些自愿帮助你的人的时间。如果你有一个单独的问题,应该作为一个单独的问题来提问。示例代码只是为了给这个问题添加一个具体的参考。问题仍然存在:
    插件如何引用扩展类的实例?
    我没有编辑这个问题。利用示例代码中的技术性问题,但实际上不回答这个问题,对将来尝试构建Grails插件的读者不会有好处。我非常有意地将这个问题的措辞用于对Grails社区的总体帮助。
    利用示例代码中的技术性,但不实际回答这个问题,对未来尝试构建Grails插件的读者不会有好处。
    -我不知道您是否断言这个答案会这样做。可能是我误解了这个问题。您可能会问如何将
    User
    类型的引用指向堆上的对象,该对象是扩展
    User
    的某个其他类的实例。如果这就是你要问的,那么上面的答案就说明了这一点。如果这不是您要问的,我很抱歉无法提供帮助。通常无法将实例传递到插件服务,例如插件服务需要创建新实例或搜索数据库以查找现有实例时。对于安全插件来说,注册新用户和在登录时验证用户都是如此。对于仍然对此感兴趣的任何人(我认为应该是几乎所有Grails插件开发人员),这里有一个包含示例插件和测试应用程序的项目: