예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
 /// <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);
        }