Search code examples
c#autofacautofac-module

Autofac: How to separate multiple plugins


I got a project generating output for different formats. The architecture is about like this:

Xyz.Core
Xyz.FormatA
Xyz.FormatB
Xyz.Runner`

both Xyz.FormatA and ...FormatB depend on ...Core. Runner depends on everything.

Now Core exposes all kinds of interfaces, for example

IFormatSpecifics
IWriter
IFormatWorker`

etc and some abstract classes, too. Both FormatA and FormatB contain an implementation of IFormatWorker (this being sort of the format specific root object and not really called such, this example being just an abstraction of what I need to do) and the others, mostly by deriving from abstract classes in Core which already do part of the work. Runner just instantiates the concrete IFormatWorkers and lets them do their work.

So far all of this has been going on without any IOC container. Now I want to switch to using Autofac.

Now my question is: what is the correct mechanism to make it so that the implementation of IFormatWorker in Xyz.FormatA gets its implementations of IFormatSpecifics, IWriter and so on from inside Xyz.FormatA, and analogous for FormatB. From my reading, I think the right way must have something to do with using Modules (one for each format) and Keyed Services. On the other hand, I've seen also a reference here on stackflow (https://stackoverflow.com/a/26798803/2105891) which seems to indicate that for a plugin-like scenario separate containers might be the right thing.

EDIT: Multitenant registrations might also be the right thing, from what I read - just that I do not have any defaults.

Thanks, Max


Solution

  • I wrote a small plugin for Autofac doing what I need. It's available as a nuget package: https://www.nuget.org/packages/Autofac.Extras.Plugins/

    The source can be found at https://github.com/ModernRonin/Autofac.Extras.Plugins

    Basically, it uses keyed services, but hides some of the complexity for this particular use case.

    Feedback and contributions are welcome.

    PS: I hope answering with a working nuget package is fine here on SO, even if I wrote it myself :)