Back to Catalog
Recently made a database read-write separation project, using the DbCommand Interceptor, in the program development process did not find any particular problem, and when the development is completed, in the testing phase, a chance to let me know, originally my interceptor injection not just injected once, Instead, each type of warehousing is injected once, and the problem is actually a serious one, and if your interceptor handles a lot of logic, it will be very performance-intensive.
Reason, static construction methods are not unique to generic classes, but are independent of each other
Public Abstract classDbcontextrepository<tentity>: Ispecificationrepository<TEntity>whereTEntity:class { #regionConstructors/// <summary> ///The static construction method is independent of each tentity, how many types of initialization, and how many times this method executes/// </summary> Staticdbcontextrepository () {//static construction methods for generic classes ...}}
As a result, when each type is initialized, a message is added to the Interceptor dictionary
New Backgroundrepositorybase<webmanageusers>(db); IRepositoryNew backgroundrepositorybase<webmanagemenus>(db); // each initialization, the static construction method will be executed
In fact, this is understandable, because the generic class itself is undefined, and when you initialize it, the specific type is only known when it is run, when it is first used, thestatic construction method of "This class" is executed, which is perfectly fine, and perhaps developers sometimes overlook it.
Resolve, use reflection to implement your own on-demand additions
/// <summary> ///DbCommand Interceptor Extension/// </summary> Public Static classdbcommandinterceptorextensions {/// <summary> ///Add the DbCommand interceptor to the Dbinterception static object as a single instance/// </summary> /// <param name= "action" ></param> Public Static voidUsingsingletoninterceptor (Dbcommandinterceptor Interceptor) {#regionSQL statement blocker, interceptors only load oncevarproperty =typeof(Dbcommanddispatcher). GetProperty ("Internaldispatcher", BindingFlags.Instance |bindingflags.nonpublic); if(Property! =NULL) { varval =Property . GetValue (System.Data.Entity.Infrastructure.Interception.DbInterception.Dispatch.Command); if(val! =NULL) { varList = val. GetType (). GetField ("_interceptors", BindingFlags.Instance |bindingflags.nonpublic); if(List! =NULL) { varListval = list. GetValue (Val) asList<system.data.entity.infrastructure.interception.idbcommandinterceptor>; if(Listval! =NULL) { if(Listval.firstordefault (i = i.tostring () = = Interceptor. GetType (). ToString ()) = =NULL) {System.Data.Entity.Infrastructure.Interception.DbInterce Ption. ADD (Interceptor); } } } } } #endregion } }
Call this very convenient
EntityFrameworks.Data.Core.Extensions.DbCommandInterceptorExtensions.UsingSingletonInterceptor (new Commandinterceptor ());
OK, so that each of our interceptors in the dbinterception object will only appear once, there will never be a interceptor is executed multiple times, hehe.
Back to Catalog
The foundation is the most serious-the static construction method of generic class can not be executed only once