0

I want to make a 'decorator' for the IRepository. This decorator is also a 'composition' of multiple IRepository's. In code:

public interface IRepository { }
public class RepositoryFoo : IRepository { }
public class RepositoryBar : IRepository { }
public class RepositoryDuh : IRepository { }

public class RepositoryComposition : IRepository
{
  public RepositoryComposition(IRepository master, IEnumerable<IRepository> slaves) { }
}

The RepositoryComposition will in some cases call both master and slaves and in some cases only the master.

I have made this setup work with both Autofac and Ninject, but I think the Ninject solution is not so good. So the question is, can this be done better? And how?

Here is my Autofac solution:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<RepositoryFoo>().Named<IRepository>("master");
builder.RegisterType<RepositoryBar>().Named<IRepository>("slave");
builder.RegisterType<RepositoryDuh>().Named<IRepository>("slave");

builder.Register<IRepository>(f => new RepositoryComposition(
  f.ResolveNamed<IRepository>("master"), 
  f.ResolveNamed<IEnumerable<IRepository>>("slave"))
);

Here is my Ninject solution:

Bind<RepositoryFoo>().ToSelf();
Bind<RepositoryBar>().ToSelf();
Bind<RepositoryDuh>().ToSelf();
Bind<IRepository>().To<RepositoryComposition>().
  WithConstructorArgument("somethings", f => f.Kernel.Get<RepositoryFoo>()).
  WithConstructorArgument("slaves", f => new IRepository[] { 
    f.Kernel.Get<RepositoryBar>(), 
    f.Kernel.Get<RepositoryDuh>() 
});

I both cases I will resolve in the IRepository interface.

  • First of all, this isn't a [decorator pattern](https://sourcemaking.com/design_patterns/decorator). In a decorator, you can add additional responsibilities to an object at runtime. Is there some particular reason your `RepositoryComposition` needs to be aware of the "master" instance vs "slave" instances? – NightOwl888 Aug 13 '15 at 18:09

1 Answers1

1

This is not an answer but is useful to know given the question: the registration is simple with Simple Injector

container.Register<IRepository, RepositoryFoo>();
container.RegisterAll<IRepository>(typeof(RepositoryBar), typeof(RepositoryDuh));
container.RegisterDecorator(
    typeof(IRepository),
    typeof(RepositoryComposition), 
    context => context.ImplementationType == typeof(RepositoryFoo));
qujck
  • 14,388
  • 4
  • 45
  • 74