C # uses Autofac to implement inversion of control IoC and aspect oriented programming AOP

Autofac is a very excellent IOC container (the most efficient container under. net) with excellent performance under. net. With AOP, it is even more powerful. The AOP of Autofac is implemented through the core part of the Castle (also a container) project, called Autofac Extras. DynamicProxy, as its name implies, is implemented as a dynamic proxy.

It is easy to use. First create a new console project, and then search Autofac on Nuget Aop and install it in the following order:

Or install through the command:

 Install-Package Autofac. Aop

After successful installation, several references will be added to the project, as shown below:

1. Create interceptor

 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; // Search Autofac on Nuget first Aop installation
 using Castle. DynamicProxy; namespace AutofacDEMO { ///  <summary>
     /// Interceptor needs to implement IInterceptor interface Intercept method ///  </summary>
     public  class LogInterceptor : IInterceptor { ///  <summary>
         /// Intercept method prints the name and parameters of the intercepted method before execution and the returned result after execution ///  </summary>
         ///  <param name="invocation"> Include information about intercepted methods </param>
         public  void Intercept(IInvocation invocation) { Console. WriteLine( " Before method execution: the parameter of intercepting method {1} under {0} class is {2} " , invocation. InvocationTarget. GetType(), invocation. Method. Name, string .Join( " , " , invocation. Arguments. Select(a => (a ?? "" ). ToString()). ToArray())); // Continue execution after the intercepted method is completed
 invocation. Proceed(); Console. WriteLine( " Method execution completed, return result: {0} " , invocation. ReturnValue); Console. WriteLine(); } } }
View Code

2. Create interception container

 var builder = new ContainerBuilder();

3.  Register interceptor to Autofac container

Interceptors must be registered in the Aufofac container, and can be injected through interceptor type or name. These two methods will make the methods of using interceptors different         

 // Naming injection builder. Register(c => new LogInterceptor()). Named<IInterceptor>( " log-calls " ); // Type injection builder. Register(c => new LogInterceptor());
//Or builder. RegisterType
<LogInterceptor>();

4. Enable interceptor

There are two main methods to enable interceptors: EnableInterfaceInterceptors () and EnableClassInterceptors ().

The EnableInterfaceConnectors method will dynamically create an interface proxy

The EnableClassInterceptors method will create a subclass proxy class of the target class, It should be noted here that only virtual methods will be intercepted , override method

Note: Autofac Extras. DynamicProxy2 can only use the above two methods

 // Enable class proxy interception // Method 1: Add attribute to the type builder. RegisterType<Student> (). EnableClassInterceptors(); // Method 2: Dynamically inject interceptors when registering types to containers (remove attribute attributes on types) builder. RegisterType<Teacher>(). InterceptedBy( typeof (LogInterceptor)). EnableClassInterceptors(); // Enable interface proxy interception // Method 1: Add attribute to the type builder. RegisterType<Man>(). As<IPerson> (). EnableInterfaceInterceptors(); // Method 2: Dynamically inject interceptors when registering types to containers (remove attribute attributes on types) builder. RegisterType<Man>(). As<IPerson>(). InterceptedBy( typeof (LogInterceptor)). EnableInterfaceInterceptors();

5. Specify the type to intercept

There are two methods:

The first is to add attribute to the type

Second: dynamically inject interceptors when registering types to containers

 // Dynamic injection interceptor builder. RegisterType<Student>(). InterceptedBy(typeof(LogInterceptor)) .EnableClassInterceptors();

6. The test results are as follows

The first type: class proxy interception

 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; using Autofac. Extras. DynamicProxy2; namespace AutofacDEMO { ///  <summary>
     /// Inherit the interface, implement the method, and add attribute to the type ///  </summary> [Intercept( typeof (LogInterceptor))] public  class Student { public  string Name; public Teacher Teacher; public Subject Subject; ///  <summary>
         /// Must be a virtual method ///  </summary>
         public  virtual  void Say() { Console. WriteLine( " You are calling Say method! Student Name: " + Name); } } [Intercept( typeof (LogInterceptor))] public  class Teacher { ///  <summary>
         /// Must be a virtual method ///  </summary>
         public  virtual  void Show() { Console. WriteLine( " I am Teacher's class ! " ); } } public  class Subject { ///  <summary>
         /// Must be a virtual method ///  </summary>
         public  virtual  void Show() { Console. WriteLine( " I am Subject's class ! " ); } } }
