Named services in IoC containers - bad idea?

It seems like a bad idea to use service keys (or "named services") when composing a container.

Using named services requires us to either annotate our constructor parameters with the corresponding keys (thus, communication with the container), or perform additional wiring for each of our services (thus losing a lot of automation from the container).

For example, I currently have the following interface, which is implemented by the following classes:

  • IListSerializer
    • CheckboxListSerializer
    • TreeViewListSerializer

I also have countless classes that depend on one or both of these classes. However, AFAIK I should refer to IListSerializeras my dependency, not the implementation. This means that I have to use keys / names to distinguish them where it starts to get ugly.

I can see that my options are one of the following:

  • Annotate constructor parameters (dependencies) with keys. Pairs with an IoC container.
  • Perform manual wiring at the root of the composition. Adds recurring twists.
  • Class reference instead of interface. It seems to be hacked to satisfy an IoC container.

Any suggestions?

+5
source share
1

, IoC. , , . - IListSerializer<T>, .

, , Autofac.

:

builder.RegisterType<CheckBoxListSerializer>()
    .Named<IListSerializer>("checkBoxSerializer");
builder.RegisterType<TreeViewListSerializer>()
    .Named<IListSerializer>("treeViewSerializer");

, , . :

class NamedParameterResolutionModule<TService> : Module
{
    Parameter _attachedParameter = new ResolvedParameter(
        (pi, c) => pi.ParameterType == typeof(TService),
        (pi, c) => c.ResolveNamed<TService>(pi.Name));

    protected override void AttachToComponentRegistration(
        IComponentRegistry registry,
        IComponentRegistration registration)
    {
        registration.Preparing += (s, e) => {
            e.Parameters = new[] { _attachedParameter }.Contact(e.Parameters);
        };
    }
}

:

builder.RegisterModule<NamedParameterResolutionModule<IListSerializer>>();

:

class SomeComponent : ...
{
    public SomeComponent(IListSerializer checkBoxSerializer) { ...
}
+9

All Articles