【问题标题】:How do we use .Net CodeDom to create a Dependency Object?我们如何使用 .Net CodeDom 创建依赖对象?
【发布时间】:2016-10-16 22:55:03
【问题描述】:

我们正在创建自己的代码以自动生成 CRUD 编码,并且我们需要生成一个用于 WPF 的类。为此,我们需要创建具有字段/属性作为依赖对象的类。我们如何在 .Net 3.5 中使用 CodeDom 实现这一点?

【问题讨论】:

    标签: c# .net codedom


    【解决方案1】:

    文章 - Three Ways to Implement Dependency Injection in .NET Applications

    摘要:将依赖项替换为 依赖注入模式代码 使您的课程更易于测试和 重用

    Dynamic Code Generation using CodeDOM

    总结:这篇文章解释了如何 CodeDOM 可用于生成代码 动态并使用动态构建它 代码编译。它还解释了如何 应用自定义属性。

    【讨论】:

      【解决方案2】:

      您可以使用以下内容动态生成依赖对象,其依赖属性来自字典。

      using System;
      using System.CodeDom;
      using System.CodeDom.Compiler;
      using System.Collections.Generic;
      using System.Reflection;
      using System.Windows;
      using Microsoft.CSharp;
      
      namespace WpfApplication1
      {
      public class DependencyPropertyGenerator
      {
          public static Type Generate(Dictionary<string, Type> typeDef)
          {
              var codeCompileUnit = new CodeCompileUnit();
      
              var codeNamespace = new CodeNamespace("Generated");
      
              codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
              codeNamespace.Imports.Add(new CodeNamespaceImport("System.Windows"));
      
              var codeTypeDeclaration = new CodeTypeDeclaration("DataObject")
              {
                  IsClass = true,
                  TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed
              };
              codeTypeDeclaration.BaseTypes.Add(new CodeTypeReference(typeof (DependencyObject)));
      
              codeNamespace.Types.Add(codeTypeDeclaration);
              codeCompileUnit.Namespaces.Add(codeNamespace);
      
              AddProperties(codeTypeDeclaration, typeDef);
      
              return CompileAssembly(codeCompileUnit);
          }
      
      
          public static void AddProperties(CodeTypeDeclaration targetClass, Dictionary<string, Type> typeDef)
          {
              foreach (var pair in typeDef)
              {
                  var dpProperty = new CodeMemberField
                  {
                      Name = pair.Key + "Property",
                      Attributes = MemberAttributes.Public | MemberAttributes.Static,
                      Type = new CodeTypeReference("DependencyProperty"),
                      InitExpression = new CodeMethodInvokeExpression(
                          new CodeTypeReferenceExpression("DependencyProperty"),
                          "Register",
                          new CodePrimitiveExpression(pair.Key),
                          new CodeTypeOfExpression(pair.Value),
                          new CodeTypeOfExpression(targetClass.Name),
                          new CodeObjectCreateExpression(typeof (PropertyMetadata),
                              new CodeDefaultValueExpression(new CodeTypeReference(pair.Value))))
                  };
                  targetClass.Members.Add(dpProperty);
      
                  var clrProperty = new CodeMemberProperty
                  {
                      Name = pair.Key,
                      Type = new CodeTypeReference(pair.Value),
                      Attributes = MemberAttributes.Public | MemberAttributes.Final
                  };
      
                  clrProperty.GetStatements.Add(
                      new CodeMethodReturnStatement(new CodeCastExpression(pair.Value,
                          new CodeMethodInvokeExpression(null, "GetValue",
                              new CodeFieldReferenceExpression(null, dpProperty.Name)))
                          ));
      
                  clrProperty.SetStatements.Add(
                      new CodeMethodInvokeExpression(null, "SetValue",
                          new CodeFieldReferenceExpression(null, dpProperty.Name),
                          new CodePropertySetValueReferenceExpression()));
      
                  targetClass.Members.Add(clrProperty);
              }
          }
      
          private static Type CompileAssembly(CodeCompileUnit compileUnit)
          {
              var compilerParameters = new CompilerParameters
              {
                  GenerateExecutable = false,
                  GenerateInMemory = true
              };
      
              var executingAssembly = Assembly.GetExecutingAssembly();
              compilerParameters.ReferencedAssemblies.Add(executingAssembly.Location);
      
              foreach (var assemblyName in executingAssembly.GetReferencedAssemblies())
              {
                  compilerParameters.ReferencedAssemblies.Add(Assembly.Load(assemblyName).Location);
              }
      
              using (var provider = new CSharpCodeProvider())
              {
                  var compileResults = provider.CompileAssemblyFromDom(compilerParameters, compileUnit);
                  var compiledAssembly = compileResults.CompiledAssembly;
                  return compileResults.Errors.Count > 0 ? null : compiledAssembly.GetType("Generated.DataObject");
              }
          }
      }
      }
      

      下面是你如何使用它:

          [Test]
          public void GenerateTest()
          {
              var typeDictionary = new Dictionary<string, Type>
              {
                  {"Field1", typeof (string)},
                  {"Field2", typeof (double)},
                  {"Field3", typeof (decimal)},
                  {"Field4", typeof (DateTime)},
                  {"Field5", typeof (float)}
              };
      
              var type = DependencyPropertyGenerator.Generate(typeDictionary);
      
              foreach (var fieldName in typeDictionary.Keys)
              {
                  var dp = DependencyPropertyDescriptor.FromName(fieldName, type, type);
                  Assert.IsNotNull(dp.DependencyProperty);
                  Assert.AreEqual(dp.DependencyProperty.Name,fieldName);
                  Assert.AreEqual(dp.DependencyProperty.PropertyType , typeDictionary[fieldName]);
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多