最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.Net Core 之AutoFac的使用

 更新時間:2021年09月07日 10:36:16   作者:張三~~  
本文簡單介紹了AutoFac的基本使用以及在asp .net core中的應(yīng)用,文中通過代碼講解相關(guān)知識非常的詳細,對大家的學(xué)習(xí)或工作都很有幫助,感興趣的小伙伴可以參考一下這篇文章

本文不介紹IoC和DI的概念,如果你對Ioc之前沒有了解的話,建議先去搜索一下相關(guān)的資料

這篇文章將簡單介紹一下AutoFac的基本使用以及在asp .net core中的應(yīng)用

Autofac介紹

組件的三種注冊方式

1.反射

2.現(xiàn)成的實例(new)

3.lambda表達式 (一個執(zhí)行實例化對象的匿名方法)

下面是一些簡短的示例,我盡可能多的列出來一些常用的注冊方式,同時在注釋中解釋下“組件”、“服務(wù)”等一些名詞的含義

// 創(chuàng)建注冊組件的builder
var builder = new ContainerBuilder();

//根據(jù)類型注冊組件 ConsoleLogger 暴漏服務(wù):ILogger
builder.RegisterType<ConsoleLogger>().As<ILogger>();

//根據(jù)類型注冊組件 ConsoleLogger,暴漏其實現(xiàn)的所有服務(wù)(接口)
builder.RegisterType<ConsoleLogger>().AsImplementedInterfaces();

// 根據(jù)實例注冊組件 output  暴漏服務(wù):TextWriter
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

//表達式注冊組件,這里我們是在構(gòu)造函數(shù)時傳參->"musection"   暴漏服務(wù):IConfigReader
builder.Register(c =new ConfigReader("mysection")).As<IConfigReader>();

//表達式注冊組件,解析時傳參
var service = scope.Resolve<IConfigReader>(
           new NamedParameter("section", "mysection"));     

//反射注冊組件,直接注冊了ConsoleLogger類(必須是具體的類),如果ConsoleLogger有多個構(gòu)造函數(shù),將會取參數(shù)最多的那個構(gòu)造函數(shù)進行實例化
builder.RegisterType<ConsoleLogger>();

//反射注冊組件,手動指定構(gòu)造函數(shù),這里指定了調(diào)用 MyComponent(ILogger log,IConfigReader config)的構(gòu)造函數(shù)進行注冊
builder.RegisterType<MyComponent>()
 .UsingConstructor(typeof(ILogger), typeof(IConfigReader));  

 //注冊MySingleton類中的靜態(tài)變量"Instance",ExternallyOwned()函數(shù)指定自己控制實例的生命周期,而不是由autofac自動釋放
 builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();

//一個組件暴漏兩個服務(wù)  
builder.RegisterType<CallLogger>().As<ILogger>().As<ICallInterceptor>(); 

//注冊當(dāng)前程序集中以“Service”結(jié)尾的類
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();
//注冊"MyApp.Repository"程序集中所有的類
builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
  
//構(gòu)建一個容器完成注冊
var rootcontainer = builder.Build();

//可以通過下面這種方式手動獲取IConfigReader 的實現(xiàn)類
//這種手動解析的方式需要 從生命周期作用域內(nèi)獲取組件,以保證組件最終被釋放
//不要直接從根容器rootcontainer中解析組件,很有可能會導(dǎo)致內(nèi)存泄漏
using(var scope = rootcontainer.BeginLifetimeScope())
{
  var reader = scope.Resolve<IConfigReader>();
}

如果不止一個組件暴露了相同的服務(wù), Autofac將使用最后注冊的組件作為服務(wù)的提供方。 想要覆蓋這種行為, 在注冊代碼后使用 PreserveExistingDefaults() 方法修改

生命周期

using(var scope = rootcontainer.BeginLifetimeScope())

上面的這段代碼創(chuàng)建了一個生命周期作用域

生命周期作用域是可釋放的,在作用域內(nèi)解析的組件一定要保證在using之內(nèi)使用或者最后手動調(diào)用組件的Dispose()函數(shù)

