Có một cách dễ dàng hơn để làm điều này?
Không, tôi không nghĩ như vậy, ít nhất cho một < = VS2013, có vẻ như rằng CodeAttributeArgument
không đi xa hơn, đó là sự xấu hổ. Họ nên tôi đã phát hành CodeAttributeArgument2
có Value
như CodeExpr
: \ ..
Nếu bạn sử dụng> = VS2014, bạn có thể nhận được quyền truy cập vào Roslyn, và nó nêntrở thành dễ dàng hơn - không biết chính xác làm thế nào bạn có thể truy cập roslyn bên trong phần mở rộng VS, phải chờ xem.
Để có được thuộc tính, bạn có thể sử dụng VS helper:
public List<CodeElement> GetAllCodeElementsOfType(
CodeElements elements,
vsCMElement elementType,
bool includeExternalTypes)
{
var ret = new List<CodeElement>();
foreach (CodeElement elem in elements)
{
// iterate all namespaces (even if they are external)
// > they might contain project code
if (elem.Kind == vsCMElement.vsCMElementNamespace)
{
ret.AddRange(
GetAllCodeElementsOfType(
((CodeNamespace)elem).Members,
elementType,
includeExternalTypes));
}
// if its not a namespace but external
// > ignore it
else if (elem.InfoLocation == vsCMInfoLocation.vsCMInfoLocationExternal && !includeExternalTypes)
continue;
// if its from the project
// > check its members
else if (elem.IsCodeType)
{
ret.AddRange(
GetAllCodeElementsOfType(
((CodeType)elem).Members,
elementType,
includeExternalTypes));
}
if (elem.Kind == elementType)
ret.Add(elem);
}
return ret;
}
Nguồn gốc: https://github.com/PombeirP/T4Factories/blob/master/T4Factories.Testbed/CodeTemplates/VisualStudioAutomationHelper.ttinclude
Trong khi đó, bạn có thể sử dụng giải pháp thụt lùi, điều này không phải là tốt đẹp, nhưng nó phải làm việc , chưa thử nghiệm chính xác 100%. Ý tưởng cơ bản là bắt đầu theo dõi ngược từ lớp và theo dõi các không gian tên/cách sử dụng khác nhau trong đường dẫn của một lớp. Này sẽ cố gắng để mô phỏng khá nhiều những gì một trình biên dịch thực sẽ làm gì, nếu nó sẽ giải quyết một kiểu:
var solution = (Solution2) _applicationObject.Solution;
var projects = solution.Projects;
var activeProject = projects
.OfType<Project>()
.First();
// locate my class.
var myClass = GetAllCodeElementsOfType(
activeProject.CodeModel.CodeElements,
vsCMElement.vsCMElementClass, false)
.OfType<CodeClass2>()
.First(x => x.Name == "Program");
// locate my attribute on class.
var mySpecialAttrib = myClass
.Attributes
.OfType<CodeAttribute2>()
.First();
var attributeArgument = mySpecialAttrib.Arguments
.OfType<CodeAttributeArgument>()
.First();
string myType = Regex.Replace(
attributeArgument.Value, // typeof(MyType)
"^typeof.*\\((.*)\\)$", "$1"); // MyType*/
var codeNamespace = myClass.Namespace;
var classNamespaces = new List<string>();
while (codeNamespace != null)
{
var codeNs = codeNamespace;
var namespaceName = codeNs.FullName;
var foundNamespaces = new List<string> {namespaceName};
// generate namespaces from usings.
var @usings = codeNs.Children
.OfType<CodeImport>()
.Select(x =>
new[]
{
x.Namespace,
namespaceName + "." + x.Namespace
})
.SelectMany(x => x)
.ToList();
foundNamespaces.AddRange(@usings);
// prepend all namespaces:
var extra = (
from ns2 in classNamespaces
from ns1 in @usings
select ns1 + "." + ns2)
.ToList();
classNamespaces.AddRange(foundNamespaces);
classNamespaces.AddRange(extra);
codeNamespace = codeNs.Parent as CodeNamespace;
if (codeNamespace == null)
{
var codeModel = codeNs.Parent as FileCodeModel2;
if (codeModel == null) return;
var elems = codeModel.CodeElements;
if (elems == null) continue;
var @extraUsings = elems
.OfType<CodeImport>()
.Select(x => x.Namespace);
classNamespaces.AddRange(@extraUsings);
}
}
// resolve to a type!
var typeLocator = new EnvDTETypeLocator();
var resolvedType = classNamespaces.Select(type =>
typeLocator.FindTypeExactMatch(activeProject, type + "." + myType))
.FirstOrDefault(type => type != null);
Bạn cần EnvDTETypeLocator quá.
Đối với VS2015, một ví dụ về hội nhập roslyn thể được tìm thấy tại đây: https://github.com/tomasr/roslyn-colorizer/blob/master/RoslynColorizer/RoslynColorizer.cs
Nó chắc chắn sẽ dễ dàng hơn rất nhiều so với nó là với hiện tại CodeModel
.
vì vậy, làm thế nào để bạn có được tham chiếu đến đối số thuộc tính? – Maslow
Bạn đã xem xét Roslyn chưa? Nó sẽ cung cấp các tính năng bạn đang tìm kiếm. – jessehouwing
Bạn đã kiểm tra thuộc tính FullName của thuộc tính chưa? –