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 (string ns in GetNamespaces(templateType, namespaceImports)) { host.NamespaceImports.Add(ns); } // Gets the generator result. GeneratorResults 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)); } Type modelType = Model.GetType(); var prop = modelType.GetProperty(binder.Name); if (prop == null) { result = null; return(false); } object value = prop.GetValue(Model, null); if (value == null) { result = value; return(true); } Type valueType = value.GetType(); result = (CompilerServicesUtility.IsAnonymousType(valueType)) ? new RazorDynamicObject { Model = value } : value; return(true); }
public virtual string BuildTypeName(Type templateType, Type modelType) { if (templateType == null) { throw new ArgumentNullException("templateType"); } if (!templateType.IsGenericTypeDefinition && !templateType.IsGenericType) { return(templateType.FullName); } if (modelType == null) { throw new ArgumentException("The template type is a generic defintion, and no model type has been supplied."); } bool @dynamic = CompilerServicesUtility.IsDynamicType(modelType); Type genericType = templateType.MakeGenericType(modelType); return(BuildTypeNameInternal(genericType, @dynamic)); }
/// <summary> /// Initialises a new instance of <see cref="TypeContext"/>. /// </summary> internal TypeContext() { ClassName = CompilerServicesUtility.GenerateClassName(); Namespaces = new HashSet <string>(); }
private byte[] CompileByte(string originalClassName, string originalText) { Console.WriteLine(assemblieslist); if (assemblieslist == null) { string replstr = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "file:///" : "file://"; var assemblies = CompilerServicesUtility .GetLoadedAssemblies() .Where(a => !a.IsDynamic && File.Exists(a.CodeBase.Replace(replstr, ""))) .Select(a => (a.CodeBase.Replace(replstr, ""))); int c = assemblies.Count(); assemblieslist = new MetadataReference[c]; int i = 0; foreach (string item in assemblies) { assemblieslist[i] = (MetadataReference.CreateFromFile(item)); i++; } } CSharpCompilation compilation = null; var syntaxTree = CSharpSyntaxTree.ParseText(originalText); // 指定编译选项。 var assemblyName = $"{originalClassName}.g"; compilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .AddReferences( // 这算是偷懒了吗?我把 .NET Core 运行时用到的那些引用都加入到引用了。 // 加入引用是必要的,不然连 object 类型都是没有的,肯定编译不通过。 //AppDomain.CurrentDomain.GetAssemblies().Select(x => MetadataReference.CreateFromFile(x.Location)) assemblieslist ); // 编译到内存流中。 byte [] buff = null; using (var ms = new MemoryStream()) { var result = compilation.Emit(ms); if (result.Success) { ms.Seek(0, SeekOrigin.Begin); buff = ms.ToArray(); } else { string errmsg = ""; for (int i1 = 0; i1 < result.Diagnostics.Length; i1++) { errmsg += result.Diagnostics[i1] + "\r\n"; } throw new Exception(errmsg); } ms.Close(); } /* * for (int i1=0;i1< list.Length;i1++) * { * list[i1] = null; * } */ return(buff); // } //catch (Exception e) //{ //} return(null); }