避免引用類的生命周期大于被引用類的生命周期 :如service 引用 repository 如果service的生命周期為單例,repository的生命周期為perrequest。service不會釋放,所以最終會造成相關(guān)的repository始終無法釋放的情況(Captive Dependencies

雖然我們需要盡可能的避免直接從根容器解析組件,但總有例外的情況,對于非單例的組件,一定不要忘記調(diào)用組件的Dispose函數(shù),實際上對于非單例的組件,從項目架構(gòu)上來說,理論上應(yīng)該是從構(gòu)造函數(shù)注入進去的而不是手動解析。 需要手動解析的應(yīng)該為一些配置幫助類等

對于一個具體組件(類)的生命周期分為以下幾種(后面的函數(shù)是autofac對應(yīng)的函數(shù)):

  • 每個依賴一個實例(Instance Per Dependency) (默認) ----InstancePerDependency()
  • 單一實例(Single Instance) 單例 ----SingleInstance()
  • 每個生命周期作用域一個實例(Instance Per Lifetime Scope)----InstancePerLifetimeScope()
  • 每個匹配的生命周期作用域一個實例(Instance Per Matching Lifetime Scope)----InstancePerMatchingLifetimeScope()
  • 每個請求一個實例(Instance Per Request) asp.net web請求----InstancePerRequest()
  • 每次被擁有一個實例(Instance Per Owned) ----InstancePerOwned()

如果你以前在傳統(tǒng)的ASP.NET MVC項目中用過autofac,需要注意一些區(qū)別:

  • .net Core中需要使用InstancePerLifetimeScope替代之前(傳統(tǒng)asp.net)的InstancePerRequest,保證每次HTTP請求只有唯一的依賴實例被創(chuàng)建。InstancePerRequest請求級別已經(jīng)不存在了
  • .net Core中Web Api與Mvc的注冊方式一樣
  • .net Core中不再需要注冊控制器,控制器由.net core創(chuàng)建,不歸autofac管理(除了控制器的構(gòu)造函數(shù)),這也解釋了為什么不再使用InstancePerRequest生命周期,但是可以通過AddControllersAsServices()函數(shù)改變,想要深入了解的可以查看:https://www.strathweb.com/2016/03/the-subtle-perils-of-controller-dependency-injection-in-asp-net-core-mvc/

AutoFac 在asp .net core中的使用

在.net core 中使用autofac還是比較簡單的,相比于傳統(tǒng)的asp.net web 項目,省去了很多步驟

引入nuget程序包:

  • Autofac
  • Autofac.Extensions.DependencyInjection

startup 中代碼:

  public static IContainer AutofacContainer;
    // This method gets called by the runtime. Use this method to add services to the container.
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        //注冊服務(wù)進 IServiceCollection
        services.AddMvc();
        ContainerBuilder builder = new ContainerBuilder();
        //將services中的服務(wù)填充到Autofac中.
        builder.Populate(services);
        //新模塊組件注冊
        builder.RegisterModule<DefaultModuleRegister>();
        //創(chuàng)建容器.
        AutofacContainer = builder.Build();
        //使用容器創(chuàng)建 AutofacServiceProvider 
        return new AutofacServiceProvider(AutofacContainer);
    }

上面代碼調(diào)用了builder的RegisterModule函數(shù),這個函數(shù)需要傳入一個TModule的泛型,稱之為autofac的模塊

模塊的功能就是把所有相關(guān)的注冊配置都放在一個類中,使代碼更易于維護和配置,下面展示了DefaultModuleRegister中的代碼

DefaultModuleRegister:

public class DefaultModuleRegister : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //注冊當(dāng)前程序集中以“Ser”結(jié)尾的類,暴漏類實現(xiàn)的所有接口,生命周期為PerLifetimeScope
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Ser")).AsImplementedInterfaces().InstancePerLifetimeScope();
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();
        //注冊所有"MyApp.Repository"程序集中的類
        //builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
    }

	public static Assembly GetAssembly(string assemblyName)
    {
        var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(AppContext.BaseDirectory + $"{assemblyName}.dll");
        return assembly;
    }
}

Configure函數(shù)中可以選擇性的加上程序停止時Autofac的釋放函數(shù):

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        //程序停止調(diào)用函數(shù)
        appLifetime.ApplicationStopped.Register(() => { AutofacContainer.Dispose(); });
    }

Controller中代碼:

  private IUserSer _user;
    private IUserSer _user2;
    public HomeController(IUserSer user, IUserSer user2)
    {
        _user = user;
        _user2 = user2;
    }
    public IActionResult Index()
    {
        using (var scope = Startup.AutofacContainer.BeginLifetimeScope())
        {
            IConfiguration config = scope.Resolve<IConfiguration>();
            IHostingEnvironment env = scope.Resolve<IHostingEnvironment>();
        }
        string name = _user.GetName();
        string name2 = _user2.GetName();
        return View();
    }

可以看到,因為我們將IServiceCollection中的服務(wù)填充到了autofac中了,所以現(xiàn)在可以在任何位置通過AutoFac解析出來.net core默認注入的服務(wù)(IConfiguration,IHostingEnvironment等)了

正常項目使用中,我們應(yīng)該將AutofacContainer放在一個公共的類庫中以便各個工程均可調(diào)用

到此這篇關(guān)于.Net Core 之AutoFac的使用的文章就介紹到這了,更多相關(guān).Net Core AutoFac內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

梨树县| 平度市| 甘德县| 花莲市| 高青县| 夏津县| 建昌县| 隆德县| 醴陵市| 汶上县| 连山| 虎林市| 理塘县| 三明市| 昭通市| 灵川县| 博爱县| 磐安县| 六盘水市| 南京市| 夏河县| 渭源县| 芦山县| 微山县| 婺源县| 台东县| 义马市| 余姚市| 茌平县| 岳西县| 澄城县| 吉隆县| 武安市| 商洛市| 洞头县| 方城县| 界首市| 陈巴尔虎旗| 清新县| 黄梅县| 琼结县|