自动解析容器中的构造函数实例
本文关键字:构造函数 实例 | 更新日期: 2023-09-27 18:12:49
如果不传递实际实例,如何注册一个接受另一个类型作为其构造的一部分的类型?假设我注册了两个表面类型。我想注册一辆车,但我不想传入一个全新的实例。我想用一个已经定义好的曲面。
根据文档他们说:
- autofacc看到IDateWriter映射到TodayWriter所以开始创建TodayWriter。
- autofacc看到TodayWriter在它的构造函数。 Autofac看到IOutput映射到ConsoleOutput,所以创建了一个新的ConsoleOutput实例。
那么为什么我在注册汽车时必须在Highway实例中通过呢?假设我有两个表面注册,我如何指定一个现有的表面?
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());
为什么我需要通过新建的高速公路()?
这是我的模型。
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}");
}
}
您可以在这里做几件事:
选项1
这与你已经拥有的保持一致。您仍然可以使用.WithParameter()
,但要传递一个ResolvedParameter
实例来解释要查找的参数以及如何实现参数:
builder.RegisterType<Car>().Named<IVehicle>( "Car" )
.WithParameter(
new ResolvedParameter(
( pInfo, ctx ) => pInfo.Name == "surface",
( pInfo, ctx ) => ctx.ResolveNamed<ISurface>( "Highway" )
)
);
传递给ResolvedParameter
构造函数的第一个委托提供了一种找到要实现的参数的方法,第二个委托使用IComponentContext
从Autofac容器中解析Highway
实例。
或者,您可以使用WithParameter()
的重载,而不必显式地创建ResolvedParameter
:
builder.RegisterType<Car>().Named<IVehicle>( "Car" )
.WithParameter(
( pInfo, ctx ) => pInfo.Name == "surface",
( pInfo, ctx ) => ctx.ResolveNamed<ISurface>( "Highway" ) );
选项2
该选项使用lambda表达式注册:
builder.Register( ( ctx ) => new Car( ctx.ResolveNamed<ISurface>( "Highway" ) ) ).Named<IVehicle>( "Car" );
在这里你可以看到,我正在传递一个lambda,它代表我的工厂函数,它将再次使用IComponentContext
来解析来自Autofac容器的Highway
。
注意
我也从你的问题中读到,你每次请求时都想要相同的ISurface
实例。如果这是你想要的,那么你需要更新你的ISurface
注册,包括.SingleInstance()
:
builder.RegisterType<Highway>().Named<ISurface>( "Highway" ).SingleInstance();
builder.RegisterType<Ocean>().Named<ISurface>( "Ocean" ).SingleInstance();
注册的默认生存期是InstancePerDependency
,这意味着autofacc解析器每次被请求时都会给出一个对象的新实例。SingleInstance
本质上是一个单例。您将只创建一个实例,并且该实例将在每次请求时返回。这是info的链接