今天就跟大家聊聊有關ASP.NET Core中如何采用Autofac來替換IOC容器并實現屬性注入,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
10余年的梁園網站建設經驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。成都全網營銷推廣的優(yōu)勢是能夠根據用戶設備顯示端的尺寸不同,自動調整梁園建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)公司從事“梁園網站設計”,“梁園網站推廣”以來,每個客戶項目都認真落實執(zhí)行。
今天我們主要講講如何采用Autofac來替換IOC容器,并實現屬性注入
首先,我們需要從nuget引用相關的包.
Autofac
Autofac.Extensions.DependencyInjection(這個包擴展了一些微軟提供服務的類.來方便替換autofac)
然后,我們修改Startup中的ConfigureServices代碼如下:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<BloggingContext>();
services.AddDirectoryBrowser();
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule<DefaultModule>();
containerBuilder.Populate(services);
var container = containerBuilder.Build();
return new AutofacServiceProvider(container);
}
這里我們使用了AutoFac的功能之一,模塊化注入.也就是RegisterModule 這里, DefaultModule是我們的注入模塊,代碼很簡單,如下:
public class DefaultModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//注入測試服務
builder.RegisterType<TestService>().As<ITestService>();
}
}
解釋一下,在上面的代碼中,我們配置IServiceProvider從Autofac容器中解析(設置一個有效的Autofac服務適配器)。
然后在整個框架中使用它來解析控制器的依賴關系,并在HttpContext上公開所有其他用例的服務定位。
這樣我們就完成了初步的Autofac容器替換.下面我們創(chuàng)建控制器來看看效果.代碼如下:
public class AutoDIController : Controller
{
private readonly ITestService _testService;
public AutoDIController(ITestService testService)
{
_testService = testService;
}
// GET: AutoDI
public ActionResult Index()
{
ViewBag.date = _testService.GetList("Name");
return View();
}
}
當框架(通過一個命名為DefaultControllerActivator的服務)要創(chuàng)建一個控制器的實例時,它會解析IServiceProvider的所有構造函數依賴項.在上面的代碼中,它會使用Autofac容器來解析產生類。
這樣就能初步的達到我們替換IOC容器的的效果了..
但是,這個操作過程與asp.net MVC的不同之處在于.控制器本身不會從容器中解析出來,所以服務只能從它的構造器參數中解析出來。
所以.這個過程,讓我們無法使用Autofac的一些更高級功能.比如屬性注入(關于屬性注入的好壞..屬于仁者見仁智者見智的東西,這里我們不討論它是好還是壞.)
我們回到Autofac設置代碼,并設置屬性注入如下:
var containerBuilder = new ContainerBuilder();
//模塊化注入
containerBuilder.RegisterModule<DefaultModule>();
//屬性注入控制器
containerBuilder.RegisterType<AutoDIController>().PropertiesAutowired();
containerBuilder.Populate(services);
注入模塊的代碼修改如下:
//屬性注入builder.RegisterType<TestService>().As<ITestService>().PropertiesAutowired();
然后修改我們的控制器代碼如下:
public class AutoDIController : BaseController
{
public ITestService _testService { get; set; }
// GET: AutoDI
public ActionResult Index()
{
ViewBag.date = _testService.GetList("Name");
return View();
}
}
這里我們剔除了控制器的構造函數.
我們運行代碼,會發(fā)現_testService 為null,所以根本沒有注入成功.失敗的原因上面我們已經解釋過了...但是還是強調一下吧..
雖然控制器的構造函數依賴性將由MVC從IServiceProvider解決(也就是我們之前構造函數注入的例子),
但是控制器本身的實例(以及它的處理)卻是由框架創(chuàng)建和擁有的,而不是由容器所有。
那么我們該如何改變控制器本身的創(chuàng)建和所有者呢?
我們會在Microsoft.Extensions.DependencyInjection中找到一個方法.叫做AddControllersAsServices
它的注釋翻譯過來為:將控制器的寄宿器轉為注冊的服務(也就是我們替換的autofac).
但是,注意..這里雖然是將控制的所有者改成了autofac,但是我們還是不能使用相關的屬性注入方法.
所以,我們到GITHUB上來看看這個方法源碼如下.(這就是開源的好處...):
public static IMvcBuilder AddControllersAsServices(this IMvcBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
var feature = new ControllerFeature();
builder.PartManager.PopulateFeature(feature);
foreach (var controller in feature.Controllers.Select(c => c.AsType()))
{
builder.Services.TryAddTransient(controller, controller);
}
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
return builder;
}
我們會發(fā)現最后一句..
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
意思是用ServiceBasedControllerActivator替換DefaultControllerActivator(意味著框架現在會嘗試從IServiceProvider中解析控制器實例)
..這下終于真相大白了..
我們只需要修改配置服務的代碼如下:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//替換控制器所有者
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
services.AddMvc();
services.AddDbContext<BloggingContext>();
services.AddDirectoryBrowser();
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule<DefaultModule>();
//采用屬性注入控制器
containerBuilder.RegisterType<AutoDIController>().PropertiesAutowired();
// containerBuilder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired();
containerBuilder.Populate(services);
var container = containerBuilder.Build();
return new AutofacServiceProvider(container);
}
注意,替換的方法一定要在addMVC之前..
然后我們運行我們的控制器代碼.效果如圖:
如圖所示,_testService已經被實例化了.說明我們的屬性注入就成功了~
看完上述內容,你們對ASP.NET Core中如何采用Autofac來替換IOC容器并實現屬性注入有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
網站欄目:ASP.NETCore中如何采用Autofac來替換IOC容器并實現屬性注入
標題URL:http://sd-ha.com/article14/ggicge.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供面包屑導航、網站維護、外貿網站建設、ChatGPT、定制開發(fā)、網站設計
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)