How can I register a type which takes another type as part of it's constructed without passing an actual instance. Say I have two ISurface types registered. I want to register a Car but i don't want to pass in a brand new instance. I want to use one of the surfaces already defined.
Per the documentation they state :
- Autofac sees that IDateWriter maps to TodayWriter so starts creating a TodayWriter.
- Autofac sees that the TodayWriter needs an IOutput in its constructor.
- Autofac sees that IOutput maps to ConsoleOutput so creates a new ConsoleOutput instance.
Then why must I pass in an instance of Highway when registering a Car? Given that I have two Surfaces's registered how do I specify an existing surface?
var builder = new ContainerBuilder();
builder.RegisterType<Highway>().Named<ISurface>("Highway");
builder.RegisterType<Ocean>().Named<ISurface>("Ocean");
builder.RegisterType<Car>().Named<IVehicle>("Car").WithParameter("surface", new Highway());
Why do I need to pass a new Highway()?
Here's my models.
public interface IVehicle
{
void Move();
}
public interface ISurface
{
string SurfaceType { get; }
}
public class Highway : ISurface
{
public string SurfaceType => "Pavement";
}
public class Ocean : ISurface
{
public string SurfaceType => "Ocean"
}
public class Car : IVehicle
{
private ISurface _surface;
public Car(ISurface surface)
{
_surface = surface;
}
public void Move()
{
Console.WriteLine($"I'm traveling at high speeds across {_surface.SurfaceType}");
}
}
There's a couple things you can do here:
Option 1
This keeps in line with what you already have. You can still use
.WithParameter()
but instead pass in aResolvedParameter
instance to explain the parameter to find and how to fulfill the parameter:The first delegate passed to the
ResolvedParameter
constructor provides a way to find the parameter to fulfill, and the second delegate uses theIComponentContext
to resolve theHighway
instance from the Autofac container.Alternatively there is an overload to
WithParameter()
that you can use without having to explicitly create aResolvedParameter
:Option 2
This option uses registration with a lambda expression:
Here you can see that I'm passing a lambda that represents my factory function which will again use the
IComponentContext
to resolve theHighway
from the Autofac container.NOTE
I also read from your question that you wanted the same instance of
ISurface
each time you requested it. If this is what you want, then you'll need to update yourISurface
registrations to include.SingleInstance()
:The default lifetime given to registrations is
InstancePerDependency
which means that the Autofac resolver will give a new instance of the object every time it is requested.SingleInstance
is essentially a singleton. You'll only get one instance created and that instance will be returned on every request. Here's a link to that info