Split up into multiple files - UUPS Upgradable ERC 721

Dear all,

my upgradable erc721 contract growed to much an I want to split several functions according to their togetherness into multiple files.

In this example "RoyaltyHelpers.sol".

There I have two questions and would like to ask you to give me some guidance:

  1. Is this the correct way to do so? (The import with initializer etc.)

  2. Can I access the constant ROYALTY_ROLE in the imported RoyaltyHelpers contract in any way directly or do I need to hand over the constant e.g. in the initializer?
    Seems as I haven't seen this before, so asking.

Thanks in advance.

import "../contracts/RoyaltyHelpers.sol";

contract MyContract is
    Initializable,ERC721Upgradeable,<cut>,
    RoyaltyHelpers

     bytes32 public constant ROYALTY_ROLE = keccak256("ROYALTY_ROLE");

    constructor() initializer {}

    function initialize(string memory contractUri) public initializer {
        __ERC721_init("MyContract", "MYT");
<cut>
        __ERC721Royalty_init();

        _grantRole(ROYALTY_ROLE, msg.sender);
        __RoyaltyHelpers_init(contractUri);
    }

And now the Subcontract:

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";

abstract contract RoyaltyHelpers is     
    Initializable,
    ERC721Upgradeable,
    AccessControlUpgradeable     
   {
    string private _contractUri;

    function __RoyaltyHelpers_init(string memory contractUri)
        internal
        onlyInitializing
    {
        _setContractURI(uri);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(
            ERC721Upgradeable,            
            AccessControlUpgradeable
        )
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function contractURI() public view returns (string memory) {
        return _contractUri;
    }

    function _setContractURI(string memory uri) internal {
        _contractUri = uri;
    }
    function setContractURI(string memory uri)
        public
        onlyRole(ROYALTY_ROLE)
    {
        _setContractURI(uri);
    }
<cut>
}

Hi all,

I tested a bit more and I had tomatos on my eyes. The solution was clear but now I have the following error:

TypeError: Linearization of inheritance graph impossible

Is this the diamond problem? But if yes, I'm just a bit lost how to solve this.
Any suggestions, please?

contract is:

import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol";
import "../contracts/RoyaltyHelpers.sol";

contract MyContract is
    Initializable,ERC721Upgradeable,<cut>,ERC721RoyaltyUpgradeable,
    RoyaltyHelpers

    constructor() initializer {}

    function initialize(string memory contractUri) public initializer {
        __ERC721_init("MyContract", "MYT");
<cut>
        __ERC721Royalty_init();

        _grantRole(ROYALTY_ROLE, msg.sender);
        __RoyaltyHelpers_init(contractUri);
    }

and the RoyaltyHelpers is

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol";

abstract contract RoyaltyHelpers is     
    Initializable,
    ERC721Upgradeable,
    AccessControlUpgradeable     
   {

    bytes32 public constant ROYALTY_ROLE = keccak256("ROYALTY_ROLE");
    string private _contractUri;

    function __RoyaltyHelpers_init(string memory contractUri)
        internal
        onlyInitializing
    {
        _setContractURI(uri);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(
            ERC721Upgradeable,            
            AccessControlUpgradeable
        )
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function contractURI() public view returns (string memory) {
        return _contractUri;
    }

    function _setContractURI(string memory uri) internal {
        _contractUri = uri;
    }
    function setContractURI(string memory uri)
        public
        onlyRole(ROYALTY_ROLE)
    {
        _setContractURI(uri);
    }
<cut>
}

Thank you very much in advance.