View Code
 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; using Autofac; using Autofac. Extras. DynamicProxy2; namespace AutofacDEMO { class Program { static  void Main( string [] args) { // There are two main methods to enable interceptors: EnableInterfaceInterceptors () and EnableClassInterceptors () // The EnableInterfaceConnectors method will dynamically create an interface proxy // The EnableClassInterceptors method will create a subclass proxy class of the target class. Note that it will only intercept virtual methods and override methods // Note: Autofac Extras. DynamicProxy2 can only use the above two methods
             #region Enable class proxy interception // Create interception container
             var builder = new ContainerBuilder(); // Register interceptor to container builder. RegisterType<LogInterceptor> (); // Method 1: Add attribute to the type builder. RegisterType<Student> (). EnableClassInterceptors(); builder. RegisterType <Teacher> (). EnableClassInterceptors(); // Method 2: Dynamically inject interceptors when registering types to containers (remove attribute attributes on types) // builder. RegisterType<Teacher>(). InterceptedBy(typeof(LogInterceptor)). EnableClassInterceptors(); // builder. RegisterType<Student>(). InterceptedBy(typeof(LogInterceptor)). EnableClassInterceptors(); // Attribute injection builder. Register(c => new Student { Teacher = c.Resolve<Teacher>(), Subject = new Subject(), Name = " Zhang San " }); using ( var container = builder. Build()) { // Get object from container
                 var Student = container. Resolve<Student> (); Student. Say(); Student. Subject. Show(); Student. Teacher. Show();               } Console. ReadLine(); #endregion       } } }
View Code

Second: Interface proxy interception

 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; namespace AutofacDEMO { ///  <summary>
     /// Define an interface ///  </summary>
     public  interface IPerson { void Say( string Name); } }
View Code
 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; using Autofac. Extras. DynamicProxy2; namespace AutofacDEMO { ///  <summary>
     /// Inherit the interface, implement the method, and add attribute to the type ///  </summary> [Intercept( typeof (LogInterceptor))] public  class Man: IPerson { public  string Age; public  void Say( string Name) { Console. WriteLine( " Men call Say method! full name: " + Name + " , Age: " + Age); } } ///  <summary>
     /// Inherit the interface, implement the method, and add attribute to the type ///  </summary> [Intercept( typeof (LogInterceptor))] public  class Woman : IPerson { public  void Say( string Name) { Console. WriteLine( " Women call Say method! full name: " + Name); } } ///  <summary>
     /// Management ///  </summary>
     public  class PersonManager { IPerson _Person; ///  <summary>
         /// Create objects dynamically based on the passed in type ///  </summary>
         ///  <param name="ds"></param>
         public PersonManager(IPerson Person) { _Person = Person; } public  void Say( string Name) { _Person. Say(Name); } } }
View Code
 using System; using System. Collections. Generic; using System. Linq; using System. Text; using System. Threading. Tasks; using Autofac; using Autofac. Extras. DynamicProxy2; namespace AutofacDEMO { class Program { static  void Main( string [] args) { // There are two main methods to enable interceptors: EnableInterfaceInterceptors () and EnableClassInterceptors () // The EnableInterfaceConnectors method will dynamically create an interface proxy // The EnableClassInterceptors method will create a subclass proxy class of the target class. Note that it will only intercept virtual methods and override methods // Note: Autofac Extras. DynamicProxy2 can only use the above two methods
             #region Enable interface proxy interception (recommended) // Create interception container
             var builder2 = new ContainerBuilder(); // Register interceptor to container builder2.RegisterType<LogInterceptor> (); // Constructor injection (as long as the caller passes in the object that implements the interface, the object creation is implemented, in the following two ways) builder2.RegisterType<PersonManager> (); // Method 1: Add attribute to the type // Attribute injection builder2.Register<Man>(c => new Man { Age = " twenty " }). As<IPerson> (). EnableInterfaceInterceptors(); // builder2.RegisterType<Man>(). As<IPerson>(). EnableInterfaceInterceptors(); builder2.RegisterType<Woman>(). Named<IPerson>( " Woman " ). EnableInterfaceInterceptors(); // Method 2: Dynamically inject interceptors when registering types to containers (remove attribute attributes on types) // builder2.RegisterType<Man>(). As<IPerson>(). InterceptedBy(typeof(LogInterceptor)). EnableInterfaceInterceptors(); // builder2.RegisterType<Woman>(). Named<IPerson>("Woman"). InterceptedBy(typeof(LogInterceptor)). EnableInterfaceInterceptors();
             using ( var container = builder2.Build()) { // Get object from container
                 var Manager = container. Resolve<PersonManager> (); Manager. Say( " administrators " ); var Person = container. Resolve<IPerson> (); Person. Say( " Zhang San " ); var Woman = container. ResolveNamed<IPerson>( " Woman " ); Woman. Say( " Wang Meng " ); } Console. ReadLine(); #endregion             } } }
View Code

Autofac has three life cycles: InstancePerLifetimeScope, SingleInstance and InstancePerDependency

InstancePerLifetimeScope: The objects generated by the same Lifetime are the same instance

SingleInstance: Single instance mode. Each call will use the same instantiated object; Use the same object every time;

InstancePerDependency: the default mode. Objects will be re instantiated every time they are called; Create a new object for each request

 // Method 2: dynamically inject interceptors when registering types to containers (remove attribute attributes on types) builder. RegisterType<Man>(). As<IPerson>(). InterceptedBy( typeof (LogInterceptor)). InstancePerLifetimeScope (). EnableInterfaceInterceptors();

See the following operation result diagram

1、InstancePerLifetimeScope 

2、SingleInstance

3、InstancePerDependency

AsImplementedInterfaces () is injected in the form of interfaces. All public interfaces of these classes are injected as services (except for releasing resources)

builder . RegisterAssemblyTypes Registers eligible types in an assembly

 Assembly assembly = Assembly. Load(assemblyName); // Assembly assembly = this. GetType(). GetTypeInfo(). Assembly; builder. RegisterAssemblyTypes (assembly). Where(type => !type.IsInterface && !type.IsSealed && ! type. IsAbstract && type. Name. EndsWith( " BLL " , StringComparison. OrdinalIgnoreCase)) .AsImplementedInterfaces() .InstancePerLifetimeScope() .EnableInterfaceInterceptors() .InterceptedBy( typeof (LogInterceptor));

each RegisterAssemblyTypes() Call will only apply one set of rules - if you want to register multiple components of different groups, you need to call multiple times RegisterAssemblyTypes()

posted @ 2018-12-05 15:14   virtue comes first   Reading( nine thousand one hundred and forty Comments( two edit   Collection   report