1. 程式人生 > 其它 >AutoFac 生命週期管理

AutoFac 生命週期管理

技術標籤:Autofacc#ioc

 public void ConfigureContainer(ContainerBuilder containerBuilder)
        {
            #region 指定控制器由AutoFac 進行例項獲取
            var assembly = this.GetType().GetTypeInfo().Assembly;
            var builder = new ContainerBuilder();

            //新建Mvc管理程式集填入當前程式集 
            var manager = new ApplicationPartManager();
            manager.ApplicationParts.Add(new AssemblyPart(assembly));
            manager.FeatureProviders.Add(new ControllerFeatureProvider());
            var feature = new ControllerFeature();
            manager.PopulateFeature(feature);

            //建立單例並且允許屬性注入
            builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
            builder.RegisterTypes(feature.Controllers.Select(t => t.AsType()).ToArray()).PropertiesAutowired();
            #endregion


            
            //瞬時生命週期 每次獲取例項不一樣
            containerBuilder.RegisterType<ServiceA>().As<IServiceA>().InstancePerDependency();
            //單例 整個容器獲取例項都是同一個
            containerBuilder.RegisterType<ServiceB>().As<IServiceB>().SingleInstance();
          
            //作用域生命週期 只有在相同作用域下獲取到的服務例項才相同
            containerBuilder.RegisterType<ServiceC>().As<IServiceC>().InstancePerLifetimeScope();
            //匹配作用域生命週期 精確到某個作用域
            containerBuilder.RegisterType<ServiceD>().As<IServiceD>().InstancePerMatchingLifetimeScope("MyScope");
            //某個請求生命週期 不同請求獲取的服務例項不一樣
            containerBuilder.RegisterType<ServiceE>().As<IServiceE>().InstancePerRequest();
            // 隱式關聯型別建立巢狀的生命週期範圍

            containerBuilder.RegisterType<ServiceG>().InstancePerOwned<IServiceF>();
            containerBuilder.RegisterType<ServiceF>().Keyed<IServiceF>("ServiceF1");


            var container = containerBuilder.Build();
            var serviceA1 = container.Resolve<IServiceA>();
            var serviceA2 = container.Resolve<IServiceA>();
            Console.WriteLine("ServiceA1 和 serviceA2 是否相同" +ReferenceEquals(serviceA1,serviceA2));

            var serviceB1 = container.Resolve<IServiceB>();
            var serviceB2 = container.Resolve<IServiceB>();
            Console.WriteLine("ServiceB1 和 serviceB2 是否相同" + ReferenceEquals(serviceB1, serviceB2));

            using var scope1 = container.BeginLifetimeScope("scope1");
            var serviceC1 = scope1.Resolve<IServiceC>();
            var serviceC2 = scope1.Resolve<IServiceC>();
            Console.WriteLine("ServiceC1 和 serviceC2 是否相同" + ReferenceEquals(serviceC1, serviceC2));

            using var scope2 = container.BeginLifetimeScope("scope2");
            var serviceC3 = scope2.Resolve<IServiceC>();
            Console.WriteLine("ServiceC1 和 serviceC3 是否相同" + ReferenceEquals(serviceC1, serviceC3));
            scope1.Dispose();
            scope2.Dispose();

            using var myScope = container.BeginLifetimeScope("MyScope");
            var serviceD1 = myScope.Resolve<IServiceD>();
            var serviceD2 = myScope.Resolve<IServiceD>();
            Console.WriteLine("ServiceD1 和 serviceD2 是否相同" + ReferenceEquals(serviceD1, serviceD2));

            var serviceF1 = myScope.ResolveKeyed<Owned<IServiceF>>("ServiceF1");
            serviceF1.Value.Call();
            serviceF1.Value.Call2();
        }
  1. InstancePerDependency() 瞬時生命週期 每次獲取例項不一樣
  2. SingleInstance() 單例 整個容器獲取例項都是同一個
  3. InstancePerLifetimeScope() 作用域生命週期 只有在相同作用域下獲取到的服務例項才相同
  4. InstancePerMatchingLifetimeScope("MyScope") 匹配作用域生命週期 精確到某個作用域
  5. InstancePerRequest() 某個請求生命週期 不同請求獲取的服務例項不一樣

以上5點就不細說了,有很多詳細的教程和解讀了。關鍵來看最後一個,主要程式碼抽取出來

{
            containerBuilder.RegisterType<ServiceG>().InstancePerOwned<IServiceF>();
            containerBuilder.RegisterType<ServiceF>().Keyed<IServiceF>("ServiceF1");
            var serviceF1 = myScope.ResolveKeyed<Owned<IServiceF>>("ServiceF1");
            serviceF1.Value.Call();
            serviceF1.Value.Call2();
}
{
    public class ServiceF : IServiceF
    {
        public ServiceF(ServiceG serviceG)
        {
            ServiceG = serviceG;
            Console.WriteLine(this.GetType().Name+"已經被初始化");
        }

        public ServiceG ServiceG { get;}

        public void Call()
        {
            Console.WriteLine(this.GetType().Name + "Call");
        }

        public void Call2()
        {
            ServiceG.Call();
        }
    }
}
{
    public class ServiceG:IServiceG
    {
        public void Call()
        {
            Console.WriteLine(this.GetType().Name + "Call");
        }

        public ServiceG()
        {
            Console.WriteLine(this.GetType().Name + "已經被初始化");
        }
    }
}

執行結果如下

呼叫順序是ServiceG先被初始化,然後是初始化ServiceF。ServiceG和ServiceF的生命週期應該是相同的。

個人理解如下

containerBuilder.RegisterType<ServiceG>().InstancePerOwned<IServiceF>(); 這行程式碼將ServiceG的生命週期限定在了ServiceF的生命週期之下,如果提前釋放ServiceF的的生命週期,那麼ServiceG中的服務應該也無法使用。

但目前關於InstancePerOwned的文件並不多,而且很模糊。如果理解有誤,望大佬指教一下。