繁体   English   中英

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

[英]Autofac Resolve constructor instance from Container?

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

根据文件,他们说:

  • Autofac看到IDateWriter映射到TodayWriter,因此开始创建TodayWriter。
  • Autofac发现TodayWriter在其构造函数中需要IOutput
  • Autofac看到IOutput映射到ConsoleOutput,因此创建一个新的ConsoleOutput实例。

那么为什么我必须在登记汽车时通过高速公路的实例? 鉴于我已经注册了两个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());

为什么我需要通过一个新的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 ,这意味着Autofac解析器将在每次请求时提供对象的新实例。 SingleInstance本质上是一个单例。 您只会创建一个实例,并且每个请求都会返回该实例。 这是该信息的链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM