2009-08-20 13 views
1

CRUDコーディングを自動化するために生成された独自のコードを作成しており、WPFで使用するためのクラスを生成する必要があります。これを行うには、フィールド/プロパティを持つクラスを依存オブジェクトとして作成する必要があります。 .NET 3.5でCodeDomを使用してこれを達成するにはどうすればよいですか?.Net CodeDomを使用して依存オブジェクトを作成するにはどうすればよいですか?

答えて

1

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

概要:テストするあなたのクラスを容易に に 依存性注入パターンコードとの依存関係を交換し、 再利用

Dynamic Code Generation using CodeDOM

概要:この記事はどのように説明しますか C odeDOMを使用してコード を動的に生成し、動的な コードのコンパイルを使用して構築することができます。また、 がカスタム属性を適用する方法についても説明します。

0

以下を使用すると、ディクショナリから取得した依存関係プロパティを使用して依存関係オブジェクトを動的に生成できます。

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]); 
     } 
    } 
関連する問題