在 autofac 依赖注入中 InstancePerOwned 的正确用法是什么

What is the proper usage of InstancePerOwned in autofac dependency injection

我想知道 InstancePerOwned<TService>() 在 Autofac 中的正确用法是什么。解决依赖关系时如何使用它?

考虑以下代码

public interface IAnotherService
{
    int Id { get; set; }
    string Lable { get; set; }
}

public class AnotherService : IAnotherService,IDisposable
{
    public int Id { get; set; }
    public string Lable { get; set; }


    public AnotherService(/* loads of dependent components*/)
    {

    }

    public override string ToString()
    {
        return string.Format("My Id is:{0} and my lable is {1}", Id, Lable);
    }

    public void Dispose()
    {
        // Another Service is Disposing ;
    }
}

public interface IMyService
{
    void DoSomething();
}

// MyService class depends on IAnotherService
// MyService class is a huge and long-lived class where we have just ommited lots of other implementations
public class MyService : IMyService
{
    private readonly IAnotherService _anotherService;

    public MyService(IAnotherService anotherService)
    {
        _anotherService = anotherService;
    }

    public Void DoSomething()
    {
        Console.WriteLine(_anotherService.ToString());
    }

    //
    //
    //
    // The rest of the class
    //
    //
    //
    //
}

在上面的代码中,MyService class 依赖于 IAnotherService。所以在你的依赖注册中你会以某种方式说

 builder.RegisterType<AnotherService>().As<IAnotherService>().InstancePerDependency();


这确保任何时候使用 Autofac 实例化或解析 MyService 的实例时,都会在实例化 MyService 的生命周期内预先解析 AnotherService 的一个实例。

虽然 MyService 还活着,换句话说,它的父生命周期是活着的,但 _anotherService 需要活着,无论它是否在 MyService 的其余代码中使用。

拥有的实例

请注意,服务的拥有实例是从刚刚创建的生命周期范围实例化的对象。

 Owned<IAnotherService> _anotherService ;


这个对象 (_anotherService) 的优点是在它实例化之前

  1. 将初始化一个新的生命周期范围
  2. AnotherService 实例在步骤 1 中新创建的生命周期范围内实例化

  3. 新的AnotherService实例及其容器lifetimescope将被绑定并形成一个Owned实例并注入到MyService class.

在 MyService 的生命周期中,您不再需要 _anotherService 的任何时候都可以直接调用它的 Dispose() 方法,例如

_anotherService.Dispose() ;


处置它后,该对象和绑定的生命周期范围以及该生命周期范围的任何其他子对象或依赖对象都将消失并释放。 所以你不必忍受 _anotherService 的不必要存在和它的依赖组件负载

所以我们的 MyService 的构造函数部分应该像下面这样:

    private readonly Owned<IAnotherService> _anotherService;

    public MyService(Owned<IAnotherService> anotherService)
    {
        _anotherService = anotherService;
    }

InstancePerOwned

这意味着我们有一个生命周期绑定到另一个服务,另一个服务在其中实例化。 如果你想强制上面生命周期内的所有新创建的对象和解析的组件共享另一个服务的同一个实例 那么你必须在注册时使用 InstancePerOwned

 builder.RegisterType<AnotherService>().As<IAnotherService>().InstancePerOwned<IAnotherService>();


并且一旦将 AnotherService 注册为 InstancePerOwned 就无法传递纯 IAnotherInstance 并且必须像 Owned 一样传递它,否则会出现异常。




您可以在 An Autofac Lifetime Primer

上阅读更多内容

编辑:修复了一个字符的拼写错误(编辑必须至少为 6 个字符!)