Example #1
0
        /// <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);
        }