[英]Autofac Resolve constructor instance from Container?
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.
假设我注册了两个ISurface类型。 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 : 根据文件,他们说:
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?
鉴于我已经注册了两个Surfaces,如何指定现有曲面?
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() ? 为什么我需要通过一个新的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: 你可以在这里做几件事:
This keeps in line with what you already have. 这与您已有的一致。 You can still use
.WithParameter()
but instead pass in a ResolvedParameter
instance to explain the parameter to find and how to fulfill the parameter: 您仍然可以使用
.WithParameter()
,而是传入ResolvedParameter
实例来解释要查找的参数以及如何完成参数:
builder.RegisterType<Car>().Named<IVehicle>( "Car" )
.WithParameter(
new ResolvedParameter(
( pInfo, ctx ) => pInfo.Name == "surface",
( pInfo, ctx ) => ctx.ResolveNamed<ISurface>( "Highway" )
)
);
The first delegate passed to the ResolvedParameter
constructor provides a way to find the parameter to fulfill, and the second delegate uses the IComponentContext
to resolve the Highway
instance from the Autofac container. 传递给
ResolvedParameter
构造函数的第一个委托提供了一种查找要实现的参数的方法,第二个委托使用IComponentContext
从Autofac容器中解析Highway
实例。
Alternatively there is an overload to WithParameter()
that you can use without having to explicitly create a ResolvedParameter
: 或者,可以使用
WithParameter()
的重载,而无需显式创建ResolvedParameter
:
builder.RegisterType<Car>().Named<IVehicle>( "Car" )
.WithParameter(
( pInfo, ctx ) => pInfo.Name == "surface",
( pInfo, ctx ) => ctx.ResolveNamed<ISurface>( "Highway" ) );
This option uses registration with a lambda expression: 此选项使用lambda表达式注册:
builder.Register( ( ctx ) => new Car( ctx.ResolveNamed<ISurface>( "Highway" ) ) ).Named<IVehicle>( "Car" );
Here you can see that I'm passing a lambda that represents my factory function which will again use the IComponentContext
to resolve the Highway
from the Autofac container. 在这里你可以看到我传递了一个代表我的工厂函数的lambda,它将再次使用
IComponentContext
从Autofac容器中解析Highway
。
I also read from your question that you wanted the same instance of ISurface
each time you requested it. 我还从你的问题中读到,每次你提出要求时,你都想要相同的
ISurface
实例。 If this is what you want, then you'll need to update your ISurface
registrations to include .SingleInstance()
: 如果这是你想要的,那么你需要更新你的
ISurface
注册以包括.SingleInstance()
:
builder.RegisterType<Highway>().Named<ISurface>( "Highway" ).SingleInstance();
builder.RegisterType<Ocean>().Named<ISurface>( "Ocean" ).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. 注册的默认生命周期是
InstancePerDependency
,这意味着Autofac解析器将在每次请求时提供对象的新实例。 SingleInstance
is essentially a singleton. SingleInstance
本质上是一个单例。 You'll only get one instance created and that instance will be returned on every request. 您只会创建一个实例,并且每个请求都会返回该实例。 Here's a link to that info
这是该信息的链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.