Search code examples
c#dependency-injectionmodulecaliburn.micro

How to register dependencies in another assembly with caliburn.micro's SimpleContainer


I'm working on a modular GUI application with caliburn.micro and I would like to do the bootstraping process separatly for each module. The reason for me to do that is that each module should be able to define its own dependencies and it makes little sense for me that the application using it should do i ( except in specific cases)

I can create a child container in the main boostraper by doing

container.CreateChildContainer();

But then I don't see how to register this container for my module to use. Any pointer to how it can be done ?

I can pass the child module to a boostraping method for my module, register what I need but don't know what to do with this container afterward.

Thank you and best regards,


Solution

  • I've found a partially working solution. However, I have some doubt about it beeing the right one :

    My modules have a base class, which is registered inside de container of the bootstrapper class. the container register itself so it can be injected in the modules constructor :

    private SimpleContainer container = new SimpleContainer();
    protected override void Configure()
    {
    
    container.Instance<container>();
    container.Instance<ILoggerFactory>(loggerFactory);
    container.Instance<IConfiguration>(config);
    container.Singleton<TestModule>();
    
    }
    

    In my module class , an initialization method is called from the constructor which creates a childContainer and register the required class in it.

    public TestModule(IConfiguration config, ILoggerFactory loggerFactory, SimpleContainer mainContainer) 
     {
         _modulecontainer = container.CreateChildContainer();
     }
    
    protected override void Initialize()
    {
         ModuleContainer.Singleton<TesterClass>();
         ModuleContainer.Singleton<ServiceTesterViewModel>();
    }
    

    This enables me to use constructor injection in my module without adding every details of the module in the application's bootstraper. Also I don't have to declare every viewModel in my module public.

    However I'm not sure it's a proper solution as I can't make it work as described in the documentation. According to it I should be able to override a previous declaration however it doesn't work. If I try to get an instance directly with the childContainer. I get an exception "Sequence contains more than one element" as my class is registered twice as a singleton :

    ServiceTesterViewModel mainViewModel = ModuleContainer.GetInstance<ServiceTesterViewModel>(); 
    

    Anyone could tell me if it is a proper solution or give me some pointers to what should be done instead.