Autofac依赖注入

Posted ccaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Autofac依赖注入相关的知识,希望对你有一定的参考价值。

简介

  • Autofac 是一款超赞的.NET IoC 容器 . 它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改 .它的实现方式是将常规的.net类当做 组件 处理.
  • 引用
    技术图片

注册的组件方式

概念

  • 通过ContainerBuilder来注册组件且告诉容器哪些组件暴露了哪些服务.
    -每个组件暴露一个或多个服务 ,他们使用 ContainerBuilder 上的 As() 方法连接起来.
public void Register(ContainerBuilder builder,ITypeFinder typeFinder)
{
      builder.RegisterType<ConsoleLogger>().As<ILogger>();
      //通过类型注册
      builder.RegisterType(typeof(ConfigReader));
      //实例组件
      builder.RegisterInstance(NopEngine).As<IEngine>().SingleInstance();
      //Lambda表达式组件
      builder.Register(c => new DefaultDapperContext("数据库连接字符串", DataProvider.mysql)).InstancePerLifetimeScope();
      //开放泛型
      builder.RegisterGeneric(typeof(NHibernateRepository<>))
       .As(typeof(IRepository<>))
       .InstancePerLifetimeScope();
      //程序集扫描
      var dataAccess = Assembly.GetExecutingAssembly();
      builder.RegisterAssemblyTypes(dataAccess)
       .Where(t => t.Name.EndsWith("Repository"))
       .AsImplementedInterfaces();
}

  • 当使用基于反射的组件时, Autofac 自动为你的类从容器中寻找匹配拥有最多参数的构造方法.
  • 当使用RegisterType时候,不能注册一个抽象类/接口组件,其中在背后。Autofac其实是创建了一个你注册对象的实例. 你无法 "new up" 一个抽象类或一个接口.
  • 实例组件:提前生成一个对象的实例并将它加入容器以供注册组件时使用
  • 接收包含一个或多个程序集的数组作为参数. 默认地, 程序中所有具体的类都将被注册. 包括内部类(internal)和嵌套的私有类. 你可以使用LINQ表达式过滤注册的类型集合.

实战

  • 在开发过程中我们会遇到很多的注册,如Nop中的类DependencyRegistrar,这里每个组件都要通过这个来进行注册。尤其是一些业务服务,他是不确定的。如果要将其封装起来,这无疑是很庞大和不易管理的。如下:
    技术图片
    所以我们不如通过程序集的扫描。
    首先定义IDependencyRegistrar类
 /// <summary>
    /// 依赖注册接口定义 实现此接口可以使用autofac依赖注入
    /// </summary>
    public interface IDependencyRegistrar
    {
        /// <summary>
        /// 注册服务或接口
        /// </summary>
        /// <param name="builder">ContainerBuilder对象</param>
        /// <param name="typeFinder">类型查找器 </param>
        /// <param name="config">配置参数</param>
        void Register(ContainerBuilder builder, ITypeFinder typeFinder, NetProOption config);

        /// <summary>
        ///依赖注册执行顺序 从小到大执行
        /// </summary>
        int Order { get; }
    }

其次,实现接口

  /// <summary>
    /// Dependency registrar
    /// </summary>
    public class DependencyRegistrar : IDependencyRegistrar
    {
        /// <summary>
        /// Register services and interfaces
        /// </summary>
        /// <param name="builder">Container builder</param>
        /// <param name="typeFinder">Type finder</param>
        /// <param name="config">Config</param>
        public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
        {
            //普通注册
            builder.RegisterType<ShipStationService>().As<IShipStationService>().InstancePerLifetimeScope();
            //这里通过程序集扫描
            builder.RegisterAssemblyTypes(typeFinder.GetAssemblies()
				.Where(r => RegexHelper.IsMatch(r.GetName().Name,"模式字符串").ToArray())
			 .Where(t => t.Name.EndsWith("Service"))
        }

        /// <summary>
        /// Order of this dependency registrar implementation
        /// </summary>
        public int Order => 2;
    }

注册依赖项

        /// <summary>
        /// Register dependencies
        /// </summary>
        /// <param name="containerBuilder">Container builder</param>
        /// <param name="nopConfig">Nop configuration parameters</param>
        public virtual void RegisterDependencies(ContainerBuilder containerBuilder, NopConfig nopConfig)
        {
            //register engine
            containerBuilder.RegisterInstance(this).As<IEngine>().SingleInstance();

            //register type finder
            containerBuilder.RegisterInstance(_typeFinder).As<ITypeFinder>().SingleInstance();

            //find dependency registrars provided by other assemblies
            var dependencyRegistrars = _typeFinder.FindClassesOfType<IDependencyRegistrar>();

            //create and sort instances of dependency registrars
            var instances = dependencyRegistrars
                .Select(dependencyRegistrar => (IDependencyRegistrar)Activator.CreateInstance(dependencyRegistrar))
                .OrderBy(dependencyRegistrar => dependencyRegistrar.Order);

            //register all provided dependencies
            foreach (var dependencyRegistrar in instances)
                dependencyRegistrar.Register(containerBuilder, _typeFinder, nopConfig);
        }

总结:

  • 深入了解Autofac,灵活运用就可以了,没有什么特别的知识点,就是要熟练应用。





以上是关于Autofac依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

依赖注入之AutoFac

Autofac 依赖注入框架

WebAPI2使用AutoFac依赖注入完整解决方案。

AutoFac实现程序集级别的依赖注入

ASP.NETCore使用AutoFac依赖注入

Autofac依赖注入