Autofac依賴注入

簡介

  • Autofac 是一款超贊的.NET IoC 容器 . 它管理類之間的依賴關係, 從而使 應用在規模及複雜性增長的情況下依然可以輕易地修改 .它的實現方式是將常規的.net類當做 組件 處理.
  • 引用
    Autofac

註冊的組件方式

概念

  • 通過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,這裡每個組件都要通過這個來進行註冊。尤其是一些業務服務,他是不確定的。如果要將其封裝起來,這無疑是很龐大和不易管理的。如下:
    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,靈活運用就可以了,沒有什麼特別的知識點,就是要熟練應用。
Tags: