日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
ASP.NETCore應(yīng)用中與第三方IoC/DI框架整合的示例分析-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)ASP.NET Core應(yīng)用中與第三方IoC/DI框架整合的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、重慶小程序開(kāi)發(fā)公司、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶(hù)創(chuàng)新互聯(lián)還提供了商丘免費(fèi)建站歡迎大家使用!

一、ConfigureServices方法返回的ServiceProvider沒(méi)有用!

我們可以通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)說(shuō)明這個(gè)問(wèn)題。我們先定義了如下這個(gè)一個(gè)MyServiceProvider,它實(shí)際上是對(duì)另一個(gè)ServiceProvider的封裝。簡(jiǎn)單起見(jiàn),我們利用一個(gè)字典來(lái)保存服務(wù)接口與實(shí)現(xiàn)類(lèi)型的映射關(guān)系,這個(gè)關(guān)系可以通過(guò)調(diào)用Registe方法來(lái)注冊(cè)。在提供服務(wù)實(shí)例的GetService方法中,如果提供的服務(wù)類(lèi)型已經(jīng)被注冊(cè),我們會(huì)創(chuàng)建并返回對(duì)應(yīng)的實(shí)例對(duì)象,否則我們將利用封裝的這個(gè)ServiceProvider來(lái)提供服務(wù)。為了確保服務(wù)實(shí)例能夠被正常回收,如果服務(wù)類(lèi)型實(shí)現(xiàn)了IDisposable接口,我們會(huì)將它添加到通過(guò)字段_disposables表示的集合中。當(dāng)MyServiceProvider的Dispose方法被調(diào)用的時(shí)候,提供的這些服務(wù)實(shí)例的Dispose方法會(huì)被調(diào)用。

 public class MyServiceProvider : IServiceProvider, IDisposable
 {
 private IServiceProvider _innerServiceProvider;
 private Dictionary _services;
 private List _disposables;
 
 public MyServiceProvider(IServiceProvider innerServiceProvider)
 {
 _innerServiceProvider = innerServiceProvider;
 this._services = new Dictionary();
 _disposables = new List();
 }
 
 
 public MyServiceProvider Register() where TTo: TFrom, new()
 {
 _services[typeof(TFrom)] = typeof(TTo);
 return this;
 }
 
 public object GetService(Type serviceType)
 {
 Type implementation;
 if (_services.TryGetValue(serviceType, out implementation))
 {
 object service = Activator.CreateInstance(implementation);
 IDisposable disposbale = service as IDisposable;
 if (null != disposbale)
 {
  _disposables.Add(disposbale);
 }
 return service;
 }
 return _innerServiceProvider.GetService(serviceType);
 }
 
 public void Dispose()
 {
 (_innerServiceProvider as IDisposable)?.Dispose();
 foreach (var it in _disposables)
 {
 it.Dispose();
 }
 _disposables.Clear();
 }
 }

我們按照如下的方式在一個(gè)ASP.NET Core應(yīng)用中使用MyServiceProvider。如下面的代碼片斷中,在注冊(cè)的Starup類(lèi)型中,我們讓ConfigureServices方法返回一個(gè)MyServiceProvider對(duì)象。服務(wù)接口IFoobar和實(shí)現(xiàn)類(lèi)型Foobar之間的映射注冊(cè)在這個(gè)MyServiceProvider對(duì)象上。在處理請(qǐng)求的時(shí)候,我們利用當(dāng)前HttpContext對(duì)象的RequestServices屬性得到為請(qǐng)求處理提供服務(wù)的ServiceProvider,并試圖利用它得到注冊(cè)的IFoobar服務(wù)。

 public class Program
 {
 public static void Main(string[] args)
 {
 new WebHostBuilder()
 .UseKestrel()
 .UseStartup()
 .Build()
 .Run();
 }
 }
 
 public class Startup
 {
 public IServiceProvider ConfigureServices(IServiceCollection services)
 {
 return new MyServiceProvider(services.BuildServiceProvider())
 .Register();
 }
 
 public void Configure(IApplicationBuilder app)
 {
 app.UseDeveloperExceptionPage()
 .Run(async context => await context.Response.WriteAsync(context.RequestServices.GetRequiredService().GetType().Name));
 }
 }
 public interface IFoobar { }
 public class Foobar : IFoobar { }

整個(gè)應(yīng)用就這樣簡(jiǎn)單,貌似也沒(méi)有什么問(wèn)題,但是我們啟動(dòng)應(yīng)用并利用瀏覽器訪(fǎng)問(wèn)該應(yīng)用是就會(huì)出現(xiàn)如下所示的錯(cuò)誤。錯(cuò)誤信息表示服務(wù)接口IFoobar尚未被注冊(cè)。

ASP.NET Core應(yīng)用中與第三方IoC/DI框架整合的示例分析

二、原因何在?

