In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail how to use dependency injection Autofac. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have some understanding of the relevant knowledge after reading this article.
Dependence inversion? Control inversion (IOC)? Dependency injection (DI)?
Are you still bothered by these nouns, or do you have little knowledge after reading a lot of theoretical articles?
Today I want to learn and summarize the use and understanding of dependency injection Autofac with my novice friends who are confused by the actual project.
Dependency injection rough understanding of dependencies: public class A {
Public void A (BB) {
/ / do something}}
It is estimated that there is no programmer who has not used such code.
Class A needs an object of B as an argument to the constructor when it is instantiated, so A depends on B, which is called dependency.
Of course, there is no need to construct a function to new a B within Class A. in fact, A depends on B as well.
Inject:
When you see the word "injection", is the syringe the first thing that comes to mind? Haha, still living in the shadow of childhood. Combine the "injection" scenario for a simple understanding of dependency injection.
Doctors use syringes (Autofac) to inject drugs (dependence = class objects) into blood vessels (other classes).
The basic use of Autofac building project
Create a MVC project and add Autofac directly through Nuget.
The injection class itself. AsSelf () public class TestController: Controller {
Private readonly InjectionTestService _ testService
Public TestController (InjectionTestService testService) {_ testService = testService;}
Public ActionResult Index () {ViewBag.TestValue = _ testService.Test ()
Return View ();} public class InjectionTestService: IService {public string Test () {return "Success";}}
Add the registration code of dependency injection to Global.asax
/ / create a container var builder = new ContainerBuilder (); / / register all Controllerbuilder.RegisterControllers (Assembly.GetExecutingAssembly ()); / / RegisterType: builder.RegisterType (). AsSelf (). InstancePerDependency (); / / Register: builder.Register (c = > new InjectionTestService ()). AsSelf (). InstancePerDependency () / / automatic injection without knowing the name of the specific class / * BuildManager.GetReferencedAssemblies () * collection of assemblies, including the assemblies specified in the assemblies element of the Web.config file, * assemblies generated from custom code in the App_Code directory, and assemblies in other top-level folders. * / get the assembly var assemblies = BuildManager.GetReferencedAssemblies () .Cast () .Where (assembly = > assembly.GetTypes () .FirstOrDefault (type = > type.GetInterfaces (). Contains (typeof (IService)! = null); / / RegisterAssemblyTypes registered assembly var enumerable = assemblies as Assembly []? Assemblies.ToArray ()
If (enumerable.Any ()) {builder.RegisterAssemblyTypes (enumerable) .Where (type = > type.GetInterfaces (). Contains (typeof (IService)). AsSelf (). InstancePerDependency ();} / / load the container into Microsoft's default dependency injection container var container = builder.Build (); DependencyResolver.SetResolver (new AutofacDependencyResolver (container)) Inject concrete classes into the interface .AsImplementedInterfaces () public class TestController: Controller {
Private readonly IService _ testService
Public TestController (IService testService) {_ testService = testService;} public ActionResult Index () {ViewBag.TestValue = _ testService.Test ()
Return View ();}} / / Register specifies the concrete class builder.Register (c = > new InjectionTestService ()). As () .InstancePerDependency (); / / RegisterType specifies the concrete class builder.RegisterType () .As () .InstancePerDependency () / / Auto-registration method / / get the assembly var assemblies = BuildManager.GetReferencedAssemblies () .Cast () .Where (assembly = > assembly.GetTypes () .FirstOrDefault (type = > type.GetInterfaces () .Contains (typeof (IService)! = null) that inherits the IService interface class / / RegisterAssemblyTypes registered assembly var enumerable = assemblies as Assembly []? Assemblies.ToArray ()
If (enumerable.Any ()) {builder.RegisterAssemblyTypes (enumerable) .Where (type = > type.GetInterfaces (). Contains (typeof (IService)). AsImplementedInterfaces (). InstancePerDependency ();} automatic injection of dependent classes using Named
Description of the requirements scenario:
There are three short message platforms A, B and C to provide short message service.
There are three implementation classes of SMS platform, AMessage,BMessage,CMessage.
The client selects different platforms to send text messages at different times.
Conventional and simple processing method
Create three new service classes, AMsgService,BMsgService,CMsgService.
On the client side, determine which short message platform to choose by if else, then new the service object, and then call the Send method to send the short message.
Shortcoming
If there is a new SMS platform D to join, you must create a new DSendMsgService, and then modify the client-side if else code.
Reform
Abstract the interface of an SMS platform public interface IMessage {
Decimal QueryBalance ()
Bool Send (string msg)
Int TotalSend (DateTime? StartDate, DateTime? EndDate);}
Concrete implementation class
[MessagePlatform (Enums.MPlatform.A platform)]
Public class ASendMessageService: IMessage {public decimal QueryBalance () {return 0;} public bool Send (string msg) {return true;} public int TotalSend (DateTime? StartDate, DateTime? EndDate) {return 100;}}
The class has a custom attribute tag MessagePlatform. What is this for? Is to make a tag to this class, combined with the use of Named, to achieve automatic injection.
Public class TestController: Controller {
Private Func _ factory
Public TestController (Func factory) {_ factory = factory;}
Public ActionResult Index () {
Var retult = _ factory ((int) Enums.MPlatform.A platform) .send ("screw you")
Return View (retult);}}
The constructor argument is actually a delegate of func?
If the input parameter of factory is an int (the enumerated value of the defined SMS platform), you can get the specific implementation class of the SMS platform.
Yes, autofac is so capricious.
Builder.RegisterType () .Named ((/ / get class custom attribute typeof (ASendMessageService) .GetCustomAttributes (typeof (MessagePlatformAttribute), false) .FirstOrDefault () as MessagePlatformAttribute) .platform.ToString () .InstancePerRequest () Builder.Register (c = > {var ic = c.Resolve (); return name = > ic.ResolveNamed (name.ToString ());})
Question:
The above only implements automatic injection for the ASendMessageService class, so what about BSendMessageService,CSendMessageService? it's impossible to copy a piece of injected configuration code, right?
Typeof (IMessage) .Assembly.GetTypes () .Where (t = > t.GetInterfaces () .Contains (typeof (IMessage) .ForEach (type = > {/ / Registration type})
If you have some implementation classes that are not under the IMessge assembly, you can't write this. You should adjust the code according to the specific project situation.
Summary
1. The purpose of dependency injection is to decouple.
two。 Do not rely on concrete classes, but rely on abstract classes or interfaces, which is called dependency inversion.
3. Control inversion is IoC (Inversion of Control), which transfers the call power of the object which is traditionally directly controlled by the program code to the container, and realizes the assembly and management of the object components through the container. The so-called concept of "control inversion" is the transfer of control over component objects, from the program code itself to the external container.
4. How Microsoft's DependencyResolver creates controller [follow-up study]
Autofac creates the lifecycle of a class
1 、 InstancePerDependency
Create a new and unique instance for each dependency or call. This is also the default way to create an instance.
Official document explanation: Configure the component so that every dependent component or call to Resolve () gets a new, unique instance (default.)
2 、 InstancePerLifetimeScope
In a lifecycle domain, each dependency or call creates a single shared instance, and for each different lifecycle domain, the instance is unique and not shared.
Official document explanation: Configure the component so that every dependent component or call to Resolve () within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances.
3 、 InstancePerMatchingLifetimeScope
In an identified lifecycle domain, each dependency or call creates a single shared instance. Instances in the parent domain can be shared in the child identity domain in the identified life cycle domain. If no marked life cycle domain is found throughout the inheritance hierarchy, an exception is thrown: DependencyResolutionException.
Official document explanation: Configure the component so that every dependent component or call to Resolve () within an ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent's instance. If no appropriately tagged scope can be found in the hierarchy an DependencyResolutionException is thrown.
4 、 InstancePerOwned
In the lifecycle of instance creation owned in a lifecycle domain, each dependent component or call the Resolve () method creates a single shared instance, and the child lifecycle domain shares the instance in the parent lifecycle domain. If no suitable lifecycle domain with child instances is found in the inheritance hierarchy, an exception is thrown: DependencyResolutionException.
Official document explanation: Configure the component so that every dependent component or call to Resolve () within an ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent's instance. If no appropriate owned instance scope can be found in the hierarchy an DependencyResolutionException is thrown.
5 、 SingleInstance
Each time you rely on a component or call the Resolve () method, you get the same shared instance. It's actually a singleton model.
Official document explanation: Configure the component so that every dependent component or call to Resolve () gets the same, shared instance.
6. InstancePerHttpRequest (InstancePerRequest is recommended for the new autofac)
Share a component instance in the context of an Http request. For asp.net mvc development only. Official document explanation: Share one instance of the component within the context of a single HTTP request. On how to use dependency injection Autofac to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.