private Tuple <CompilerResults, string> Compile(TypeContext context) { if (_disposed) { throw new ObjectDisposedException(GetType().Name); } var compileUnit = GetCodeCompileUnit(context.ClassName, context.TemplateContent, context.Namespaces, context.TemplateType, context.ModelType); var @params = new CompilerParameters { GenerateInMemory = true, GenerateExecutable = false, IncludeDebugInformation = false, CompilerOptions = "/target:library /optimize" }; var assemblies = CompilerServicesUtility .GetLoadedAssemblies() .Where(a => !a.IsDynamic && File.Exists(a.Location)) .GroupBy(a => a.GetName().Name).Select(grp => grp.First(y => y.GetName().Version == grp.Max(x => x.GetName().Version))) // only select distinct assemblies based on FullName to avoid loading duplicate assemblies .Select(a => a.Location); var includeAssemblies = (IncludeAssemblies() ?? Enumerable.Empty <string>()); assemblies = assemblies.Concat(includeAssemblies) .Where(a => !string.IsNullOrWhiteSpace(a)) .Distinct(StringComparer.InvariantCultureIgnoreCase); @params.ReferencedAssemblies.AddRange(assemblies.ToArray()); string sourceCode = null; if (Debug) { var builder = new StringBuilder(); using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture)) { _codeDomProvider.GenerateCodeFromCompileUnit(compileUnit, writer, new CodeGeneratorOptions()); sourceCode = builder.ToString(); } } return(Tuple.Create(_codeDomProvider.CompileAssemblyFromDom(@params, compileUnit), sourceCode)); }
public CodeCompileUnit GetCodeCompileUnit(string className, string template, ISet <string> namespaceImports, Type templateType, Type modelType) { if (string.IsNullOrEmpty(className)) { throw new ArgumentException("Class name is required."); } if (string.IsNullOrEmpty(template)) { throw new ArgumentException("Template is required."); } namespaceImports = namespaceImports ?? new HashSet <string>(); templateType = templateType ?? ((modelType == null) ? typeof(TemplateBase) : typeof(TemplateBase <>)); // Create the RazorEngineHost var host = CreateHost(templateType, modelType, className); // Add any required namespace imports foreach (var ns in GetNamespaces(templateType, namespaceImports)) { host.NamespaceImports.Add(ns); } // Gets the generator result. var result = GetGeneratorResult(host, template); // Add the dynamic model attribute if the type is an anonymous type. var type = result.GeneratedCode.Namespaces[0].Types[0]; if (modelType != null && CompilerServicesUtility.IsAnonymousType(modelType)) { type.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(HasDynamicModelAttribute)))); } // Generate any constructors required by the base template type. GenerateConstructors(CompilerServicesUtility.GetConstructors(templateType), type); // Despatch any inspectors Inspect(result.GeneratedCode); return(result.GeneratedCode); }
public override bool TryGetMember(GetMemberBinder binder, out object result) { if (binder == null) { throw new ArgumentNullException("binder"); } var dynamicObject = Model as RazorDynamicObject; if (dynamicObject != null) { return(dynamicObject.TryGetMember(binder, out result)); } var modelType = Model.GetType(); var prop = modelType.GetProperty(binder.Name); if (prop == null) { result = null; return(false); } var value = prop.GetValue(Model, null); if (value == null) { result = value; return(true); } var valueType = value.GetType(); result = (CompilerServicesUtility.IsAnonymousType(valueType)) ? new RazorDynamicObject { Model = value } : value; return(true); }
/// <summary> /// Initialises a new instance of <see cref="TypeContext" />. /// </summary> internal TypeContext() { ClassName = CompilerServicesUtility.GenerateClassName(); Namespaces = new HashSet <string>(); }