[Lazy] implementing Assembly injection in asp.net core, asp. netcore

Source: Internet
Author: User

[Lazy] implementing Assembly injection in asp.net core, asp. netcore

 

Preface in asp.net core, I have introduced DI containers. We can easily implement dependency injection without using third-party plug-ins. The following code: 1 // This method gets called by the runtime. use this method to add services to the container. 2 public void ConfigureServices (IServiceCollection services) 3 {4 // services. registerAssembly ("IServices"); 5 services. addSingleton <IUserService, UserService> (); 6 // Add framework services. 7 services. addMvc (); 8 services. addMvcCore () 9. addApiExplorer (); 10 services. addSwaggerGen (options => 11 {12 options. swaggerDoc ("v1", new Info () 13 {14 Title = "Swagger test", 15 Version = "v1", 16 Description = "Swagger test RESTful API ", 17 TermsOfService = "None", 18 Contact = new Contact19 {20 Name = "", 21 Email = "xxoo123@outlook.com" 22}, 23 }); 24 // set the xml annotation document. Note that the name must be the same as the project name 25 var filePath = Path. combine (PlatformServices. default. application. applicationBasePath, "WebApi. xml "); 26 options. includeXmlComments (filePath); 27}); 28}View Code

 

However, with the expansion of the company's business, the functional modules of the system project have expanded dramatically, adding no more than or thousands of Repository and services (a bit exaggerated ...), at this time, it would be a bit cool to simply inject drops. Can I use reflection technology to inject an assembly ?? Try it. First, I will formulate some class name constraints without permission. The rules are set by yourself. For example:
  • UserService --> IUserService
  • UserRepository --> IUserRepository
  • ......
  • ClassName --> IClassName
Now let's start encoding: 1 /// <summary> 2 /// IServiceCollection extension 3 /// </summary> 4 public static class ServiceExtension 5 {6 /// <summary> 7 // implementation classes in the DI batch Injection Interface set. 8 /// <para> 9 /// note that the following conventions exist: 10 // IUserService --> UserService, IUserRepository --> UserRepository.11 /// </para> 12 /// </summary> 13 /// <param name = "service"> </param> 14 // <param name = "interfaceAssemblyName"> name of the interface assembly (excluding the file extension) </param> 15 // <returns> </returns> 16 public static IServiceCollection RegisterAssembly (this IServiceCollection service, string interfaceAssemblyName) 17 {18 if (servi Ce = null) 19 throw new ArgumentNullException (nameof (service); 20 if (string. isNullOrEmpty (interfaceAssemblyName) 21 throw new ArgumentNullException (nameof (interfaceAssemblyName); 22 23 var assembly = RuntimeHelper. getAssembly (interfaceAssemblyName); 24 if (assembly = null) 25 {26 throw new DllNotFoundException ($ "the dll \" {interfaceAssemblyName} \ "not be found "); 27} 28 29 // filter out non-interface and generic interface 30 var types = Assembly. GetTypes (). Where (t => t. GetTypeInfo (). IsInterface &&! T. getTypeInfo (). isGenericType); 31 32 foreach (var type in types) 33 {34 var implementTypeName = type. name. substring (1); 35 var implementType = RuntimeHelper. getImplementType (implementTypeName, type); 36 if (implementType! = Null) 37 service. addSingleton (type, implementType); 38} 39 return service; 40} 41 42 // <summary> 43 // The implementation class corresponding to the DI batch Injection Interface set. 44 // </summary> 45 // <param name = "service"> </param> 46 // <param name = "interfaceAssemblyName"> name of the interface assembly (excluding the file extension) </param> 47 // <param name = "implementAssemblyName"> name of the implementation assembly (excluding the file extension) </param> 48 // <returns> </returns> 49 public static IServiceCollection RegisterAssembly (this IServiceCollection service, string interfaceAssemblyName, string implementAssemblyName) 50 {51 if (service = null) 52 throw ne W ArgumentNullException (nameof (service); 53 if (string. isNullOrEmpty (interfaceAssemblyName) 54 throw new ArgumentNullException (nameof (interfaceAssemblyName); 55 if (string. isNullOrEmpty (implementAssemblyName) 56 throw new ArgumentNullException (nameof (implementAssemblyName); 57 58 var interfaceAssembly = RuntimeHelper. getAssembly (interfaceAssemblyName); 59 if (interfaceAssembly = null) 60 {61 throw n Ew DllNotFoundException ($ "the dll \" {interfaceAssemblyName} \ "not be found"); 62} 63 64 var implementAssembly = RuntimeHelper. getAssembly (implementAssemblyName); 65 if (implementAssembly = null) 66 {67 throw new DllNotFoundException ($ "the dll \" {implementAssemblyName} \ "not be found "); 68} 69 70 // filter out non-interface and generic interface 71 var types = interfaceAssembly. getTypes (). where (t => t. getTypeInfo (). isInterface &&! T. getTypeInfo (). isGenericType); 72 73 foreach (var type in types) 74 {75 // filter out abstract classes, generic classes, and non-class76 var implementType = implementAssembly. definedTypes77. firstOrDefault (t => t. isClass &&! T. IsAbstract &&! T. IsGenericType & 78 t. GetInterfaces (). Any (B => B. Name = type. Name); 79 if (implementType! = Null) 80 {81 service. AddSingleton (type, implementType. AsType (); 82} 83} 84 85 return service; 86} 87}View Code

