gpt4 book ai didi

c# - Autofac 从 Container 解析构造函数实例?

转载 作者:行者123 更新时间:2023-11-30 14:07:33 26 4
gpt4 key购买 nike

如何在不传递实际实例的情况下注册一个将另一种类型作为其构造的一部分的类型。假设我注册了两个 ISurface 类型。我想注册一辆车,但我不想传递一个全新的实例。我想使用已经定义的表面之一。

根据他们声明的文档:

  • Autofac 看到 IDateWriter 映射到 TodayWriter 所以开始创建今日作家。
  • Autofac 发现 TodayWriter 需要一个 IOutput构造函数.
  • Autofac 看到 IOutput 映射到 ConsoleOutput,因此创建一个新的ConsoleOutput 实例。

那为什么注册Car的时候一定要传入一个Highway的实例呢?如果我注册了两个 Surface,我该如何指定一个现有的 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());

为什么我需要通过 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" )
)
);

第一个委托(delegate)传递给了ResolvedParameter构造函数提供了一种查找要实现的参数的方法,第二个委托(delegate)使用 IComponentContext解决 Highway来自 Autofac 容器的实例。

或者,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解决 Highway来自 Autofac 容器。

注意

我还从您的问题中了解到您想要 ISurface 的相同实例每次你要求它。如果这是你想要的,那么你需要更新你的 ISurface注册包括.SingleInstance() :

builder.RegisterType<Highway>().Named<ISurface>( "Highway" ).SingleInstance();
builder.RegisterType<Ocean>().Named<ISurface>( "Ocean" ).SingleInstance();

注册的默认生命周期是 InstancePerDependency这意味着 Autofac 解析器将在每次请求时提供对象的新实例。 SingleInstance本质上是一个单例。您只会创建一个实例,并且该实例将在每次请求时返回。这是一个 link到那个信息

关于c# - Autofac 从 Container 解析构造函数实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39985987/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com