Autofac入門と代替ASP.NET Core、ABP依存注入容器

12263 ワード

目次
  • Autofacの使用
  • 1、簡単な実践
  • 2、登録コンポーネント
  • 3,Lambda登録コンポーネント
  • 4,登録汎用
  • 5、属性注入
  • 6、解析サービス
  • 7、ライフサイクル
  • 8、インスタンス役割ドメイン
  • 9、Autofacその他の学習すべき知識
  • ASP.NET Core
  • 1、デフォルト依存注入
  • 2、Autofac
  • を使用
  • ABP
  • Autofac公式サイトのドキュメントアドレス:https://autofaccn.readthedocs.io/zh/latest/index.html
    本論文では,Autofacフレームワークを用いて依存注入などの操作をどのように完了するかについて述べ,理論に触れない.

    Autofacの使用


    私たちはいます.NET Coreコンソールプログラムでテストと実践を行います.

    1、簡単な実践


    まず、インタフェースと実装を追加します.
        public interface IMyService { }
    
        public class MyService : IMyService { }
    
    次に、Mainメソッドにコンテナを登録して構築します.
        class Program
        {
            private static IContainer Container;
            static void Main(string[] args)
            {
                //        
                var builder = new ContainerBuilder();
    
                //     
                builder.RegisterType().As();
                // ...
    
                //     
                Container = builder.Build();
            }
        }
    
    次のように使用できます.
            public static void Test()
            {
                //       
                using (ILifetimeScope scope = Container.BeginLifetimeScope())
                {
                    //     
                    IMyService myService = scope.Resolve();
                }
            }
    
    .AS()は、コンポーネントを露出させるためのサービスである.
    これがAutofacの簡単な使用です.以下では、より詳細な使用方法と実践について説明します.

    2、登録コンポーネント

    ContainerBuilderオブジェクトを介してコンポーネントを登録し、コンテナにどのコンポーネントがどのサービスを暴露したかを示した.コンポーネントの登録方法はいろいろありますが、反射法を使用して登録し、汎用パラメータを渡しました.
    .RegisterType()
    
    あるいはタイプ(Type)で注入する:
                builder.RegisterType(typeof(MyService)).As();
    			
    
    もちろん、登録されたコンポーネントを反射することで、対応する構造関数が自動的に注入されます.UsingConstructorメソッドを使用して、コンテナのコンポーネントのインスタンス化を要求するときに、どの構造関数を使用するかを指定することもできます.
    builder.RegisterType()
           .UsingConstructor(typeof(ILogger), typeof(IConfigReader));
    
    インスタンスを事前に登録することもできます.
                MyService t = new MyService();
    
                builder.RegisterInstance(t).As();
    
    これにより、単一のアプリケーションが生成されます.ただし、RegisterInstance(t)はtへの参照を保持するため、すなわち、このインスタンスをコンテナのインスタンスに登録する.
    もちろんLambda式ツリーを使用してnew:
                builder.Register(c => new MyService()).As();
    
    これにより、外部からの参照を回避できます.
    そうしたくない場合は、ExternallyOwnedメソッドを使用すると、新しいインスタンスがコンテナに生成されます.AutoMapperができると分かりやすいです.
                builder.RegisterInstance(t).As().ExternallyOwned();
    

    3,Lambda登録コンポーネント


    あるタイプのコンストラクション関数が別のインタフェースに依存する場合、このタイプはコンポーネントとして登録され、複雑になります.Lambda式を使用してコンポーネントを登録できます.
    次のインタフェースとタイプがあります.
        public interface IA { }
    
        public class A : IA { }
        public interface IB { }
    
        public class B : IB
        {
            private IA _a;
            public B(IA a)
            {
                _a = a;
            }
        }
    
    では、Aタイプを登録してから、Bタイプを登録することができます.
                builder.RegisterType().As();
    builder.Register(c => new B(c.Resolve()));
    もちろん、ここでは式を使って利便性を紹介します.このように使用することもできます.
                builder.RegisterType().As();
    builder.RegisterType().As();
    Bタイプをインスタンス化すると、自動的にコンストラクタが注入されます.

    4、汎用登録


    汎用タイプを登録する場合は、次の手順に従います.
        public interface IA { }
    
        public class A : IA { }
    
    RegisterGenericを使用して、汎用コンポーネントを登録できます.
                builder.RegisterGeneric(typeof(A<>)).As();
    
    もちろんIAも汎用型なら.As(typeof(IA))を使うべきです.

    5、属性注入


    コンポーネントを登録するときにPropertiesAutowiredメソッドを使用すると、コンテナはインスタンスを生成するときに属性を自動的に注入します.次のタイプがあります.
        public interface IA { }
    
        public class A : IA { }
        public interface IB { }
    
        public class B : IB
        {
            public IA A { get; set; }
        }
    
    登録:
                builder.RegisterType().As();
    builder.RegisterType().PropertiesAutowired().As();
    すると、コンテナは自動的にBタイプの属性に依存を注入します.
    もちろん、これにより、タイプの各属性に依存が注入されます.
    ある属性にのみ注入したい場合は、WithPropertyの方法を使用します.たとえば、次のようにします.
                builder.RegisterType().WithProperty("A",new A()).As();
    

    6、解析サービス


    コンポーネントを登録すると、Build()メソッドを呼び出してコンテナを生成します.次いで、Resolveの方法を使用して、そのライフサイクル内でサービスを解析する.
    前の例を参照してください.
                using (ILifetimeScope scope = Container.BeginLifetimeScope())
                {
                    //     
                    IMyService myService = scope.Resolve();
                }
    
    なお、インスタンスは、コンテナ(IContainer)からではなく、ライフサイクルから解析されます.サービスが登録されているかどうかを知りたい場合は、ResolveOptional()またはTryResolve()メソッドを使用します.
                using (ILifetimeScope scope = Container.BeginLifetimeScope())
                {
                    IB b;
                    //     
                    if (scope.TryResolve(out b))
                    {
                        
                    }
                }
    
    解析時にパラメータを渡すことで、コンテナ生成インスタンスを制御する際に、コンストラクション可能な関数を使用してタイプをインスタンス化できます.
    Autofacでは、さまざまなパラメータマッチングメカニズムが用意されています.
  • NamedParameter-名前でターゲットパラメータ
  • に一致
  • TypedParameter-タイプマッチングターゲットパラメータ(特定のタイプをマッチングする必要がある)
  • ResolvedParameter-柔軟なパラメータマッチング
  • 例は次のとおりです.
    namespace AutofacTest
    {
        public interface IA { }
    
        public class A : IA
        {
            public A(string a, string b) { Console.WriteLine($"a = {a}, b = {b}"); }
        }
        class Program
        {
            private static IContainer Container;
            static void Main(string[] args)
            {
                //        
                var builder = new ContainerBuilder();
                builder.RegisterType().As();
    //コンテナの  
    Container = builder.Build();
    Test();
    }
    public static void Test()
    {
    //ライフサイクル  
    using (ILifetimeScope scope = Container.BeginLifetimeScope())
    {
    IA b = scope.Resolve(new NamedParameter(「a」,「テスト」)new NamedParameter(「b」,「テスト」)
    }
    }
    }
    または、次のように変更します.
                    IA b = scope.Resolve(new TypedParameter(typeof(string), "  "), new TypedParameter(typeof(string), "  "));
    
    また、Autofacでは、次のようなさまざまな関係のサービス解析もサポートされています.
  • 直接依存(B)
  • 遅延インスタンス化(Lazy)
  • 制御可能ライフサイクル(Owned)
  • 動的インスタンス化(Func)
  • パラメータ付きインスタンス化(Func)
  • 遍歴型(IEnumerable,IList,ICollection)
  • メタデータレビュー(Metadata Interrogation(Meta,Meta))
  • キーイングサービスの検索(Keyed Service Lookup(Iundex))
  • 7、ライフサイクル


    ライフサイクルについては、次のように参照してください.https://autofaccn.readthedocs.io/zh/latest/lifetime/index.html
    前述したように、インスタンスを取得するには
    using (ILifetimeScope scope = Container.BeginLifetimeScope())
    {
    
    }
    
    BeginLifetimeScopeは、解放可能であり、コンポーネントの解放を追跡することができるライフサイクル役割ドメインを作成する.
    ライフサイクル放出は、Dispose()またはusing{}の形式で行うことができます.
    あなたもできます.
                using (ILifetimeScope scope = Container.BeginLifetimeScope())
                {
                    using (ILifetimeScope sc = scope.BeginLifetimeScope())
                    {
                    }
                }
    

    8、インスタンスの役割ドメイン


    インスタンスの役割ドメインは、露出した同じサービスのインスタンスが複数のリクエスト間でどのように共有されるかを決定する.コンポーネントの役割ドメインは、登録コンポーネントが決定した後、Resolve()が返される例を明示的に呼び出すと、具体的な動作(単一例など)が現れる.
    8.1依存インスタンス
    はい.NETのデフォルトの依存注入フレームワークでは、'transientまたはfactoryと呼ばれ、要求ごとに異なるインスタンスが返されます.Autofacのデフォルトはこのモードです.InstancePerDependencyの明示的な宣言も使用できます.
    builder.RegisterType().InstancePerDependency();
    
    8.2単一インスタンスSingleInstanceメソッドは、コンポーネントを単一のインスタンスとして登録することができる.
    builder.RegisterType().SingleInstance();
    
    8.3ライフサイクルの役割ドメインの例InstancePerLifetimeScopeを使用して、コンポーネントが1つのライフサイクルの役割ドメイン内に設定され、取得されたインスタンスは同じです.
    また、積層されたライフサイクルの役割ドメインも異なり、例えば以下の例ではTrue,Falseとなる.
                using (ILifetimeScope scope = Container.BeginLifetimeScope())
                {
                    IA b = scope.Resolve();
                    IA bb = scope.Resolve();
                    Console.WriteLine(b == bb);
                    using (ILifetimeScope sc = scope.BeginLifetimeScope())
                    {
    
                        IA bbb = sc.Resolve();
                        Console.WriteLine(b == bbb);
                    }
                }
    
    また、Autofacには他の方法の役割ドメイン管理もあります.リンクをクリックしてください.https://autofaccn.readthedocs.io/zh/latest/lifetime/instance-scope.html

    9,Autofacその他の学習すべき知識


    Autofacは非常に強力なフレームワークです.本稿では、入門の基礎部分を選んで説明します.他の自由度の高い複雑な知識点は、次のようなものです.
  • ライフサイクルイベント
  • ドキュメント学習を表示する必要があります.ここでは説明しません.

    ASP.NET Core


    ASP.NET Coreでは、2.xと3.xの差は比較的多く、ここでは3.xを例とします.

    1、デフォルト依存注入


    ASP.NET Coreでは、デフォルトの依存注入は、ConfigureServicesメソッドを使用して登録すればよい.
    例:
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddTransient();
            }
    

    2、Autofacの使用


    ASP.でNET CoreでAutofacを依存注入容器として使用する場合は、Microsoft.Extensions.DependencyInjection.AbstractionsというNugetパッケージを取り付ける必要があります.
    そしてプログラムのホストに
                   .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    
    例は次のとおりです.
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                   .UseServiceProviderFactory(new AutofacServiceProviderFactory())
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup();
                    });
    
    次にStartupクラスにConfigureContainerメソッドを追加し、このメソッドに必要なコンポーネントを登録します.
            public void ConfigureContainer(ContainerBuilder builder)
            {
                builder.RegisterType().As();
    }
    最後にConfiguraServicesメソッドに追加します.
    services.AddOptions();
    
    ASPとしてAutofacを使用できます.NET Coreは注入容器に依存する.
    完全なコード:
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddOptions();
                services.AddControllers();
            }
            public void ConfigureContainer(ContainerBuilder builder)
            {
                builder.RegisterType().As();
    }

    ABP


    まずASPを追加するように要求します.NET Coreプログラムは、ABPを構成し、対応するパッケージを導入します.参考になるhttps://docs.abp.io/zh-Hans/abp/latest/Getting-Started-AspNetCore-Application
    ABPでは、デフォルトでもConfigureServicesを使用して直接注入すればよい.使用例:
        public class AppModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {
                context.Services.AddTransient();
            }
        }
    
    
    context.Servicesは、IServiceCollectionのオブジェクトです.
    もちろんABPはAutofacを依存注入容器として使用することもできる.
    ABPでAutofacを使用するには、Volo.Abp.Autofacパッケージを参照する必要があります.
    次に、[DependsOn(typeof(AbpAutofacModule))]の特性をモジュールに追加する.
        [DependsOn(typeof(AbpAutofacModule))]
        public class AppModule : AbpModule{}
    
    次に、StartupのConfiguraServicesメソッドでABPモジュールを追加し、Autofacを使用するように設定します.
            public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddApplication(options=>
                {
                    options.UseAutofac();
                });
            }