/// <summary> /// Returns assembly from cache if it's present. If not CacheMiss event is invoked and return argument /// is pushed to the cache /// </summary> public Assembly GetOrAdd() { //First try memory cache layer Assembly ass = MemoryCache.Get(Key); if (ass != null) { return(ass); } //It wasn't found in memory cache, check the file ass = CompiledAssemblyCache.CheckCacheForAssembly(wsdlLocation, ContentHash); if (ass != null)// there was hit, save it to memory cache { MemoryCache.Add(Key, ass); } else { //Nothing in file cache, call cache miss event if (cacheMiss != null) { ass = cacheMiss(AbsoluteWsdlLocation, WsdlContent); if (ass != null) { MemoryCache.Add(Key, ass); //rename temporary assembly in order to cache it for later use CompiledAssemblyCache.RenameTempAssembly(ass.Location, wsdlLocation, ContentHash); } } } return(ass); }
///// <summary> ///// Clears the cache. ///// </summary> ///// <param name="wsdlLocation">WSDL location.</param> //internal static void ClearCache(string wsdlLocation) //{ // // clear the cached assembly file for this WSDL // try // { // string path = GetLibTempPath(); // //string path = Path.GetTempPath(); // string newFilename = path + GetMd5Sum(wsdlLocation) + CodeConstants.TEMPDLLEXTENSION; // File.Delete(newFilename); // } // catch (Exception ex) // { // //can't delete cache, just leave a notification file so the next time assembly is regenerated // throw new TemporaryCacheException("Problem occured when trying to clear temporary local assembly cache for WSDL: " + wsdlLocation + ".", ex); // } //} ///// <summary> ///// Clears all cached DLLs. ///// </summary> //internal static void ClearAllCached() //{ // string path = GetLibTempPath(); // DirectoryInfo di = new DirectoryInfo(path); // FileInfo[] dllFiles = di.GetFiles("*" + CodeConstants.TEMPDLLEXTENSION); // foreach (FileInfo fi in dllFiles) // { // try // { // fi.Delete(); // } // catch (Exception ex) // { // throw new TemporaryCacheException("Problem occurred when trying to clear temporary local assembly cache.", ex); // } // } //} /// <summary> /// Renames the temp assembly. /// </summary> /// <param name="pathToAssembly">Path to assembly.</param> /// <param name="name">New name for the assembly</param> /// <param name="hash">Hash from content of the wsdl file.</param> internal static void RenameTempAssembly(string pathToAssembly, string name, int hash) { string path = Path.GetDirectoryName(pathToAssembly); string newFilename = path + @"\" + CompiledAssemblyCache.GetMd5Sum(name) + "#" + hash.ToString("x16") + CodeConstants.TEMPDLLEXTENSION; try { File.Copy(pathToAssembly, newFilename); } catch { //do nothing } }
///// <summary> ///// Clears the cache. ///// </summary> ///// <param name="wsdlLocation">WSDL location.</param> //public static void ClearCache(string wsdlLocation) //{ // CompiledAssemblyCache.ClearCache(wsdlLocation); //} ///// <summary> ///// Clear all cached DLLs. ///// </summary> //public static void ClearAllCached() //{ // CompiledAssemblyCache.ClearAllCached(); //} /// <summary> /// Builds the assembly from WSDL. /// </summary> /// <param name="absoluteWsdlLocation">Absolute path to wsdl file.</param> /// /// <param name="wsdlContent">Actual content of wsdl file</param> /// <returns>Assembly containg proxy for service defined in <paramref name="absoluteWsdlLocation"/></returns> private Assembly BuildAssemblyFromWsdl(string absoluteWsdlLocation, string wsdlContent) { // Use an XmlTextReader to get the Web Service description StringReader wsdlStringReader = new StringReader(wsdlContent); XmlTextReader tr = new XmlTextReader(wsdlStringReader); ServiceDescription.Read(tr); tr.Close(); // WSDL service description importer CodeNamespace cns = new CodeNamespace(CodeConstants.CODENAMESPACE); sdi = new ServiceDescriptionImporter(); //sdi.AddServiceDescription(sd, null, null); // check for optional imports in the root WSDL CheckForImports(absoluteWsdlLocation); sdi.ProtocolName = protocolName; sdi.Import(cns, null); // change the base class // get all available Service classes - not only the default one ArrayList newCtr = new ArrayList(); foreach (CodeTypeDeclaration ctDecl in cns.Types) { if (ctDecl.BaseTypes.Count > 0) { if (ctDecl.BaseTypes[0].BaseType == CodeConstants.DEFAULTBASETYPE) { newCtr.Add(ctDecl); } } } foreach (CodeTypeDeclaration ctDecl in newCtr) { cns.Types.Remove(ctDecl); ctDecl.BaseTypes[0] = new CodeTypeReference(CodeConstants.CUSTOMBASETYPE); cns.Types.Add(ctDecl); } // source code generation CSharpCodeProvider cscp = new CSharpCodeProvider(); StringBuilder srcStringBuilder = new StringBuilder(); StringWriter sw = new StringWriter(srcStringBuilder, CultureInfo.CurrentCulture); if (schemas != null) { foreach (XmlSchema xsd in schemas) { if (XmlSchemas.IsDataSet(xsd)) { MemoryStream mem = new MemoryStream(); mem.Position = 0; xsd.Write(mem); mem.Position = 0; DataSet dataSet1 = new DataSet(); dataSet1.Locale = CultureInfo.InvariantCulture; dataSet1.ReadXmlSchema(mem); SDD.TypedDataSetGenerator.Generate(dataSet1, cns, cscp); } } } cscp.GenerateCodeFromNamespace(cns, sw, null); proxySource = srcStringBuilder.ToString(); sw.Close(); // assembly compilation string location = ""; if (HttpContext.Current != null) { location = HttpContext.Current.Server.MapPath("."); location += @"\bin\"; } CompilerParameters cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Xml.dll"); cp.ReferencedAssemblies.Add("System.Web.Services.dll"); cp.ReferencedAssemblies.Add("System.Data.dll"); cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); cp.GenerateExecutable = false; cp.GenerateInMemory = false; cp.IncludeDebugInformation = false; cp.TempFiles = new TempFileCollection(CompiledAssemblyCache.GetLibTempPath()); CompilerResults cr = cscp.CompileAssemblyFromSource(cp, proxySource); if (cr.Errors.Count > 0) { throw new DynamicCompilationException(string.Format(CultureInfo.CurrentCulture, @"Building dynamic assembly failed: {0} errors", cr.Errors.Count)); } Assembly compiledAssembly = cr.CompiledAssembly; return(compiledAssembly); }