程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 談一談autofac組件的實例范圍

談一談autofac組件的實例范圍

編輯:C#入門知識

談一談autofac組件的實例范圍。本站提示廣大學習愛好者:(談一談autofac組件的實例范圍)文章只能為提供參考,不一定能成為您想要的結果。以下是談一談autofac組件的實例范圍正文


實例范圍決議如何在懇求之間共享服務。

原文地址:http://docs.autofac.org/en/latest/lifetime/instance-scope.html

每個依賴一個實例
運用這個選項,每次懇求服務都會前往一個新實例。運用 InstancePerDependency() 指定。這是默許選項。上面的代碼,第2行和第3行是等價的。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>();
builder.RegisterType<Worker>().InstancePerDependency();

上面的代碼,每次循環都生成一個新的實例,一共生成 100 個實例。

using(var scope = container.BeginLifetimeScope())
{
 for(var i = 0; i < 100; i++)
 {
  var w = scope.Resolve<Worker>();
  w.DoWork();
 }
}


單個實例

運用這個選項,在根范圍或嵌套范圍中懇求服務,都前往同一個的實例。運用 SingleInstance() 指定。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().SingleInstance();
上面的代碼,w1 和 w2 一直是同一個對象,100 次循環只要一個 Worker 類的實例。

using(var scope1 = container.BeginLifetimeScope())
{
 for(var i = 0; i < 100; i++)
 {
  var w1 = scope1.Resolve<Worker>();
  using(var scope2 = scope1.BeginLifetimeScope())
  {
   var w2 = scope2.Resolve<Worker>();
  }
 }
}

每個生命周期范圍一個實例

運用這個選項,在特定的 ILifetimeScope 中懇求服務,只前往一個實例。運用 InstancePerLifetimeScope() 指定。上面的代碼中,scope1 中的 100 次 w1 是同一個對象,scope2 中的 100 次 w2 是同一個對象,但是 w1 和 w2 不是同一個對象。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerLifetimeScope();
using(var scope1 = container.BeginLifetimeScope())
{
 for(var i = 0; i < 100; i++)
 {
  var w1 = scope1.Resolve<Worker>();
 }
}

using(var scope2 = container.BeginLifetimeScope())
{
 for(var i = 0; i < 100; i++)
 {
  var w2 = scope2.Resolve<Worker>();
 }
}

每個婚配的生命周期范圍一個實例

相似於下面【每個生命周期范圍一個實例】,但可以提供更多控制。運用此選項,允許為 ILifetimeScope 對象提供“標志”。在標志婚配的范圍中只要一個實例。運用 InstancePerMatchingLifetimeScope() 辦法指定。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerMatchingLifetimeScope("x");

上面的代碼中,w1 和 w2 相反,w3 和 w4 相反,但 w1 和 w3 不同。

using(var scope1 = container.BeginLifetimeScope("x"))
{
 for(var i = 0; i < 100; i++)
 {
  var w1 = scope1.Resolve<Worker>();
  using(var scope2 = scope1.BeginLifetimeScope())
  {
   var w2 = scope2.Resolve<Worker>();
  }
 }
}

using(var scope3 = container.BeginLifetimeScope("x"))
{
 for(var i = 0; i < 100; i++)
 {
  var w3 = scope3.Resolve<Worker>();
  using(var scope4 = scope1.BeginLifetimeScope())
  {
   var w4 = scope4.Resolve<Worker>();
  }
 }
}

解析時必需提供提供適宜的標志,以下代碼會拋出異常。

using(var noTagScope = container.BeginLifetimeScope())
{
 var fail = noTagScope.Resolve<Worker>();
}

每個懇求一個實例

有些使用順序自然具有【懇求】語義,例如 ASP.NET MVC 或 WebForm 使用順序。【每個懇求一個實例】在【每個婚配的生命周期范圍一個實例】根底上,經過提供范圍標志,注冊函數和罕見類型集成完成。實質上是【每個婚配的生命周期范圍一個實例】。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerRequest();

ASP.NET Core 運用【每個生命周期范圍一個實例】,而不是【每個懇求一個實例】。

每個Owned 一個實例

 Owned<T> 隱式關聯類型創立嵌套的生命周期范圍。運用 instance-per-owned 注冊,可將依賴限定在 owned 實例中。

var builder = new ContainerBuilder();
builder.RegisterType<MessageHandler>();
builder.RegisterType<ServiceForHandler>().InstancePerOwned<MessageHandler>();

本例中 ServiceForHandler 服務會限制在 MessageHandler 實例范圍內。

using(var scope = container.BeginLifetimeScope())
{
 // MessageHandler 和隸屬的 ServiceForHandler 
 // 在 scope 上面的一個微型的 lifetime scope 中。
 // 解析 Owned<T> 需求順序員擔任執行清算任務。
 var h1 = scope.Resolve<Owned<MessageHandler>>();
 h1.Dispose();
}

線程范圍

Autofac 可以強迫使A線程的對象不滿足B線程的依賴。

var builder = new ContainerBuilder();
builder.RegisterType<MyThreadScopedComponent>()
    .InstancePerLifetimeScope();
var container = builder.Build();

然後讓每個創立自己的 lifetime scope

void ThreadStart()
{
 using (var threadLifetime = container.BeginLifetimeScope())
 {
  var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
 }
}

重要:在多線程場景下,要小心不要將父范圍清算掉。否則,派生線程中的子范圍將無法解析服務。

每個線程都將有自己的 MyThreadScopedComponent 實例,實質上是生命周期范圍內的單例。范圍內的實例不會提供到內部,因而很容易堅持線程間的組件隔離。

經過添加 ILifetimeScope 參數,可將父范圍注入到生成線程的代碼中,Autofac 會將以後范圍自動注入,接上去可以運用它創立嵌套范圍。

public class ThreadCreator
{
 private ILifetimeScope _parentScope;

 public ThreadCreator(ILifetimeScope parentScope)
 {
  this._parentScope = parentScope;
 }

 public void ThreadStart()
 {
  using (var threadLifetime = this._parentScope.BeginLifetimeScope())
  {
   var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
  }
 }
}

假如想進一步控制,可以運用【每個婚配的生命周期范圍一個實例】將線程范圍的組件同外部生命周期范圍關聯起來,這個方式的效果如圖:

圖中的"Context"是 BeginLifetimeScope 辦法創立的生命周期范圍。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved