当前位置:网站首页>Autofac details
Autofac details
2022-06-23 23:31:00 【Brother Li Yu】
Autofac Detailed explanation
zero 、 List of articles
One 、Autofac Detailed explanation
1、 summary
- Autofac Is the third party IOC Containers , It's the most popular IOC Containers .
- Powerful , Than asp.netcore Built in containers are much more powerful , Support attribute injection and method injection , Support AOP.
- Official website address :http://autofac.org/
- Source code download address :https://github.com/autofac/Autofac
2、 Quick start
(1)Nuget Bring in the package
Autofac Based on version 6.3 demonstration ,Net5
(2) Container creation object
// Create a container builder
ContainerBuilder containerBuilder = new ContainerBuilder();
// Registered general class
containerBuilder.RegisterType<Honer>();
//build once , Get a container
IContainer container = containerBuilder.Build();
// You can get instances of objects based on containers
Honer phone = container.Resolve<Honer>();
3、 Type of registration
(1) Registered general class
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>();
IContainer container = containerBuilder.Build();
Honer phone = container.Resolve<Honer>();
(2) Registration abstraction and implementation
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>();
IContainer container = containerBuilder.Build();
IPhone phone = container.Resolve<IPhone>();
(3) Register assembly
- RegisterAssemblyTypes( Assembly array ), Assembly must be public Of
- AsImplementedInterfaces(): Indicates the type of registration , Register as an interface
- PropertiesAutowired(): Support attribute Injection
- Where: Meet the condition type registration
var basePath = AppContext.BaseDirectory;
var dll = Path.Combine(basePath, "MyAutofac.dll");
ContainerBuilder containerBuilder = new ContainerBuilder();
var assemblysServices = Assembly.LoadFrom(dll);
containerBuilder.RegisterAssemblyTypes(assemblysServices)
.Where(t => !t.Name.EndsWith("XXX"))
.AsImplementedInterfaces()
.PropertiesAutowired();
IContainer container = containerBuilder.Build();
ITeacher teacher = container.Resolve<ITeacher>();

4、 Three injection methods
(1) Constructor injection
The default support , Cannot filter with attributes , By default, the constructor with the most parameters is selected for injection
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>();
containerBuilder.RegisterType<Teacher>().As<ITeacher>();
containerBuilder.RegisterType<Student>().As<IStudent>();
IContainer container = containerBuilder.Build();
ITeacher teacher = container.Resolve<ITeacher>();

(2) All attribute injection
key word
PropertiesAutowired, All the attributes of this object are injected
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>();
containerBuilder.RegisterType<Teacher>().As<ITeacher>().PropertiesAutowired();
containerBuilder.RegisterType<Student>().As<IStudent>();
IContainer container = containerBuilder.Build();
ITeacher teacher = container.Resolve<ITeacher>();

(3) Attribute injection of tag features
key word
PropertiesAutowired, Define the property selectorCustomPropertySelector
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>();
containerBuilder.RegisterType<Teacher>().As<ITeacher>().PropertiesAutowired(new CustomPropertySelector());
containerBuilder.RegisterType<Student>().As<IStudent>();
IContainer container = containerBuilder.Build();
ITeacher teacher = container.Resolve<ITeacher>();
public class CustomPropertySelector : IPropertySelector
{
public bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
var flag = propertyInfo.CustomAttributes.Any(it => it.AttributeType == typeof(SelectPropAttribute));
return flag;
}
}

(4) Methods to inject
key word
OnActivated, Specifies the calling method
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>();
containerBuilder.RegisterType<Teacher>().As<ITeacher>()
.OnActivated(p =>
{
p.Instance.SetStudent1(p.Context.Resolve<IStudent>());
});
containerBuilder.RegisterType<Student>().As<IStudent>();
IContainer container = containerBuilder.Build();
ITeacher teacher = container.Resolve<ITeacher>();

5、 Object lifecycle
(1) Instantaneous life cycle
Each acquisition is a new instance , key word
InstancePerDependency, The default life cycle
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().InstancePerDependency();
IContainer container = containerBuilder.Build();
IPhone phone1 = container.Resolve<IPhone>();
IPhone phone2 = container.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($"InstancePerDependency:phone1==phone2=>{isflg1}");
InstancePerDependency:phone1==phone2=>False
(2) Single instance life cycle
There is the same instance in the same process , key word
SingleInstance
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().SingleInstance();
IContainer container = containerBuilder.Build();
IPhone phone1 = container.Resolve<IPhone>();
IPhone phone2 = container.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($"SingleInstance:phone1==phone2=>{isflg1}");
using (var scope = container.BeginLifetimeScope())
{
IPhone phone3 = scope.Resolve<IPhone>();
IPhone phone4 = scope.Resolve<IPhone>();
bool isflg2 = object.ReferenceEquals(phone3, phone4);
Console.WriteLine($"SingleInstance:phone3==phone4=>{isflg2}");
bool isflg3 = object.ReferenceEquals(phone1, phone3);
Console.WriteLine($"SingleInstance:phone1==phone3=>{isflg3}");
}
SingleInstance:phone1==phone2=>True
SingleInstance:phone3==phone4=>True
SingleInstance:phone1==phone3=>True
(3) Scope lifecycle
There is the same instance in the same scope , key word
InstancePerLifetimeScope
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().InstancePerLifetimeScope();
IContainer container = containerBuilder.Build();
IPhone phone1 = container.Resolve<IPhone>();
IPhone phone2 = container.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($"InstancePerLifetimeScope:phone1==phone2=>{isflg1}");
IPhone phone3 = null;
IPhone phone4 = null;
using (var scope = container.BeginLifetimeScope())
{
phone3 = scope.Resolve<IPhone>();
phone4 = scope.Resolve<IPhone>();
bool isflg2 = object.ReferenceEquals(phone3, phone4);
Console.WriteLine($"InstancePerLifetimeScope:phone3==phone4=>{isflg2}");
bool isflg3 = object.ReferenceEquals(phone1, phone3);
Console.WriteLine($"InstancePerLifetimeScope:phone1==phone3=>{isflg3}");
}
IPhone phone5 = null;
IPhone phone6 = null;
using (var scope = container.BeginLifetimeScope())
{
phone5 = scope.Resolve<IPhone>();
phone6 = scope.Resolve<IPhone>();
bool isflg2 = object.ReferenceEquals(phone5, phone6);
Console.WriteLine($"InstancePerLifetimeScope:phone5==phone6=>{isflg2}");
bool isflg3 = object.ReferenceEquals(phone1, phone5);
Console.WriteLine($"InstancePerLifetimeScope:phone1==phone5=>{isflg3}");
}
bool isflg4 = object.ReferenceEquals(phone3, phone5);
Console.WriteLine($"InstancePerLifetimeScope:phone3==phone5=>{isflg4}");
InstancePerLifetimeScope:phone1==phone2=>True
InstancePerLifetimeScope:phone3==phone4=>True
InstancePerLifetimeScope:phone1==phone3=>False
InstancePerLifetimeScope:phone5==phone6=>True
InstancePerLifetimeScope:phone1==phone5=>False
InstancePerLifetimeScope:phone3==phone5=>False
(4) Scope scope lifecycle
Cannot create instance outside scope , Within the scope , Objects under the same scope are the same , key word
InstancePerMatchingLifetimeScope
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().InstancePerMatchingLifetimeScope("scope1", "scope2");
IContainer container = containerBuilder.Build();
IPhone phone1 = null;
IPhone phone2 = null;
using (var scope = container.BeginLifetimeScope("scope1"))
{
phone1 = scope.Resolve<IPhone>();
phone2 = scope.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($"InstancePerMatchingLifetimeScope:phone1==phone2=>{isflg1}");
}
IPhone phone3 = null;
using (var scope = container.BeginLifetimeScope("scope2"))
{
phone3 = scope.Resolve<IPhone>();
}
IPhone phone4 = null;
using (var scope = container.BeginLifetimeScope("scope2"))
{
phone4 = scope.Resolve<IPhone>();
}
bool isflg2 = object.ReferenceEquals(phone3, phone4);
Console.WriteLine($"InstancePerMatchingLifetimeScope:phone3==phone4=>{isflg2}");
bool isflg3 = object.ReferenceEquals(phone1, phone3);
Console.WriteLine($"InstancePerMatchingLifetimeScope:phone1==phone3=>{isflg3}");
InstancePerMatchingLifetimeScope:phone1==phone2=>True
InstancePerMatchingLifetimeScope:phone3==phone4=>False
InstancePerMatchingLifetimeScope:phone1==phone3=>False
(5) Request the same object at a time
key word
InstancePerRequest, Only in web Debugging in project , Console error
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().InstancePerRequest();
IContainer container = containerBuilder.Build();
IPhone phone1 = container.Resolve<IPhone>();
IPhone phone2 = container.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($"InstancePerRequest:phone1==phone2=>{isflg1}");
6、 Support profile registration
(1)nuget Import assembly
Autofac
Autofac.Configuration
Microsoft.Extensions.Configuration.Json
(2) The configuration file autofac.json, attribute -> Always copy
{
"components": [
{
// Realization
"type": "Net5.IOC.Honer,Net5.IOC",
// abstract
"services": [
{
"type": "Net5.IOC.IPhone,Net5.IOC"
}
],
// Life cycle
"instanceScope": "single-instance",
// Attribute injection
"injectProperties": true
}
]
}
(3) Create objects through configuration file registration
ContainerBuilder containerBuilder = new ContainerBuilder();
IConfigurationBuilder config = new ConfigurationBuilder();
IConfigurationSource autofacJsonConfigSource = new JsonConfigurationSource()
{
Path = "Autofac/autofac.json",
Optional = false,//boolean, The default is false, Don't write
ReloadOnChange = true,// ditto
};
config.Add(autofacJsonConfigSource);
ConfigurationModule module = new ConfigurationModule(config.Build());
containerBuilder.RegisterModule(module);
IContainer container = containerBuilder.Build();
IPhone phone1 = container.Resolve<IPhone>();
IPhone phone2 = container.Resolve<IPhone>();
bool isflg1 = object.ReferenceEquals(phone1, phone2);
Console.WriteLine($" Profile registration :phone1==phone2=>{isflg1}");
(4) Running results
Profile registration :phone1==phone2=>True
7、 Support AOP Faceted programming
You can... Without modifying the method , Add common logic before and after methods , journal , abnormal , Cache, etc
(1)nuget Import assembly
Castle.Core
Autofac.Extras.DynamicProxy
(2) Customize an aspect class implementation IInterceptor Interface
public class CustomInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(" Before method execution ...");
// Execute the current method
invocation.Proceed();
Console.WriteLine(" After method execution ...");
}
}
(3) In the abstract / Add attribute tags to the implementation class
[Intercept(typeof(CustomInterceptor))]
public interface IPhone
{
string ShowName();
}
// Implement class virtual methods
public class Honer : IPhone
{
public virtual string ShowName()
{
Console.WriteLine("Honer");
return "Honer";
}
}
(4) Register the relationship creation object in the container
- EnableInterfaceInterceptors + Feature tags are abstract , All implementation classes support AOP
- EnableInterfaceInterceptors + Attributes are marked on the implementation class , Tagged classes support AOP
- EnableClassInterceptors, To support AOP The method must be used virtual Virtual method
- EnableClassInterceptors + Feature tags are abstract , All implementation classes support AOP
- EnableClassInterceptors + Attributes are marked on the implementation class , Tagged classes support AOP
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().As<IPhone>().EnableInterfaceInterceptors();
containerBuilder.RegisterType(typeof(CustomInterceptor));
IContainer container = containerBuilder.Build();
IPhone phone = container.Resolve<IPhone>();
phone.ShowName();
(5) Running results
Before method execution ...
Honer
After method execution ...
8、 Single abstract multiple implementation problem
(1) Register the relationship creation object in the container
Do not mark your name when registering , Those registered later will overwrite those registered earlier
Mark your name when you register , When creating objects, use names to distinguish
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Honer>().Named<IPhone>("Honer");
containerBuilder.RegisterType<Huawei>().Named<IPhone>("Huawei");
IContainer container = containerBuilder.Build();
IPhone honer = container.ResolveNamed<IPhone>("Honer");
IPhone huawei = container.ResolveNamed<IPhone>("Huawei");
honer.ShowName();
huawei.ShowName();
(2) Running results
Honer
Huawei
9、 Integrated into the Asp.NetCore5 frame
(1)nuget Import assembly
Autofac
Autofac.Extensions.DependencyInjection
(2) Define implementation classes and abstractions
public class UserService : IUserService
{
private IUserRepository UserRepositoryCtor { get; set; }
public UserService(IUserRepository userRepository)
{
UserRepositoryCtor = userRepository;
}
public string Login(string username, string password)
{
return " Login successful ";
}
}
(3) Add controllers and pages
public class FourthController : Controller
{
private IUserService _userService;
public FourthController(IUserService userService)
{
this._userService = userService;
}
public IActionResult Index()
{
object result = this._userService.Login("username", "password");
return View(result);
}
}
@model String
<h2>this is fourth index...</h2>
<h2>@Model</h2>
(4) stay Program Replace container factory
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
}
(5) stay Startup Class ConfigureServices Method to replace the class that creates the controller
// By default, the controller has IControllerActivator Created , Replace with created by the container
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
(6) Register the relationship between abstraction and implementation
stay
StartupAdd a method to the classConfigureContainer, Used to register abstractions and implement , These registration information can be modularized and encapsulated intoAutofacModuleWhen there are many abstract classes and implementations , You can put the whole dll register , The special relationship can be written later to cover the previous registration relationship .
/// <summary>
/// Autofac special : Register the relationship between abstraction and detail , Use autofac The original built-in registration relationship should be commented out
/// Autofac and ServiceCollection It is the coexistence of the two ,Autofac Will take over ServiceCollection Everything
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule<AutofacModule>();
}
public class AutofacModule : Module
{
/// <summary>
/// rewrite Autofac In the pipe Load Method , Inject registered content here
/// </summary>
/// <param name="builder"></param>
protected override void Load(ContainerBuilder builder)
{
// Registration abstraction and implementation
builder.RegisterType<UserRepository>().As<IUserRepository>();
builder.RegisterType<UserService>().As<IUserService>();
// Register all controller classes
var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
// Implement attribute Injection , Method injection cannot be implemented here
builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
}
}
(7) Running results


