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,靈活運用就可以了,沒有什麼特別的知識點,就是要熟練應用。