日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

既然是依賴注入容器,必然會涉及到服務的注冊,獲取服務實例,管理作用域,服務注入這四個方面。

  • 服務注冊涉及如何將我們的定義的服務注冊到容器中。這通常是實際開發中使用容器的第一步,而容器本身通常是由框架來實例化的,大多數時候,并不需要自己初始化容器。

  • 獲取服務實例這一步,在實際開發中通常也不涉及,服務示例一般是通過注入來實現的。這里只是為了讓我們對容器的使用了解的更全面一些。

  • 管理作用域一般在開發中也不涉及,框架,例如 .NET 的 MVC 框架已經幫我們把這個問題處理了。

  • 服務注入是我們需要關注的,不同的依賴注入容器支持不同的注入方式。在使用中,我們會通過注入來獲取服務對象的實例。而不是自己 new 出來。

?看起來很復雜,使用的時候其實很簡單。

1. 服務注冊

1.1 支持不同的作用域 Scope

DependencyInjection 通過 Add 方法來進行服務注冊,三種不同的作用域通過三種帶有不同后綴的 Add 方法來支持。

?

services.AddSingleton<IUserService, UserService>();services.AddScoped<IUserService, UserService>();services.AddTransient<IUserService, UserService>();

Singleton 就是單例,以后通過該容器獲取出來的,都是同一個服務對象實例。

Scoped 就是限定了作用域,在每個特定的作用域中,只會有一個服務對象實例。作用域需要你自己來創建,后面在使用服務的時候,我們再介紹。

而 Transient 則在每次從容器中獲取的時候,都對創建新的服務對象實例。  

三種作用域簡單明了,后面我們介紹服務注冊的時候,就不再關注服務的作用域,都使用單例來介紹,其它兩種方式是相同的。

1.2 基于接口注冊

這是最為常見的注冊方式,在實際開發中,服務一般都有對應的接口。為了方便注冊,在 .NET Core 中一般使用泛型方式進行注冊,這樣比較簡潔。是最推薦的方式。

1services.AddSingleton<IUserService, UserService>();

當然,也可以使用基于類型的方式注冊,不過代碼沒有使用泛型方式優雅。你需要先獲取服務的類型,再通過類型進行注冊。

1services.AddSingleton(typeof(IUserService),?typeof(UserService));

1.3 直接注冊實例

如果服務并沒有對應的接口,可以直接使用對象實例注冊,ServiceCollection 會直接使用該實例類型作為服務接口類型來注冊,這種方式比較簡單粗暴。

1services.AddSingleton(typeof(UserService));

?

1.4 注冊泛型服務

泛型是很強大的特性,例如,泛型的倉儲,我們只需要一個泛型倉儲,就可以通過它訪問針對不同類型的數據。

容器必須要支持泛型的服務,例如,針對下面的簡化倉儲示例,注意這里的 Get() 簡化為只返回默認值。

1234567891011121314public?interface?IRepository<T>{????T Get(int?id);}public?class?Repository<T>: IRepository<T> {????public?Repository() {????????Console.WriteLine(typeof(T).Name);????}????public?T Get(int?id){????????return?default(T);????}}

只需要注冊一次,就可以獲得不同實現的支持。但是,泛型比較特殊,不能這樣寫:

1services.AddSingleton<IRepository<>, Repository<>>();

你需要通過類型的方式來進行服務注冊。

1services.AddSingleton(typeof(IRepository<>),?typeof(Repository<>));  

如果沒有這個倉儲接口的話,就可以這樣注冊。

1services.AddSingleton(typeof(Repository<>));

如果涉及到多個類型的泛型,例如倉儲的定義變成下面這樣,id 的類型使用 K 來指定。

1234public?interface?IRepository<T, K>{????T Get(K id);}

而倉儲的實現也變成下面這樣:

123456789public?class?Repository<T, K>: IRepository<T, K> {????public?Repository() {????????Console.WriteLine(typeof(T).Name);????}????public?T Get(K id){????????return?default(T);????}}

注冊的時候,就需要寫成下面的樣子:

1services.AddSingleton (typeof?(IRepository<,>),?typeof?(Repository<,>));
1

1.5 工廠模式注冊

除了讓容器幫助構造服務對象實例,我們也可以自己定義構建服務對象實例的工廠供容器使用。

如果服務實現沒有參數,例如 UserRepository,可以這樣寫:

123services.AddSingleton<IUserRepository>( (serviceProvider) => {????return?new?UserReposotory();????} );

如果構造函數是有參數的,比如:

12345public?class?UserReposotory: IUserRepository {????public?UserReposotory(string?name){????????Console.WriteLine( name);????}}  

注冊就變成了下面的樣子,需要注意的是,工廠會得到一個 ServiceProvider 的實例供你使用。

1234services.AddSingleton<IUserRepository> ((serviceProvider) => {????????????Console.WriteLine ("construction IUserReposority");????????????return?new?UserReposotory ("Tom");????????});

1.6 直接使用?ServiceDescriptor 注冊

實際上,上面各種注冊方式最終都會通過創建一個服務描述對象來完成注冊,它的定義如下,你可以看到上面各種注冊方式所涉及的痕跡。

12345678public?class?ServiceDescriptor{????public?ServiceLifetime Lifetime {?get; }????public?Type ServiceType {?get; }????public?Type ImplementationType {?get; }????public?object?ImplementationInstance {?get; }????public?Func<IServiceProvider,?object> ImplementationFactory {?get; }}

所以,實際上,你可以通過自己創建這個服務描述對象來進行注冊。

1services.Add(ServiceDescriptor.Singleton<IUserService, UserService>());

