powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Кто-нибудь в T4 и EnvDTE разбирается?
21 сообщений из 21, страница 1 из 1
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455641
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажется в VS2017 EnvDTE игнорирует атрибуты.

Пример:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
namespace ConsoleApp2
{
    [Test]
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    class Test : Attribute { }
}


Добавляю в приложение шаблон Template1.tt:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".txt" #>
<#@ Assembly Name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#
	Init();
	WriteLine(Classes.Count.ToString());

//попытка получить атрибуты:
	foreach(CodeClass cc in Classes) {
		foreach(CodeElement ce in cc.Members){
			if(ce.Kind == vsCMElement.vsCMElementFunction){
				CodeFunction cf = ce as CodeFunction;
				WriteLine(ce.Name + " " + cf.Attributes.Count.ToString());
			}
		}
	}
#>
<#+

public CodeNamespace Ns {get;set;}
public List<CodeClass> Classes {get;set;}

public void Init(){

	IServiceProvider hostServiceProvider = (IServiceProvider)Host;
	DTE dte  = (DTE)hostServiceProvider.GetService(typeof(DTE));

	Project proj=null;
	foreach(Project p in dte.Solution.Projects){
		if(p.Name == "ConsoleApp2"){
			proj=p;
			break;
		} 
	} 

	foreach(CodeElement ce in proj.CodeModel.CodeElements) {
		if(ce.Name=="ConsoleApp2"){
			Ns = ce as CodeNamespace;
			break;
		}
	}

	Classes = new List<CodeClass>();
	GetClasses(Ns);
}

public void GetClasses(CodeNamespace cn){
	foreach(CodeElement ce in cn.Members) {
		if(ce.Kind == vsCMElement.vsCMElementNamespace) {
			GetClasses(ce as CodeNamespace);
        } else if(ce.Kind == vsCMElement.vsCMElementClass) {
			Classes.Add(ce as CodeClass);
		}
    }
}
 
#>

на выходе:

Код: c#
1.
2.
2
Main 0

Это у всех так или только у меня?
Или я не там ищу атрибут Test?
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455647
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В примере косяк, [Test] у Main должен стоять.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455651
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, пример заработал.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455657
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот в пустом проекте типа WebApplication не пашут атрибуты в шаблончеге.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455879
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не пашут лишь у методов контроллеров. Вот гадство, именно там они и нужны.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455897
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyНе пашут лишь у методов контроллеров. Вот гадство, именно там они и нужны.Скомпилируй сборку работай с ней из T4 через рефлекшен. Не забудь указать следующую опцию, чтобы T4 "отпускал" файл сборки после своей работы.
Код: c#
1.
<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455899
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
* Скомпилируй сборку и работай ...
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455937
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К* Скомпилируй сборку и работай ...Если ты о Reflection, то он блокирует сборку, и даже пляски с аппдоменами не спасают. И гемор с зависимостями.

В общем, достоверно обнаружил, что атрибуты не видны, если файл с исходником не в корне проекта, а в папке. Двойное гадство.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455942
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КAntonariyНе пашут лишь у методов контроллеров. Вот гадство, именно там они и нужны.Скомпилируй сборку работай с ней из T4 через рефлекшен. Не забудь указать следующую опцию, чтобы T4 "отпускал" файл сборки после своей работы.
Код: c#
1.
<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>

Не заметил этого сообщения, попробую.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455973
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рефлекшн обломался:

Код: plaintext
1.
2.
3.
4.
Ошибка		Выполнение преобразования: System.IO.FileNotFoundException: Не удалось загрузить файл или сборку "System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" либо одну из их зависимостей. Не удается найти указанный файл.
Имя файла: 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   в Microsoft.VisualStudio.TextTemplating6E191A85ED77A05CD85D8E03765372E33142481F5E036A4E4C2916AA9B1D39F2C379D43E983ED2B7A82C5E314F85E5216BA7CD97091222A4B24FF8AF71DCC1B2.GeneratedTextTransformation.TransformText()
   в System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   в Microsoft.VisualStudio.TextTemplating.TransformationRunner.PerformTransformation()
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455987
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня это, так же, работает для анализа классов MVC/WebAPI конроллеров, проблем нет.

Гружу сборку через:
Код: c#
1.
2.
var controllersAssembly = Path.Combine(ProjectFolder, "Bin", Path.ChangeExtension(ProjectName, "dll"));
Assembly.LoadFrom(controllersAssembly);


Работа с EnvDTE
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
<#@ assembly name="System.Core" #>
<#@ assembly name="EnvDTE" #> 
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="EnvDTE" #>
<#+
	string TemplateFolder 
	{
		get { return Path.GetDirectoryName(Host.TemplateFile); }
	}

	string SolutionFolder
	{
		get
		{
			var dte = GetIdeService<DTE>();
			return Path.GetDirectoryName(dte.Solution.FullName);
		}
	}

	string ProjectFolder
	{
		get { return Path.GetDirectoryName(Project.FullName); }
	}

	string ProjectName
	{
		get { return Project.Name; }
	}

	Project Project
	{
		get
		{
			var dte = GetIdeService<DTE>();
			var item = dte.Solution.FindProjectItem(Host.TemplateFile);

			if (item != null && item.ContainingProject != null)
				return item.ContainingProject;

			throw new InvalidOperationException("Can't find project.");
		}
	}

	T GetIdeService<T>()
	{
		var sp = (IServiceProvider)Host;
		return (T)sp.GetService(typeof(T));
	}