The code for RuntimeHelper. cs is attached:

1 public class RuntimeHelper 2 {3 // <summary> 4 // obtain the project assembly and exclude all system assembly (Microsoft. * **, System. * **, etc.), Nuget download Package 5 /// </summary> 6 /// <returns> </returns> 7 public static IList <Assembly> GetAllAssemblies () 8 {9 var list = new List <Assembly> (); 10 var deps = DependencyContext. default; 11 var libs = deps. compileLibraries. where (lib =>! Lib. Serviceable & lib. Type! = "Package"); // exclude all system assembly and Nuget download package 12 foreach (var lib in libs) 13 {14 try15 {16 var assembly = AssemblyLoadContext. default. loadFromAssemblyName (new AssemblyName (lib. name); 17 list. add (assembly); 18} 19 catch (Exception) 20 {21 // ignored22} 23} 24 return list; 25} 26 27 public static Assembly GetAssembly (string assemblyName) 28 {29 return GetAllAssemblies (). firstOrDefault (assembly => assembly. fullName. C Ontains (assemblyName); 30} 31 32 public static IList <Type> GetAllTypes () 33 {34 var list = new List <Type> (); 35 foreach (var assembly in GetAllAssemblies () 36 {37 var typeInfos = assembly. definedTypes; 38 foreach (var typeInfo in typeInfos) 39 {40 list. add (typeInfo. asType (); 41} 42} 43 return list; 44} 45 46 public static IList <Type> GetTypesByAssembly (string assemblyName) 47 {48 var list = new List <Typ E> (); 49 var assembly = AssemblyLoadContext. default. loadFromAssemblyName (new AssemblyName (assemblyName); 50 var typeInfos = assembly. definedTypes; 51 foreach (var typeInfo in typeInfos) 52 {53 list. add (typeInfo. asType (); 54} 55 return list; 56} 57 58 public static Type GetImplementType (string typeName, Type baseInterfaceType) 59 {60 return GetAllTypes (). firstOrDefault (t => 61 {62 if (t. name = typeName & 63 t. getTypeInfo (). getInterfaces (). any (B => B. name = baseInterfaceType. name) 64 {65 var typeInfo = t. getTypeInfo (); 66 return typeInfo. isClass &&! TypeInfo. IsAbstract &&! TypeInfo. IsGenericType; 67} 68 return false; 69}); 70} 71}View Code

Okay, this is basically done. Remember to add the following to Startup. cs:

1 // This method gets called by the runtime. use this method to add services to the container. 2 public IServiceProvider ConfigureServices (IServiceCollection services) 3 {4 services. registerAssembly ("IServices"); 5 services. configure <MemoryCacheEntryOptions> (6 options => options. absoluteExpirationRelativeToNow = TimeSpan. fromMinutes (5); // set the cache validity period to 5 minutes. 7 8 // Add framework services. 9 services. AddMvc (); 10 11 return services. BuilderInterceptableServiceProvider (builder => builder. SetDynamicProxyFactory (); 12}View Code

 

To sum up, note that a good memory is worse than a bad pen.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.