殊途同歸,其實與使用上面的方式效果是一樣的。

2 管理 Scope

如果注冊服務的時候,指定了服務是單例的,無論從哪個 Scope 中獲得的服務實例,都會是同一個。所以,單例的服務與 Scope 就沒有什么關系了。

如果注冊服務的時候,指定了服務是瞬態的,無論從哪個 Scope 中獲取服務實例,都會是新創建的,每次獲取就新創建一個。所以,瞬態的服務與 Scope 也沒有什么關系了。

只有在注冊時聲明是 Scoped 的服務,才會涉及到 Scope。所以,只有 Scoped 的服務才會涉及到 Scope。

在容器初始化之后,會創建一個根的 Scope 作用域,它是默認的。?

1IServiceProvider provider = services.BuildServiceProvider ();

在需要作用域的時候,可以通過已經創建的 provider 來創建作用域,然后從這個新創建的作用域再獲取當前的服務提供器。

1234IServiceProvider provider = services.BuildServiceProvider ();IServiceScope scope = provider.CreateScope();IServiceProvider scopedServiceProvider = scope.ServiceProvider;  

通過作用域的服務提供器獲取服務對象實例的時候,就會影響到通過 Scoped 注冊的服務了。

這種類型的服務在每一個 Scope 中只會創建一個。

在微軟的實現中,不支持嵌套的 Scope。

3 注入服務

?現在又回到了涉及編程中的使用,在需要服務對象實例的時候,我們只需要注入。

微軟的實現實際上只支持了構造函數注入。例如:

12345678public?class?HomeController : Controller{????private?readonly?IDateTime _dateTime;????public?HomeController(IDateTime dateTime)????{????????_dateTime = dateTime;????}

 

4 常見問題

?多次注冊問題

你可以對同一個服務類型多次注冊,這并不會遇到異常。在獲取服務對象實例的時候,是通過最后一次注冊來支持的。

需要的話,也可以獲取到所有注冊的服務對象實例。

1var?instances = provider.GetServices(typeof(IUserService));  

不是直接注入服務,而是注入容器

容器本身也可以注入,它的類型是 IServiceProvider,這樣,你可以自己來通過容器完成特殊的處理。

123var?sp = provider.GetService<IServiceProvider> ();var?userService = sp.GetService<IUserService> ();Console.WriteLine (userService);

  

5 簡化注冊過程

?https://www.cnblogs.com/catcher1994/p/handle-multi-implementations-with-same-interface-in-dotnet-core.html

?

參考資料:

  • ServiceCollectionServiceExtensions at GitHub

  • Does .net core dependency injection support Lazy<T>

總結

以上是生活随笔為你收集整理的依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品九九视频 | 99久久婷婷国产综合精品电影 | 天天舔天天操 | 无码人妻精品一区二区 | 神马午夜激情 | 欧美激情 亚洲 | 在线观看污污视频 | 国产精品一卡二卡在线观看 | 五月激情天| 五月天激情影院 | 欧美日韩视频一区二区三区 | 久久99国产视频 | 免费观看一级视频 | 午夜999| 欧美性色a | 91精品国产综合久久福利 | av大全免费观看 | 欧美激情日韩 | 国产精品三区四区 | 黄色大片aa | 在线无| 青草视频在线观看视频 | 久久久久亚洲av无码专区桃色 | 懂色av蜜臂av粉嫩av | 欧美大片免费观看 | 蜜乳av一区 | 亚洲最新av网站 | 在线观看91| 精品国产一区二区三区日日嗨 | 尤物视频最新网址 | 日韩黄色在线视频 | av视| 99热91| 欧美乱淫 | www久久久 | 美女网站污| 国产日韩在线看 | 国产婷婷色一区二区三区 | 就要操就要射 | 开心色99| 波多野结衣中文一区 | 中文字幕在线观看视频一区 | 芒果视频在线观看免费 | www成人网| 亚洲涩涩在线 | 成人欧美视频在线观看 | 快播怡红院 | 奇米视频在线观看 | 久久久久久久国产精品毛片 | 国产黄在线播放 | 免费国产一区二区 | 日本特黄一级片 | 成人3d动漫一区二区三区 | 婷婷成人综合网 | 三上悠亚在线一区 | 96国产精品 | 一级黄色性视频 | 欧美日韩亚洲激情 | 精品午夜一区二区三区在线观看 | 开心激情五月婷婷 | 日韩一区二区视频在线 | 国产片淫乱18一级毛片动态图 | 男人的天堂手机在线 | 最新黄色网址在线观看 | chinesepron hd videos国产91 | 青青草华人在线 | 日韩视频国产 | 特一级黄色大片 | 亚洲自拍激情 | 无码人妻一区二区三区在线 | 中文字幕永久在线观看 | 影音先锋伦理片 | 免费的黄色小视频 | 热精品| 91狠狠干 | 射射综合网 | 日韩a毛片 | 九一国产在线观看 | 99热只有这里有精品 | 无码日韩人妻精品久久蜜桃 | 成年免费视频 | 国产又粗又猛又黄视频 | 国产乡下妇女做爰毛片 | 波多av在线| 亚洲久草 | 成人做爰9片免费视频 | av体验区 | 国产乱码精品1区2区3区 | 亚洲在线影院 | 爱插视频| 超碰超碰超碰超碰 | 日韩中文字幕视频在线 | 亚洲精品成人在线 | 床上激情网站 | 都市激情校园春色亚洲 | 国产乱论视频 | 成人av在线网站 | 噜啪啪 | 中文字幕精品一区二区精品 |