我們正在創建自己生成的代碼來自動化CRUD編碼,我們需要生成一個WPF使用的類。爲此,我們需要創建具有字段/屬性作爲依賴對象的類。我們如何使用.Net 3.5中的CodeDom完成這項工作?我們如何使用.Net CodeDom創建一個依賴對象?
1
A
回答
1
文章 - Three Ways to Implement Dependency Injection in .NET Applications
摘要: 依賴注入模式代碼 替換依賴讓你的類更容易測試和 重用
Dynamic Code Generation using CodeDOM
摘要:文章解釋如何 C. odeDOM可用於動態生成代碼 並使用動態代碼編譯 構建它。它還解釋瞭如何應用自定義屬性 。
0
您可以使用以下命令動態生成一個依賴項對象,其依賴項屬性源自Dictionary。
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]);
}
}
相關問題
- 1. 依賴對象創建
- 2. 如何使用依賴注入創建業務層對象?
- 3. 如何使用依賴注入創建新對象
- 4. 依賴倒置。對象創建
- 5. 創建相互依賴的對象
- 6. 如何在SQLAlchemy中創建兩個相互依賴的對象?
- 7. 我們如何從一個依賴類中訪問噴油器對象?
- 8. 如何用依賴項注入多次創建對象
- 9. 如何用某些依賴注入來限制對象創建?
- 10. 我們如何創建Dagger 2的依賴關係圖?
- 11. 我如何使用依賴於對
- 12. 如何使用CodeDom創建一個十進制常量?
- 13. 微依賴,避免耦合和對象創建對象
- 14. 由其他依賴創建的對象的.NET .NET構造器注入
- 15. 一旦我們有了值,我該如何創建對象?
- 16. 如何在我們剛剛創建的對象上使用object.get()
- 17. 如何爲依賴於DbEntityEntry的對象創建單元測試
- 18. 如何在Redshift中爲對象創建依賴項列表?
- 19. 我只釋放對象,如果我使用alloc創建它們?
- 20. 使用imageCFC我如何創建一個圖像對象?
- 21. 如何使用spring來解析手動創建的對象的依賴關係?
- 22. 創建一個自定義依賴塊
- 23. 注入一個對象內的依賴
- 24. CodeDom - 創建具有對象數組屬性的對象
- 25. 如何爲依賴於另一個會話的會話創建依賴關係?
- 26. 如何用依賴創建CocoaPod?
- 27. node.js eventemitter創建多個對象還是依賴於參數?
- 28. 可否依賴注入延遲創建對象所需?
- 29. 對工廠或創建對象的依賴關係
- 30. JavaScript對象依賴於另一個對象