Search code examples
dependency-injectiondryioc

Instances resolved conditionally


I'm writing an editor where some objects depend on an instance of some IFileFormat interface.

Depending on the file extension, the actual instance is either an instance of FileFormat1 class or FileFormat2 class, both implementing the IFileFormat interface.

I would like to have classes which depend on the IFileFormat get the instance in the c-tor:

class ClientObj {
     public ClientObj(IFileFormat f) { ... }
}

Is it possible to somehow register IFileFormat dynamically based on the file extension? (which is a string value). Note that the file extension itself is determined at run-time based on the filename of the file selected by the user.

I'm aware I could have a factory injected in the ClientObj c-tor which could allow me to determine dynamically the IFileFormat, but it would be nice to somehow depend on only the IFileFormat instance, not some factory instance.


Solution

  • In case your extension implementations are known at runtime you may register their instances via UseInstance(new FileExt2()).

    If you want to register all known extensions beforehand but select the one to be injected based on condition, then do:

    container.Register<IFileExt, FileExt1>(setup: Setup.With(condition: req => myCfg.FileExt == "ext1"));
    // similar for the rest of implementations
    

    Update

    You may also Register the new implementation any time with the IfAlreadyRegistered.Replace option. (UseInstance implies that by default). Then also don't forget use Setup.With(asResolutionCall: true) for the reasons https://github.com/dadhi/DryIoc/blob/master/docs/DryIoc.Docs/RulesAndDefaultConventions.md#injecting-dependency-asresolutioncall