我們明明在返回的ServiceProvider注冊(cè)了IFoobar和Foobar之間的映射關(guān)系,為什么RequestServices返回的ServiceProvider說(shuō)該服務(wù)尚未被注冊(cè)呢?的解釋就是ConfigureServices方法返回的ServiceProvider與HttpContext的RequestServices返回的ServiceProvider根本就不是同一個(gè)。實(shí)際上它們本來(lái)就不是同一個(gè)對(duì)象。

ConfigureServices方法返回的ServiceProvider將會(huì)作為WebHost的ServiceProvider,對(duì)于每次接收的請(qǐng)求,WebHost會(huì)根據(jù)這個(gè)ServiceProvider創(chuàng)建一個(gè)新的ServiceProvider來(lái)作為HttpContext的RequestServices屬性,這兩個(gè)ServiceProvider具有父子管理。照例說(shuō),如果RequestServices返回的ServiceProvider是根據(jù)ConfigureServices方法返回的ServiceProvider創(chuàng)建的,那么它也應(yīng)該能夠識(shí)別注冊(cè)的服務(wù)類(lèi)型IFoobar,那么為什么依然會(huì)出現(xiàn)錯(cuò)誤呢?

要了解這個(gè)問(wèn)題,就需要知道這個(gè)所謂的“子ServiceProvider”是如何被創(chuàng)建出來(lái)的,這其中涉及到ServiceScope的概念。簡(jiǎn)單來(lái)說(shuō),ServiceScope是對(duì)一個(gè)ServiceProvider的封裝,前者決定后者的生命周期。ServiceScope由ServiceScopeFactory創(chuàng)建,后者以一個(gè)服務(wù)的形式注冊(cè)到“父ServiceProvider”上面。當(dāng)“父ServiceProvider”需要?jiǎng)?chuàng)建“子ServiceProvider”的時(shí)候,它會(huì)調(diào)用GetService方法得到這個(gè)ServiceScopeFactory對(duì)象(采用的服務(wù)接口為IServiceScopeFactory),并利用后者創(chuàng)建一個(gè)ServiceScope,這個(gè)ServiceScope提供的ServiceProvider就是返回的“子ServiceProvider”。

但是對(duì)于我們的MyServiceProvider對(duì)象來(lái)說(shuō),當(dāng)調(diào)用它的GetService方法試圖獲取ServiceScopeFactory對(duì)象的時(shí)候,獲取的實(shí)際上是被封裝的那個(gè)SerivceProvider關(guān)聯(lián)的ServiceScopeFactory,那么很自然創(chuàng)建的“子ServiceProvider”也與MyServiceProvider沒(méi)有什么關(guān)系。

三、如何解決這個(gè)問(wèn)題?

既然我們知道了問(wèn)題的根源,我們自然就有了解決方案。解決方案并不復(fù)雜,我們只需要MyServiceProvider的GetService方法返回反映其自身服務(wù)注冊(cè)相關(guān)的ServiceScopeFactory。為此我們定義了如下一個(gè)ServiceScope和對(duì)應(yīng)的ServiceScopeFactory。

 internal class ServiceScope : IServiceScope
 {
 private MyServiceProvider _serviceProvider;
 
 public ServiceScope(IServiceScope innserServiceScope, Dictionary services)
 {
 _serviceProvider = new MyServiceProvider(innserServiceScope.ServiceProvider, services);
 }
 public IServiceProvider ServiceProvider
 {
 get { return _serviceProvider; }
 }
 
 public void Dispose()
 {
 _serviceProvider.Dispose();
 }
 }
 
 internal class ServiceScopeFactory : IServiceScopeFactory
 {
 private IServiceScopeFactory _innerServiceFactory;
 private Dictionary _services;
 
 public ServiceScopeFactory(IServiceScopeFactory innerServiceFactory, Dictionary services)
 {
 _innerServiceFactory = innerServiceFactory;
 _services = services;
 }
 public IServiceScope CreateScope()
 {
 return new ServiceScope(_innerServiceFactory.CreateScope(), _services);
 }
 }

除此之外,我們?yōu)镸yServiceProvider添加了一個(gè)構(gòu)造函數(shù),GetService方法也針對(duì)IServiceScopeFactory添加了相應(yīng)的代碼。


 public class MyServiceProvider : IServiceProvider, IDisposable
{
 public MyServiceProvider(IServiceProvider innerServiceProvider, Dictionary services)
 {
 _innerServiceProvider = innerServiceProvider;
 _services = services;
 _disposables = new List();
 }
 
 public object GetService(Type serviceType)
 {
 if (serviceType == typeof(IServiceScopeFactory))
 {
 IServiceScopeFactory innerServiceScopeFactory = _innerServiceProvider.GetRequiredService();
 return new ServiceScopeFactory(innerServiceScopeFactory, _services);
 }
 ... 
 }
 ...
 }

感謝各位的閱讀!關(guān)于“ASP.NET Core應(yīng)用中與第三方IoC/DI框架整合的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!


當(dāng)前題目:ASP.NETCore應(yīng)用中與第三方IoC/DI框架整合的示例分析-創(chuàng)新互聯(lián)
URL分享:http://www.dlmjj.cn/article/didoce.html