An elegant conditional method for referencing third-party. NET libraries

Source: Internet
Author: User

1. Problems encountered

This year I've been developing a webapiclient library that is designed to be as easy as Java's retrofit to request HTTP interfaces from the server. In this age of RESTful APIs, JSON is everywhere, and the. NET Framework naturally has a JSON library, System.Web.Script.Serialization.JavaScriptSerializer is one of them, but the comprehensive better, or third-party json.net. During the development of the webapiclient process, I've never relied on json.net because if my webapiclient relies on json.net version 6.0, a third-party library Thirdlib relies on a json.net version of 7.0, and Webapiclient and Thirdlib are not available in the project because They rely on the json.net version of the different and conflict, it is very troublesome for users to solve.

2. Desired Effect

The effect I expect is that if a project referencing the Webapiclient library is used to json.net, then Webapiclient uses json.net when JSON is serialized, otherwise using. Net The System.Web.Script.Serialization.JavaScriptSerializer of the framework. This requires me to develop webapiclient, not directly referencing json.net to develop, only at runtime to detect whether the application domain has loaded json.net, and thus reflect call json.net to serialize.

The effect is like this.

/// <summary>///deserializing Objects/// </summary>/// <param name= "JSON" >JSON</param>/// <param name= "ObjType" >Object Type</param>/// <returns></returns> Public ObjectDeserialize (stringjson, Type ObjType) {    if(string. IsNullOrEmpty (JSON)) {return NULL; }    if(jsonnet.issupported = =true)    {        returnJsonnet.deserializeobject (JSON, objType); }    varSerializer =NewSystem.Web.Script.Serialization.JavaScriptSerializer (); returnSerializer. Deserialize (JSON, objType);}

3. Solution

Detects whether the application domain has loaded json.net at run time, thus reflecting call json.net for serialization.

Difficulties in the implementation:

1, if the detection is loaded json.net

2, after the detection, only load json.net how to do

3, how to reduce the performance of reflection loss

Difficult to solve:

1. Use the AppDomain.CurrentDomain.GetAssemblies () method to get the currently loaded assembly of the current program domain, and determine whether there is a json.net assembly;

2, listen to the AppDomain.CurrentDomain.AssemblyLoad event, subscribe to the newly loaded assembly is json.net assembly;

3, the Newtonsoft.Json.JsonConvert SerializeObject and Deserializeobject method to generate a strongly typed delegate, cache up and wait for the call;

Complete code implementation:

usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Reflection;usingSystem.Text;usingSystem.Threading.Tasks;namespacewebapiclient{/// <summary>    ///provides json.net no reference calls/// </summary>    Static classjsonnet {/// <summary>        ///json.net assembly name/// </summary>        Private Static ReadOnly stringJsonnetassemblyname ="Newtonsoft.json"; /// <summary>        ///JsonConvert class name/// </summary>        Private Static ReadOnly stringJsonnetjsonconverttypename ="Newtonsoft.Json.JsonConvert"; /// <summary>        ///delegate of the serialization method/// </summary>        Private Staticfunc<Object,string> Serializefunc =NULL; /// <summary>        ///delegate for deserialization method/// </summary>        Private Staticfunc<string, Type,Object> Deserializefunc =NULL; /// <summary>        ///Get support/// </summary>         Public Static BOOLissupported =false; /// <summary>        ///json.net/// </summary>        Staticjsonnet () {AppDomain.CurrentDomain.AssemblyLoad+ = (s, e) = =initjsonnet (e.loadedassembly);        Initjsonnet (AppDomain.CurrentDomain.GetAssemblies ()); }        /// <summary>        ///Serializing Objects/// </summary>        /// <param name= "obj" >Object</param>        /// <returns></returns>         Public Static stringSerializeObject (Objectobj) {            returnJsonNet.serializeFunc.Invoke (obj); }        /// <summary>        ///Deserializing Objects/// </summary>        /// <param name= "JSON" >JSON text</param>        /// <param name= "type" >Object Type</param>        /// <returns></returns>         Public Static ObjectDeserializeobject (stringjson, type type) {            returnJsonNet.deserializeFunc.Invoke (JSON, type); }        /// <summary>        ///Initialize Json.NET/// </summary>        /// <param name= "assemblies" >the found Assembly</param>        Private Static voidInitjsonnet (paramsassembly[] Assemblies) {            if(jsonnet.issupported = =true)            {                return; }            varjsonnetassembly =assemblies. FirstOrDefault (Item=item. GetName ().            Name.equals (Jsonnetassemblyname, stringcomparison.ordinalignorecase)); if(jsonnetassembly = =NULL)            {                return; }            varJsonconverttype = Jsonnetassembly.gettype (Jsonnetjsonconverttypename,false); if(Jsonconverttype = =NULL)            {                return; } Serializefunc=Createserializeobjectfunc (Jsonconverttype); Deserializefunc=Createdeserializeobjectfunc (Jsonconverttype); Jsonnet.issupported= Serializefunc! =NULL&& Deserializefunc! =NULL; }        /// <summary>        ///to create a delegate for the SerializeObject method/// </summary>        /// <param name= "ClassType" >JsonConvert Type</param>        /// <returns></returns>        Private Staticfunc<Object,string>Createserializeobjectfunc (Type ClassType) {varmethod = Classtype.getmethod ("SerializeObject",New[] {typeof(Object) }); if(Method = =NULL)            {                return NULL; }            return(func<Object,string>) method. CreateDelegate (typeof(func<Object,string>)); }        /// <summary>        ///to create a delegate for the Deserializeobject method/// </summary>        /// <param name= "ClassType" >JsonConvert Type</param>        /// <returns></returns>        Private Staticfunc<string, Type,Object>Createdeserializeobjectfunc (Type ClassType) {varmethod = Classtype.getmethod ("Deserializeobject",New[] {typeof(string),typeof(Type)}); if(Method = =NULL)            {                return NULL; }            return(func<string, Type,Object>) method. CreateDelegate (typeof(func<string, Type,Object>)); }    }}

About Webapiclient

This is a HttpClient client project that allows you to describe what to do, rather than how you request it, and you will see a bright, get-to-new idea.

Github:https://github.com/xljiulang/webapiclient

An elegant conditional method for referencing third-party. NET libraries

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.