Search code examples
c#inheritancebond

Allowing two projects to inherit from the same bond


Using Microsoft Bond in a C# project.

Suppose I had a Bond file A used in one project A', and wanted to have two projects B' and C' have Bond files B and C both of which have structs that inherit from a struct in file A. How would I do that?

I thought about making a ProjectReference, but it appears to only supply the C# classes generated from these Bond files, and not allow me to make Bond inheritance from the original Bond files, so instead I made a link between one project to the other. Unfortunately, my current solution is very error-prone, and changing that file location in one project would break the other as well.

What would be the suggested way to do that?


Solution

  • To have Bond files B and C inherit from or contain the types from Bond file A (in project A'), you need to import Bond file A at the top of B and C. This makes the types in A known in B and C.

    a.bond

    namespace A;
    
    struct Base { }
    

    b.bond

    import "a.bond"
    
    namespace B;
    
    struct Derived : A.Base { } 
    
    struct Composition {
        // notice fully qualified name is used for Base
        0: A.Base has_a_base;
    }
    

    For the import path, you have three options:

    1. Use a fully qualified path like import "C:/src/projectAPrime/schemas/a.bond"
    2. Use a relative path like import "../../projectAPrime/schemas/a.bond"
    3. Use a relative path like import "a.bond" or import "schemas/a.bond" and add to the Bond import paths: elsewhere in the consuming project, you'd make sure that the BondImportDirectory item was augmented with a search directory for project A.

    I would not recommend the first option, as it ties the paths to one specific machine's layout. Mixes of option 2 or 3 are used in practice.

    For approach three, the consuming project usually has something like this either directly in it, or via some other MSBuild file it imports.

    <ItemGroup>
      <BondImportDirectory Include="$(ProjectAPrimeRoot)" />
      <!-- or some other reference to project A, depending
           on how your projects are structured (perhaps you
           have a all_projects.props file for these sort of
           variables or item modifications -->
    </ItemGroup>
    

    I can't give you more concrete guidance than this, as your specific project structure isn't something I know, and MSBuild doesn't have a way for a project to "export" values that referencing project automatically get (that I'm aware of).

    Note that you will still need a ProjectReference to project A', as the code generated in projects B' and C' will have dependencies on the code generated and compiled into the assembly that project A' produces.

    For a working example of imports using BondImportDirectory see the C# import example in the Bond repository. This does not address the cross-project import, however, so you'll need to adapt for your situation.

    If you're a C++ developer, this should feel similar to #include paths.