Lind.DDD.Aspects dynamic interception of AOP in ~lind by means of plugins implementation

Source: Internet
Author: User

Back to Catalog

One important reason why. Net MVC has evolved is that it exposes a set of AOP filters that can be used to easily intercept action in a controller and inject our own code logic into global exception records, user authorization, URL authorization, Operation Behavior Records, and so on, this a large number of Lind basic components are implemented MVC and API filtering implementation, using these filters so that we do not like HttpModule and HttpHandler, but also to configure the injection point in config, so that the programmer in the development of the way to feel comfortable, Maintenance success is very low!

The main content points of this paper

    1. Method interceptors in the LIND.DDD
    2. Dynamic injection requires Lind.DDD.Plugins support
    3. 0 Method of configuration blocking
    4. A log blocker
    5. Building a cache Interceptor
Directory structure

Method interceptors in the LIND.DDD

Lind.DDD.Aspects This interceptor originated from the ABP framework, but do not know why, ABP to this interceptor is not fully implemented, so today the uncle realized a bit, solved the related bug, on the method interception, in the dynamic Agent factory in the method interception context Added some necessary parameters, because the uncle thought that you only provide a "method name" parameter, too simple, haha.

    /// <summary>    ///Method Related Information/// </summary>     Public classMethodmetadata {/// <summary>        ///Context/// </summary>        PrivateMethodInfo _context; /// <summary>        ///Method Name/// </summary>        Private string_methodname;  PublicMethodmetadata (stringMethodName, MethodInfo context =NULL) {_methodname=MethodName; _context=context; }        /// <summary>        ///Method Name/// </summary>         Public Virtual stringMethodName {Get{return_methodname;} Set{_methodname =value;} }        /// <summary>        ///Method Context/// </summary>         Public Virtual stringContext {Get{return_context;} Set{_context =value;} }    }

An implementation of a simple log interceptor, which is intercepted by method execution

     /// <summary>    ///method is intercepted before execution and logs are logged/// </summary>     Public classLoggeraspectattribute:beforeaspectattribute { Public Override voidAction (Invokecontext context) {Console.WriteLine ("Logger start!"+context.            Method.methodname); Lind.DDD.Logger.LoggerFactory.Instance.Logger_Info (context. Method.methodname+"This method starts to execute"); }    }

And in the program, this feature attribute how to be a dynamic proxy interception, event, if you can directly write code is also possible, is the use of aspect provided by the Proxyfactory factory to produce, but the uncle thought, such code coupling is too high, And for the existing code needs to be modified, the most important point, this code always feel a bad taste!

Static void Main (string[] args)        {            proxyfactory.createproxy<ITest> (typeof( Loggeraspecttest)). Do ();            Console.read ();        }

So we have the following Uncle's package, Use Lind.DDD.Plugins this plug-in mode, all the interceptors are first registered, and then in the production of objects for it to dynamically add the corresponding Proxyfactory object, please continue to look down, dynamic injection needs Lind.DDD.Plugins support this part of the explanation.

Dynamic injection requires Lind.DDD.Plugins support

The above interceptors are simple implementations, simple calls, without generality, that is, you need to maintain the "interception of code", and the uncle in the use of the feeling very uncomfortable, so think of plugins, let the plug-in for us to achieve this injection, like the MVC filter, in the framework itself to implement methods to intercept the function! Uncle thinks this is the best!

1 All interceptors inherit iaspectproxy to represent the interface, while it inherits the Iplugins

/// <summary>    /// An interface that supports AOP interception, which is considered a plug-in that is dynamically    injected into the system /// </summary>     Public Interface IAspectProxy:Lind.DDD.Plugins.IPlugins {}

2 in the Resolve method of PlugInManager, add dynamic proxyfactory implementation, so that the type of iaspectproxy is implemented, and the implementation of interceptor is implemented automatically.

        /// <summary>        ///returning objects from a plug-in container/// </summary>        /// <param name= "ServiceName" >Object Full Name</param>        /// <param name= "servicetype" >interface Type</param>        /// <returns></returns>         Public Static ObjectResolve (stringServiceName, Type servicetype) {            varobj =_container.            Resolvenamed (ServiceName, servicetype); if(typeof(Lind.DDD.Aspects.IAspectProxy). IsAssignableFrom (servicetype)) {obj=proxyfactory.createproxy (servicetype, obj.            GetType ()); }            returnobj; }

OK, with the above code, our method of interception is a plug-in, the use of the plug-in before the time used the same way, of course, the bottom is the use of AUTOFAC to implement the IOC container.

var old = lind.ddd.plugins.pluginmanager.resolve<iaophellotest2> ("  Lind.DDD.UnitTest.AopHello"); Old. Hello ("zz"1);
A log blocker

Logging is necessary for some business complex methods, such as some order method, the user withdrawal method will add related logs, and if you want to dynamically add the log, and not to add in the code snippet, you can design a log interceptor, of course, you can control the method execution, you can also control after the method execution!

 // <summary>    ///method is intercepted before execution and logs are logged/// </summary>     Public classLoggeraspectattribute:beforeaspectattribute { Public Override voidAction (Invokecontext context) {Console.WriteLine ("Logger start!"+context.            Method.methodname); Lind.DDD.Logger.LoggerFactory.Instance.Logger_Info (context. Method.methodname+"This method starts to execute"); }    }    /// <summary>    ///block after execution of the method and log/// </summary>     Public classLoggerendaspectattribute:afteraspectattribute { Public Override voidAction (Invokecontext context) {Console.WriteLine ("Logger start!"+context.            Method.methodname); Lind.DDD.Logger.LoggerFactory.Instance.Logger_Info (context. Method.methodname+"This method starts to execute"); }    }

The directory method needs to add the behavior of this log, as long as the corresponding attribute is added to the method, (the method does not need to be a virtual method) and does not need to modify the method code body, as in the following code

/// <summary>    ///     How AOP is called /// </summary>     Public class loggeraspecttest:itest    {        [loggeraspectattribute]        publicvoid do ()        {            //  I do things            Console.WriteLine (" I do things ");        }    }

Building a cache Interceptor

At present, the uncle is building a cache interceptor, mainly to implement a cache of the method return value, and do not need to write the logic of this cache judgment in each method body, the uncle thinks, this aspect-oriented AOP design, is the trend, please look forward to!

     /// <summary>    ///Cache Blocker/// </summary>     Public classCachingaspectattribute:beforeaspectattribute {Cachingmethod cachingmethod;  PublicCachingaspectattribute (Cachingmethod cachingmethod) { This. Cachingmethod =Cachingmethod; }         Public Override voidAction (Invokecontext context) {varMETHOD =context.            Method; stringprefix ="Lind"; varBaseinterfaces =context. GetType ().            Getinterfaces (); if(Baseinterfaces! =NULL&&Baseinterfaces.any ()) {                foreach(varIteminchbaseinterfaces) {prefix+ = Item. ToString () +"_"; }            }            //key names, used in put and get            varKey = prefix +method.            MethodName;            Console.WriteLine (key); Switch(cachingmethod) { CaseCachingmethod.remove://...                     Break;  CaseCachingmethod.get://...                     Break;  CaseCachingmethod.put://...                     Break; default:                    Throw NewInvalidOperationException ("Invalid cache mode. "); }        }    }

Our pursuit of support will not stop, I hope that the majority of young people can step on the heart, to seriously study a technology, in fact, a technical study thoroughly, the uncle think is enough!

Sincerely

Salute

Back to Catalog

Lind.DDD.Aspects dynamic interception of AOP in ~lind by means of plugins implementation

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.