Search code examples
c#dependency-injectionunity-containerioc-containercircular-dependency

Circular reference with my bootloader / Unity


I have a serious problem with my Unity and bootloader. It's a circular reference.

Let me explain what I have currently:

MainApp (winforms)

ServiceLayer - C# project

DependencyInjection - C# Project for the Container

Bootloader - C# project for the bootloader to do mappings for automapper and Unity.

Now the the bookloader has references to everything i.e. The service, the container etc the mainApp (winforms) and it does its job just great.

The problem is that I am starting the bootloader from my MainApp (winforms) like so

 DI.Container.RegisterType<IBootstrapper, Bootstrapper>(
    new InjectionConstructor(DI.Container));

            var bootstrapper = DI.Container.Resolve<IBootstrapper>();

            bootstrapper.StartUp();

Now the problem here is the following, MainApp needs a reference to Bootloader because that's where the class and interface is - but I can't because Bootloader has a reference to the MainApp as the bootloader registers some stuff that is in the mainapp.

I think I am getting confused somewhere, the main idea was to move the bootstrapper out of the mainapp into its own assembly and the Container has its own assembly too; the bootstrapper needs all its references including to MainApp but of course Mainapp needs a reference to bootstrapper to create it and start it up.

Edit

I could of course register the types from the mainapp by accessing the container directly but doesn't this defeat the object of having my bootloader, which takes care of everything?


Solution

  • I'm not an expert on this topic, the reason I found your post was because I was looking for help with a similar issue, but I think maybe there is some overlap between our problems, and maybe the stuff I've tried so far might be able to help you, or point you in a direction that can get you some progress.

    If you want to see all the stuff I wrote, including some diagrams, you can find it here: Using StructureMap, is one of these project organizations better than another?

    If there is a better answer, hopefully someone will point it out and I'll learn from this as well.

    Basically, I think you have a couple options.

    You can merge your bootloader and MainApp into the same project. (as you said, that seems "wrong")

    You can move the code from MainApp that is needed by BootLoader into another assembly, and then reference it from both BootLoader and MainApp.

    You can remove your reference from MainApp to BootLoader, and then use see if there are other ways to automatically get a reference to BootLoader at runtime using Unity. I'm using StructureMap, which has a feature where you tell it to scan some assemblies (at app startup), and then you can tell it to apply "default conventions", which means if there is an interface called IWhatever, and a class Whatever:IWhatever, then it will automatically set it up so asking for an instance of IWhatever will give you a concrete instance of Whatever.

    So this way, you can have BootLoader reference MainApp at compile time, but still have code in MainApp that can access stuff in BootLoader at runtime (by using IOC and going through an interface).

    I hope this helps.