I have my project structure looks like this:
Structure of code:
hypervisor
├── hypervisor.go
├── hyperv
│ └── hyperv.go
└── virtualbox
├── vbox.go
└── vboxprops.go
Source code:
//hypervisor/hypervisor.go
package hypervisor
type Hypervisor interface {
Start(vmName string) error
ListMounts(vmName string) ([]MountPath, error)
//....
}
type MountPath struct {
HostPath string
GuestPath string
}
func detect() (Hypervisor, error) {
return &virtualbox.Virtualbox{}, nil // <<1 HERE
}
// ... other code
And have another (nested) package :
//hypervisor/virtualbox/vbox.go
package virtualbox
type Virtualbox struct {
}
func (*Virtualbox) Start(vmName string) error {
return vboxManage("startvm", vmName, "--type", "headless").Run()
}
func (*Virtualbox) ListMounts(vmName string) ([]hypervisor.MountPath, error) { // <<2 HERE
// ....
}
// ... other code
And as seen, of course, such code leads to import cycle not allowed . because of:
hypervisorpcakge referencingvirtualbox.VirtualBoxtypevirtualboxpackage referencinghypervisor.MountPathtype
I know if I move the struct MounthPath to another package would solve the issue, but I don't think is the correct solution design-wise.
Any suggestion?
One of easiest way I would do is to separate entities into
entitiespackage for example (in this case: theHypervisorandVirtualboxstruct are entities or whatever you want to call it).This is most common design I think, so every struct that inner packages use will not cause cyclic deps.
Example of usage: all
timepackage structs are on top package level.time.Time{},time.Duration{}, etc.time.Durationdoes not sit ontime/durationpackage.