(8) stay Startup Of Configure Method to create objects with containers
using (var container = host.Services.CreateScope())
{
IUserService userService = container.ServiceProvider.GetService<IUserService>();
}

(9) Single abstract multi implementation integration into framework
When injecting, inject through constructor or attribute autofac Context instance , Then create the corresponding instance according to the name .
Define single abstract and multi instance classes
// abstract
public interface ITestService
{
string Show();
}
// Realization 1
public class TestServiceA : ITestService
{
public string Show()
{
return "TestServiceA";
}
}
// Realization 2
public class TestServiceB : ITestService
{
public string Show()
{
return "TestServiceB";
}
}
stay
AutofacModuleRegister the relationship between abstraction and implementation
// Single abstract multi implementation registration
builder.RegisterType<TestServiceA>().Named<ITestService>("a");
builder.RegisterType<TestServiceB>().Named<ITestService>("b");
Add controllers and pages
public class FifthController : Controller
{
private IComponentContext _componentContext;
public FifthController(IComponentContext componentContext)
{
this._componentContext = componentContext;
}
public IActionResult Index()
{
ITestService testServiceA = _componentContext.ResolveNamed<ITestService>("a");
ITestService testServiceB = _componentContext.ResolveNamed<ITestService>("b");
object result = $"{testServiceA.Show()}--{testServiceB.Show()}";
return View(result);
}
}
@model String
<h2>this is Fifth index...</h2>
<h2>@Model</h2>
Running results

