如何让T4生成基于特定名称空间(递归)中的类的代码
本文关键字:递归 空间 代码 定名称 T4 于特 | 更新日期: 2023-09-27 17:48:56
我的体系结构的服务层由许多单一用途的命令类(对数据执行特定功能的类,例如创建用户)和查询类(为特定数据查询数据库的单个类)组成。这些通过Windsor安装程序注入到我的Asp.net MVC控制器类中。
例如,我在自定义IWindsorInstaller
类中运行container.Register(Component.For<CreateUserCommand>().ImplementedBy<CreateUserCommand>());
来实例化控制器中的CreateUserCommand
。
问题是,因为每个命令/查询类都是单一用途的,我最终会有很多这样的类,维护我的安装程序类将是一个痛苦的屁股。我突然想到,这将是T4的完美工作,因为我可以运行T4并让它重新生成安装程序类,以自动注册我所有的命令和查询类。
不幸的是,因为我从来没有做过T4之前,我不知道如何继续实际实现这一点。我已经阅读了T4的基础知识,但我的主要困惑是如何通过T4找到所有的命令和查询类。
在纸面上,我可以找到所有的命令/查询类,因为它们是在MyApp.DomainModel.Commands.*
和MyApp.DomainModel.Queries.*
名称空间中定义的。例如,CreateUserCommand
类驻留在MyApp.DomainModel.Queries.Users
命名空间中。但是,我不知道如何在运行时实际查看名称空间,更不用说递归地查看了。
我有可能为这些类创建一个ICommand
和IQuery
接口,如果在T4中比命名空间更容易找到,但我不知道如何通过T4找到所有ICommand/IQuery
子类。
我确实知道反射,但是从阅读中我读到很多说在T4中使用反射是一个坏主意和/或不能正常工作。
如果有人能给我指出任何可以帮助我完成这个任务的东西,我将非常感激!
从T4中使用反射本身并不是一件坏事,但关于"不能正常工作",主要问题是您无法可靠地反映T4模板定义的当前程序集,因为这尚未被编译。您通常需要将项目拆分为不同的程序集,以便从T4访问您自己的类型。
查找命名空间中的所有类型并不是一个困难的问题,特别是如果它们都定义在同一个程序集中。
<#@ import namespace = "System.Reflection" #>
<#
var path="D:'Path'To'MyApp.DomainModel.dll";
Assembly a = Assembly.ReflectionOnlyLoadFrom(path);
foreach (var type in a.GetTypes()) {
if (type.Namespace == "MyApp.DomainModel.Commands") { #>
<#=type.Name #>
<# }
}
#>