CodeModel是發現Visual Studio內部代碼的強大工具。我們將VS2013的CodeModel與T4結合使用來生成我們3層體系結構中大部分乏味的代碼。什麼是使用Visual Studio的代碼模型來查找類的更快方法?
我發現什麼是以下幾點:
我們有2個項目,假設A和B,其中一個(A)有(B)的參考。在項目A中,我們僅使用此項目中的模型類來生成模型的擴展。這些類在項目B中使用了幾個類。下面是這些類中的一個的示例。
using Common.Library;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Projecten.Model.DataContracts.Statistiek
{
[DataObject]
[CustomResultClass("FactuurStatistiek")]
public partial class FactuurStatistiek : BaseStatistiek
{
public FactuurStatistiek Copy()
{
FactuurStatistiek copy = new FactuurStatistiek();
copy.AddRange(this);
return copy;
}
}
}
我們已經與其中的[CustomResultClass]屬性被用於代碼生成2個屬性的裝飾類。
問題是,當我們在項目A中找到此類的CodeModel時,這些屬性不可用。我寫了一個搜索例程來搜索整個解決方案。下面的代碼:
public CodeType CodeType
{
get
{
if (m_CodeType == null)
{
m_CodeType = GetCodeType();
}
return m_CodeType;
}
}
/// <summary>
/// Get the CodeType for the property
/// </summary>
private CodeType GetCodeType()
{
string name = Name;
CodeType codeType = null;
if (name == "FactuurStatistiek")
{
codeType = FindCodeType(CodeProperty.Type.AsFullName);
}
if (codeType == null)
{
CodeTypeRef codeTypeRef = CodeProperty.Type;
if (codeTypeRef.CodeType.IsCodeType)
{
codeType = codeTypeRef.CodeType;
}
if (codeType == null)
{
if (string.IsNullOrEmpty(CodeProperty.Type.AsFullName))
{
codeType = CodeModel.CodeTypeFromFullName(CodeProperty.Type.AsString);
}
else
{
codeType = CodeModel.CodeTypeFromFullName(CodeProperty.Type.AsFullName);
}
}
}
return codeType;
}
private CodeType FindCodeType(string fullName)
{
CodeType codeType = null;
foreach (Project project in Metadata.Dte.Solution.Projects)
{
foreach (ProjectItem projectItem in project.ProjectItems)
{
codeType = RecurseProjectItems(projectItem.ProjectItems, fullName);
if (codeType != null)
{
return codeType;
}
}
}
return null;
}
private CodeType RecurseProjectItems(ProjectItems projectItems, string fullName)
{
CodeType codeType = null;
if (projectItems != null)
{
foreach (ProjectItem projectItem in projectItems)
{
if (projectItem.FileCodeModel != null)
{
codeType = RecurseCodeElements(projectItem.FileCodeModel.CodeElements, fullName);
if (codeType != null)
{
break;
}
}
codeType = RecurseProjectItems(projectItem.ProjectItems, fullName);
if (codeType != null)
{
break;
}
}
}
return codeType;
}
private CodeType RecurseCodeElements(CodeElements codeElements, string fullName)
{
CodeType codeType = null;
if (codeElements != null)
{
foreach (CodeElement codeElement in codeElements)
{
if (codeElement.Kind == vsCMElement.vsCMElementNamespace)
{
codeType = RecurseCodeElements(((CodeNamespace)codeElement).Members, fullName);
}
else if (codeElement.Kind == vsCMElement.vsCMElementClass)
{
string classFullName = ((CodeClass)codeElement).FullName;
if (((CodeClass)codeElement).FullName == fullName)
{
codeType = (CodeType)codeElement;
}
}
if (codeType != null)
{
break;
}
}
}
return codeType;
}
此代碼工作正常,我們得到正確的CodeModel該類但代碼是非常,非常緩慢。我的猜測是,不僅遍歷所有的項目和項目使它慢,但我有這樣的感覺,在解決CodeModels發現類中的文本被解析。
我們應該如何改進搜索算法,使性能變得可以接受?
沒有人對我有任何建議嗎? –
我的建議是使用Roslyn來代替。 –