Autofac官方文檔(十六)【在啟動時運行代碼】

來源:互聯網
上載者:User

Autofac提供了在構建容器時通知群組件或自動啟用組件的功能。

有三種自動啟用機制可用: - 可啟動組件 - 自動啟用組件 - 容器構建回調

在所有情況下,當容器建成時,組件將被啟用。 可開機組件

一個可開機組件是容器在最初構建時被容器啟用的組件,並且有一個特定的方法被調用來引導組件上的一個動作。

關鍵是要實現Autofac.IStartable介面。在構建容器時,組件將被啟用,並調用IStartable.Start()方法。

這隻會發生一次,對於每個組件的單個執行個體,首次構建容器。手動解析可啟動組件不會導致調用Start()方法。不建議可啟動組件實現其他服務,或者註冊為SingleInstance()以外的任何其他服務。

每次被啟用時需要像Start()方法那樣的組件應該使用像OnActivated這樣的生存事件。

要建立可啟動組件,請實現Autofac.IStartable:

public class StartupMessageWriter : IStartable{   public void Start()   {      Console.WriteLine("App is starting up!");   }}

然後註冊你的組件,並確保將其指定為IStartable,否則該操作將不會被調用:

var builder = new ContainerBuilder();builder   .RegisterType<StartupMessageWriter>()   .As<IStartable>()   .SingleInstance();

在構建容器時,類型將被啟用,並調用IStartable.Start()方法。 在這個例子中,一條訊息將被寫入控制台。

已知問題:雖然IStartable組件將以依賴性順序解析,但Start()方法實際上可能不會以依賴性順序調用。 您可以使用與SingleInstance註冊相結合的容器構建回調來解決此問題。 見下文。 自動啟用的組件

一個自動啟用的組件是一個組件,只需要在構建容器時啟用一次。 這是一種“暖開機”的行為方式,其中組件的任何方法都不被調用,也不需要實現介面 - 組件的單個執行個體將被解析,而不涉及它所持有的執行個體。

要註冊自動啟用的組件,請使用AutoActivate()註冊擴充。

var builder = new ContainerBuilder();builder   .RegisterType<TypeRequiringWarmStart>()   .AsSelf()   .AutoActivate();

注意:如果您在註冊AutoActivate()組件時忽略AsSelf()或As<T>()服務註冊調用,則組件只會被註冊為自動啟用,容器構建後並不一定會在解析“自身” 。 容器構建回調

您可以通過註冊構建回調來註冊任何在容器構建時發生的任意動作。 構建回調是一個Action<IContainer>,並將從ContainerBuilder.Build返回該容器之前擷取構建的容器。 構建回調按照它們註冊的順序執行:

var builder = new ContainerBuilder();builder   .RegisterBuildCallback(c => c.Resolve<DbContext>());/回調將在容器產生之後但返回之前運行var container = builder.Build();

您可以使用構建回調作為在容器構建中自動啟動/預熱對象的另一種方法。 通過將它們與生命週期事件OnActivated和SingleInstance註冊結合使用來實現這一點。 這可以解決IStartable實現以依賴順序解析的已知問題,但Start()方法不一定按依賴順序調用。

單元測試形式中的一個冗長/人為的例子:

public class TestClass{  // 建立一個依賴鏈 像:  //    ==> 2 ==+  // 4 =+       ==> 1  //    ==> 3 ==+  // 4需要2和3  // 2需要1   // 3需要1  // 依賴應該按順序啟動  // 1, 2, 3, 4  // 或者  // 1, 3, 2, 4  private class Dependency1  {    public Dependency1(ITestOutputHelper output)    {      output.WriteLine("Dependency1.ctor");    }  }  private class Dependency2  {    private ITestOutputHelper output;    public Dependency2(ITestOutputHelper output, Dependency1 dependency)    {      this.output = output;      output.WriteLine("Dependency2.ctor");    }    public void Initialize()    {      this.output.WriteLine("Dependency2.Initialize");    }  }  private class Dependency3  {    private ITestOutputHelper output;    public Dependency3(ITestOutputHelper output, Dependency1 dependency)    {      this.output = output;      output.WriteLine("Dependency3.ctor");    }    public void Initialize()    {      this.output.WriteLine("Dependency3.Initialize");    }  }  private class Dependency4  {    private ITestOutputHelper output;    public Dependency4(ITestOutputHelper output, Dependency2 dependency2, Dependency3 dependency3)    {      this.output = output;      output.WriteLine("Dependency4.ctor");    }    public void Initialize()    {      this.output.WriteLine("Dependency4.Initialize");    }  }  //Xunit把這個傳遞給測試類別的ctor,所以我們可以捕獲控制台輸出。  private ITestOutputHelper _output;  public TestClass(ITestOutputHelper output)  {    this._output = output;  }  [Fact]  public void OnActivatedDependencyChain()  {    var builder = new ContainerBuilder();    builder.RegisterInstance(this._output).As<ITestOutputHelper>();    builder.RegisterType<Dependency1>().SingleInstance();    //OnActivated取代了IStartable的需要。 當一個執行個體被啟用/建立時,它將按照指定的方式運行Initialize方法。 使用SingleInstance意味著只發生一次。    builder.RegisterType<Dependency2>().SingleInstance().OnActivated(args => args.Instance.Initialize());    builder.RegisterType<Dependency3>().SingleInstance().OnActivated(args => args.Instance.Initialize());    builder.RegisterType<Dependency4>().SingleInstance().OnActivated(args => args.Instance.Initialize());    //注意這些不是依賴性順序    builder.RegisterBuildCallback(c => c.Resolve<Dependency4>());    builder.RegisterBuildCallback(c => c.Resolve<Dependency2>());    builder.RegisterBuildCallback(c => c.Resolve<Dependency1>());    builder.RegisterBuildCallback(c => c.Resolve<Dependency3>());    // 這將運行構建回調。    var container = builder.Build();    //這些沒有任何作用。 OnActivated不會再被調用,因為它們是SingleInstance。    container.Resolve<Dependency1>();    container.Resolve<Dependency2>();    container.Resolve<Dependency3>();    container.Resolve<Dependency4>();  }}

這個樣本單元測試會產生這個輸出:

Dependency1.ctorDependency2.ctorDependency3.ctorDependency4.ctorDependency2.InitializeDependency3.InitializeDependency4.Initialize

你會從輸出中看到,以依賴順序執行的回呼函數和OnActivated方法。 如果你必須有啟用和啟動都發生在依賴順序(而不僅僅是啟用/決議),這是解決方案。

請注意,如果您不使用SingleInstance,則將為每個新的依賴項執行個體調用OnActivated。 由於“暖開機”對象通常是單例,建立起來很昂貴,所以這通常是你想要的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.