天天看點

Autofac - 生命周期

執行個體生命周期決定在同一個服務的每個請求的執行個體是如何共享的。

  當請求一個服務的時候,Autofac會傳回一個單例 (single instance作用域), 一個新的對象 (per lifetime作用域) 或者在某種上下文環境中的單例。比如 一個線程 或者一個HTTP請求 (per lifetime 作用域)。

  這條規則适用于顯式調用Resolve從容器中檢索對象或者滿足依賴而隐式實作的對象。

準備工作:

public class Person
{

    public string Name { get; set; }

    public int Age { get; set; }

    public void Self()
    {
        Console.WriteLine("我叫{0}, 今年{1}歲了!", this.Name, this.Age);
    }
}      

開始了:

  1、Per Dependency

  在其他容器中也稱作瞬态或者工廠,使用Per Dependency作用域,服務對于每次請求都會傳回新的執行個體. 

  在沒有指定其他參數的情況下,這是預設是作用域。

var builder = new ContainerBuilder();

builder.Register(c => new Person() { Name = "Elvin" }).InstancePerDependency();

var container = builder.Build();

var person1 = container.Resolve<Person>();
person1.Name = "person1";
            
var person2 = container.Resolve<Person>();
person2.Name = "person2";

person1.Self();
person2.Self();      
Autofac - 生命周期

  2、Single Instance

  使用Single Instance作用域,所有對父容器或者嵌套容器的請求都會傳回同一個執行個體。

  這裡将 InstancePerDependency 直接替換成 SingleInstance 就行了, 其他代碼是一樣的. 直接看結果:

Autofac - 生命周期

  3、Per Lifetime Scope

  每一個lifetime内, 生成的對象都是同一個執行個體.  

  這個作用域适用于嵌套的生命周期。一個使用Per Lifetime 作用域的component在一個 nested lifetime scope内最多有一個執行個體。

  當對象特定于一個工作單元時,這個非常有用。比如,一個HTTP請求,每一個工作單元都會建立一個nested lifetime,如果在每一次HTTP請求中建立一個nested lifetime,那麼其他使用 per-lifetime 的component在每次HTTP請求中隻會擁有一個執行個體。

  這種配置模型在其他容器中等價于per-HTTP-request, per-thread等。  

var builder = new ContainerBuilder();

builder.Register(c => new Person() { Name = "Elvin" }).InstancePerLifetimeScope();

var container = builder.Build();

var person1 = container.Resolve<Person>();
person1.Name = "person1";

var person2 = container.Resolve<Person>();
person2.Name = "person2";

var inner = container.BeginLifetimeScope();

var person3 = container.Resolve<Person>();
person3.Name = "person3";

var person4=  container.Resolve<Person>();
person4.Name = "person4";

person1.Self();
person2.Self();

person3.Self();
person4.Self();       

  

Autofac - 生命周期

ASP.NET和WCF內建中,每一次web請求或者方法調用,InstancePerLifetimeScope會被預設附加到component上。

   4、上下文

  上下文作用域和per-lifetime作用域類似,但是對可見性提供更多顯示的控制。

  在大多數程式中,同一層次的容器嵌套代表一個工作單元,如果需要多層嵌套(例如global->request->transation),可以使用标簽確定component在多層結構中的某一層共享。

  builder.RegisterType<XWorker>().InstancePerMatchingLifetimeScope(MyContextHierarchy.UserSession);      

  提供的标簽和生命周期作用域是對應的

  var userSessionLifetime = container.BeginLifetimeScope();
  userSessionLifetime.Tag = MyContextHierarchy.UserSession;      

 參考:

  AutoFac文檔