其他分享
首页 > 其他分享> > .NET Core 中依赖注入框架详解 Autofac

.NET Core 中依赖注入框架详解 Autofac

作者:互联网

本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的

Autofac相比.NET Core原生的注入方式提供了强大的功能,详细可以查看Autofac官方API

(1)首先看第一个例子 控制台应用(.NET Core)

通过Nuget安装两个包 => Autofac Autofac.Extensions.DependencyInjection

 public static class Demo
{ 
        public interface IAccount { }
        public interface IMessage { }
        public interface ITool { }
        public class Base : IDisposable
        {
            public Base()
            {
                Console.WriteLine($"{GetType().Name} Created");
            }

            public void Dispose()
            {
                Console.WriteLine($"{GetType().Name} Disposed");
            }
        }
        public class Account : Base, IAccount { }
        public class Message : Base, IMessage { }
        public class Tool : Base, ITool { }

        public static void Run()
        {
            //.NET Core 服务集合
            var serviceCollection = new ServiceCollection()
                .AddTransient<IAccount, Account>()
                .AddTransient<IMessage, Message>();
 
            var containerBuilder = new ContainerBuilder();
            //将服务集合添加到Autofac
            containerBuilder.Populate(serviceCollection);
            //通过类型注册将服务添加到Autofac 
            containerBuilder.RegisterType().As();

            var container =  containerBuilder.Build();
            IServiceProvider provider = new AutofacServiceProvider(container);
            Debug.Assert(provider.GetService() is Account);

        }
}
View Code

那么使用Autofac有哪些其它优势?下面看看 属性注入和程序集注入

public static class Demo
    {
        public interface IAccount { }
        public interface IMessage { }
        public interface ITool { }
        public interface ITest { public IMessage Message { get; set; } }

        public class Base 
        {
            public Base()
            {
                Console.WriteLine($"{GetType().Name} Created");
            }

        }
        public class Account : Base, IAccount { }
        public class Message : Base, IMessage { }
        public class Tool : Base, ITool { }
        public class Test : Base, ITest
        {
            public IMessage Message { get; set; }
            public Test(IAccount account, ITool tool)
            {
                Console.WriteLine($"Ctor : Test(IAccount, ITool)");
            }
        }

        public static void Run()
        {
            //.NET Core 服务集合
            //var serviceCollection = new ServiceCollection()
            //    .AddTransient<ITool, Tool>();

            var containerBuilder = new ContainerBuilder();
            //将服务集合添加到Autofac
            //containerBuilder.Populate(serviceCollection);
            //属性注入
            containerBuilder.RegisterType<Test>().As<ITest>().PropertiesAutowired();
            //程序集注入
            containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .Where(t => t.BaseType == typeof(Base))
                .As(t => t.GetInterfaces()[0])//调用As方法,暴露服务
                .InstancePerLifetimeScope();//每个生命周期作用域的组件在每个嵌套的生命周期作用域中最多只会有一个单一实例


            var container = containerBuilder.Build();
            IServiceProvider provider = new AutofacServiceProvider(container);
            Debug.Assert(provider.GetService<IAccount>() is Account);
            Debug.Assert(provider.GetService<IMessage>() is Message);
            Debug.Assert(provider.GetService<ITool>() is Tool);

            var test = provider.GetService<ITest>();
            Debug.Assert(test.Message is Message);


        }
View Code

(2)ASP.NET Core 内置DI 与 Autofac 比较

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddTransient<IAccount, Account>();
        }
View Code

内置DI 在Startup类 ConfigureServices通过AddTransient方式注册

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
            .UseServiceProviderFactory(new AutofacServiceProviderFactory());
View Code
Startup.cs 
// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            //services.AddTransient<IAccount, Account>();//内置DI
        }

        public void ConfigContainer(ContainerBuilder containerBuilder)
        {
            //containerBuilder.RegisterType<Account>().As<IAccount>();
            var assembly = Assembly.GetEntryAssembly();
            containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .Where(t => t.BaseType == typeof(Base))
                .As(t => t.GetInterfaces()[0])
                .InstancePerLifetimeScope();
                
        }
View Code

Autofac 需要在Program.cs中替换 .NET Core的默认容器 UseServiceProviderFactory(new AutofacServiceProviderFactory())

在 Startup.cs 中 创建ConfigContainer方法,服务注册和 控制台应用相似;

真正在实际项目中按照以上方式注册服务会很麻烦,难以维护,可读性差;Autofac提供了一种以模块化方式进行注册

比如我们有不同的业务模块 AModule BModule...,将这些module继承 Autofac.Module 重写Load方法进行服务注册

最后在ConfigContainer中RegisterModule进行模块化注册

public class AModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            var containerBaseType = typeof(ControllerBase);

            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .Where(t => containerBaseType.IsAssignableFrom(t) && t != containerBaseType)
                .PropertiesAutowired();
        }
    }


public void ConfigContainer(ContainerBuilder containerBuilder)
        {
            
            containerBuilder.RegisterModule<AModule>();
                
        }

 

标签:Core,Autofac,class,public,Base,containerBuilder,NET
来源: https://www.cnblogs.com/louiszh/p/14121707.html