国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - ASP.NET Core應(yīng)用中與第三方IoC/DI框架的整合

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

2020-04-30 12:41蔣金楠 ASP.NET教程

ASP.NET Core應(yīng)用中,針對第三方DI框架的整合可以通過在定義Startup類型的ConfigureServices方法返回一個ServiceProvider來實現(xiàn)。但是并不是那么容易的,下面通過實例給大家分享一下

一、ConfigureServices方法返回的ServiceProvider沒有用!

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class MyServiceProvider : IServiceProvider, IDisposable
{
private IServiceProvider _innerServiceProvider;
private Dictionary<Type, Type> _services;
private List<IDisposable> _disposables;
 
public MyServiceProvider(IServiceProvider innerServiceProvider)
{
_innerServiceProvider = innerServiceProvider;
this._services = new Dictionary<Type, Type>();
_disposables = new List<IDisposable>();
}
 
 
public MyServiceProvider Register<TFrom, TTo>() 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();
}
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Program
{
public static void Main(string[] args)
{
new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Build()
.Run();
}
}
 
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
return new MyServiceProvider(services.BuildServiceProvider())
.Register<IFoobar, Foobar>();
}
 
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage()
.Run(async context => await context.Response.WriteAsync(context.RequestServices.GetRequiredService<IFoobar>().GetType().Name));
}
}
public interface IFoobar { }
public class Foobar : IFoobar { }

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

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

二、原因何在?

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

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

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

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

三、如何解決這個問題?

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
internal class ServiceScope : IServiceScope
{
private MyServiceProvider _serviceProvider;
 
public ServiceScope(IServiceScope innserServiceScope, Dictionary<Type, Type> 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<Type, Type> _services;
 
public ServiceScopeFactory(IServiceScopeFactory innerServiceFactory, Dictionary<Type, Type> services)
{
_innerServiceFactory = innerServiceFactory;
_services = services;
}
public IServiceScope CreateScope()
{
return new ServiceScope(_innerServiceFactory.CreateScope(), _services);
}
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MyServiceProvider : IServiceProvider, IDisposable
{
 public MyServiceProvider(IServiceProvider innerServiceProvider, Dictionary<Type, Type> services)
 {
 _innerServiceProvider = innerServiceProvider;
 _services = services;
 _disposables = new List<IDisposable>();
 }
 
 public object GetService(Type serviceType)
 {
 if (serviceType == typeof(IServiceScopeFactory))
 {
 IServiceScopeFactory innerServiceScopeFactory = _innerServiceProvider.GetRequiredService<IServiceScopeFactory>();
 return new ServiceScopeFactory(innerServiceScopeFactory, _services);
 }
 ...
 }
 ...
 }

以上分享,希望能對需要解決這樣問題的朋友有所幫助!

原文鏈接:http://www.cnblogs.com/artech/p/3rd-party-di-integration.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲欧美另类在线 | 日韩精品免费在线视频 | 久久久精品亚洲 | 亚洲综合大片69999 | 国产91对白叫床清晰播放 | 午夜视频在线观看免费视频 | 日韩资源 | 精品国产乱码久久久久久丨区2区 | ...99久久国产成人免费精品 | 亚洲综合av在线播放 | 日韩一区中文 | 欧美大片免费观看 | 日韩一区二区电影 | 午夜视频在线免费观看 | 国产视频黄在线观看 | 日韩免费一区二区 | 欧美日韩欧美日韩 | 午夜亚洲| 少妇一区二区三区免费观看 | 欧美国产日韩在线 | 黄在线观看 | 狠狠色噜噜| 91影院在线观看 | 国产综合视频在线观看 | 精品成人免费一区二区在线播放 | 欧美大逼| 久久久一 | 深夜精品 | 中日韩一线二线三线视频 | 国产精品99久久久久久久vr | 精品国产乱码久久久久久牛牛 | 亚洲午夜激情 | 免费一级毛片 | 久久99精品国产 | 免费一看一级毛片 | 亚洲视频在线看 | 看片久久 | 国产精品极品美女在线观看免费 | 欧美午夜精品一区二区三区电影 | 国产一级毛片国语一级 | 久久国产精品一区 |