#>

...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39455988
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавлю, работаю с VS2013, MVC5. Про заморочки с другими версиями не в курсе.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456000
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КУ меня это, так же, работает для анализа классов MVC/WebAPI конроллеров, проблем нет.С приведенным кодом и у меня проблем не будет.

С рефлекшеном проблемы начинаются тут: foreach(var t in Assembly.LoadFrom(controllersAssembly).ExportedTypes)

А с DTE - гемор с атрибутами. Попробуй мой шаблон у себя запустить, только замени "ConsoleApp2" на имя своего проекта и корневого неймспейса. У меня сейчас нет другой студии, а тип приложения пофиг. Я в консольном закинул Program.cs в папку, и атрибуты стали невидимы.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456076
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyАлексей КУ меня это, так же, работает для анализа классов MVC/WebAPI конроллеров, проблем нет.С приведенным кодом и у меня проблем не будет.

С рефлекшеном проблемы начинаются тут: foreach(var t in Assembly.LoadFrom(controllersAssembly).ExportedTypes)Ну у меня вот так работает:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
<#+
	class Controller
	{
		public string VarName;

		public string Path;

		public string[] Actions;
	}

	enum ControllersTypes { Mvc, Api }

	const string S_Controller = "Controller";
	const string S_MvcController = "System.Web.Mvc.Controller";
	const string S_ApiController = "System.Web.Http.ApiController";

	Controller[] GetControllers()
	{
		var assembly = Assembly.LoadFrom(ControllersAssembly);

		var q =
			from t in assembly.GetTypes()
			let ctt = GetControllerType(t)
			where ctt.HasValue
			let ct = CreateController(t, ctt.Value)
			orderby ct.VarName
			select ct;

		return q.ToArray();
	}

	Controller CreateController(Type type, ControllersTypes controllerType)
	{
		var name = type.Name.Substring(0, type.Name.Length - S_Controller.Length);

		return new Controller
		{
			VarName = name,
			Path = GetControllerPath(name, controllerType),
			Actions = GetControllerActions(type)
		};
	}

	ControllersTypes? GetControllerType(Type type)
	{
		if (type.Name.EndsWith(S_Controller) == false)
			return null;

		if (HasBaseType(type, S_MvcController))
			return ControllersTypes.Mvc;

		if (HasBaseType(type, S_ApiController))
			return ControllersTypes.Api;

		return null;
	}

	bool HasBaseType(Type type, string typeName)
	{
		while (true)
		{
			type = type.BaseType;

			if (type == null)
				break;

			if (type.FullName == typeName)
				return true;
		}

		return false;
	}

	string GetControllerPath(string name, ControllersTypes controllerType)
	{
		if (controllerType == ControllersTypes.Mvc)
			return name;

		if (controllerType == ControllersTypes.Api)
			return "api/" + name;

		throw new ArgumentException("type");
	}

	string[] GetControllerActions(Type type)
	{
		var q =
			from t in GetControllerActionsTypes(type)
			from m in t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
			where m.IsSpecialName == false
			select m.Name;

		return q.Distinct().OrderBy(n => n).ToArray();
	}

	IEnumerable<Type> GetControllerActionsTypes(Type type)
	{
		while (true)
		{
			yield return type;
			type = type.BaseType;

			if (type == null || type.FullName == S_MvcController || type.FullName == S_ApiController)
				break;
		}
	}
#>
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456091
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy, а вообще, может через Roslyn попробовать? Его изобрели вроде как как раз для этого.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456095
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
assembly.GetTypes() - не удается загрузить один или более запрошенных типов.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456101
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КAntonariy, а вообще, может через Roslyn попробовать? Его изобрели вроде как как раз для этого.Тынц?
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456106
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyАлексей КAntonariy, а вообще, может через Roslyn попробовать? Его изобрели вроде как как раз для этого.Тынц? Тынц
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456108
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariyassembly.GetTypes() - не удается загрузить один или более запрошенных типов.Вероятно его не устраивает версия .Net, используемая в процессе VS IDE.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456121
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КAntonariyassembly.GetTypes() - не удается загрузить один или более запрошенных типов.Вероятно его не устраивает версия .Net, используемая в процессе VS IDE.Точно, у меня Сore.
...
Рейтинг: 0 / 0
Кто-нибудь в T4 и EnvDTE разбирается?
    #39456134
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КAntonariyпропущено...
Тынц? Тынц Это трындец и перебор, натягивать объектную модель на каждый символа кусок. Меня лишь интерфейс сборки интересует.

А текст можно и через dte анализировать, или вообще без ничего. но это костыль. Уж лучше в названия методов добавлять префиксы/постфиксы вместо атрибутов.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Кто-нибудь в T4 и EnvDTE разбирается?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]