Ablue Ablue - 1 month ago 13
C# Question

IoC registration for wrapper class

I have interface

IA
and implementations
A:IA
and
B:IA
. The
B
implementation has a dependency on
IA
with constructor DI so that
B.ctor(IA)
.

The intent of this design is to wrap
A
with
B
and allow them to be used interchangeably.
A
is an adapter to a database, and
B
allows caching of that data.

IA
is also depending on by provider classes in this system, so that when I register those providers I would like to use an instance of
B
. My object graph should basically look as follows:

new Provider(
new B(
new A(
new DbContex("constr")
)
)
)


I have considered using a tagging interface such that
IB:IA
and
B:IB
, but then I would need to depend on
IB
on my providers instead of
IA
which would not be ideal.

I have also considered using a factory for
IA
that creates an instance of
B
using an instance of
A
, but that feels wrong.

So I guess I am looking for some way of accomplishing this registration using the simpleinjector IoC container.

Example code

public class A : IA
{
private readonly DbContext _context;

public A(DbContext context)
{
_context = context;
}

public T Get<T>()
{
// Do stuff to get and
// return value from database.
}

public void Set<T>(T value)
{
// Do stuff to set value
// in database.
}
}


Wrapper class:

public class B : IA
{
private readonly IA _adapter;

public B(IA adapter)
{
_adapter = adapter;
}

public T Get<T>()
{
// Do stuff to get and
// return value from cache
// or database adapter.
}

public void Set<T>(T value)
{
// Do stuff to set value
// in cache and database.
}
}


Consumer of
IA
:

public class Provider
{
private readonly IA _adapter;

public Provider(IA adapter)
{
_adapter = adapter;
}
}

Answer

What you're looking for is known as the decorator pattern.

Simple Injector has excellent support for applying decorators, probably the best support compared to other mainstream IoC containers.

You can read all about the decorator subsystem here: Aspect-Oriented Programming in the documentation.

For this basic case the registrations needed are straightforward:

container.Register<IA, A>();
container.RegisterDecorator<IA, B>();

And don't forget to put 'IA' in the ctor of B.

Comments