private TDslBase CreateInternal <TDslBase>(ScriptNotFoundBehavior notFoundBehavior, string url, object[] parameters) { DslEngine engine = GetEngine <TDslBase>(); Type type = null; engine.Cache.ReadLock(delegate { type = engine.Cache.Get(engine.CanonizeUrl(url)); if (type == null) { bool recompilation; string[] urls = GetUrls(engine, ref url, out recompilation); bool existsInArray = engine.Storage.IsUrlIncludeIn(urls, BaseDirectory, url); if (existsInArray == false) { if (notFoundBehavior == ScriptNotFoundBehavior.Throw) { throw new InvalidOperationException("Could not find DSL script: " + url); } return; } CompilerContext compilerContext; try { compilerContext = engine.Compile(urls); } catch (Exception) { // if we fail to compile with batch, we will try just the current url urls = new string[] { url }; compilerContext = engine.Compile(urls); } Assembly assembly = compilerContext.GeneratedAssembly; RegisterBatchInCache(engine, urls, assembly); //find the type that we searched for //we may have a race condition with the cache, so we force //it to go through the assemly instead of the cache type = engine.GetTypeForUrl(assembly, url); RaiseCompilationEvent(recompilation); } }); if (type == null) { return(default(TDslBase)); } return((TDslBase)engine.CreateInstance(type, parameters)); }
private void RegisterBatchInCache(DslEngine engine, IEnumerable <string> urls, Assembly compiledAssembly) { engine.Cache.WriteLock(delegate { foreach (string batchUrl in urls) { Type type = engine.GetTypeForUrl(compiledAssembly, batchUrl); if (type == null) { throw new InvalidOperationException("Could not find the generated type for: " + batchUrl); } engine.Cache.Set(batchUrl, type); } engine.Storage.NotifyOnChange(urls, delegate(string invalidatedUrl) { engine.Cache.Remove(invalidatedUrl); standAloneCompilation.Add(invalidatedUrl); }); }); }