边栏推荐
- 云原生流水线工具汇总
- Deserialization - PHP deserialization
- 不同网络结构的特征也能进行对比学习?蚂蚁&美团&南大&阿里提出跨架构自监督视频表示学习方法CACL,性能SOTA!...
- Common core resource objects of kubernetes
- HDLBits-&gt;Circuits-&gt;Arithmetic Circuitd-&gt;3-bit binary adder
- AIX系统月维护查什么(二)
- Fabric.js 手动加粗文本iText
- Docker中部署Redis集群与部署微服务项目的详细过程
- 《阿里云天池大赛赛题解析》——O2O优惠卷预测
- Installation and use of qingscan scanner
猜你喜欢
随机推荐
WebService client request failed can not create a secure xmlinputfactory
SQL语句中EXISTS的详细用法大全
What is an applet container
Troubleshooting of undefined problems in the channel list of easynvr channel management
Micro build low code tutorial - Application creation
企业网站的制作流程是什么?设计和制作一个网站需要多长时间?
Urgent! Tencent cloud container security supports the detection of Apache log4j2 vulnerabilities for the first time. It is in free trial
MySQL事務隔離
PLC数据操作系列之构造不同应用场景的缓存栈FIFO(算法详解)
生鲜前置仓的面子和里子
Payment industry tuyere project: smart digital operation 3.0
百万消息量IM系统技术要点分享
巨头下场“摆摊”,大排档陷入“苦战”
The latest February activity # 1 core 2G first year: 38 yuan / year! 2-core 4G light weight RMB 74 / year! Mysql database 19.9 yuan / year!!
数据解读!理想L9冲刺「月销过万」,从BBA手中抢份额
Come on, touch and write a hook
Fabric.js 手动加粗文本iText
Map集合的四种遍历
远程办公之:如何成为时间管理大师?| 社区征文
HDLBits-&gt; Circuits-&gt; Arithmetic Circuitd-&gt; 3-bit binary adder






