我的架构的服务层由许多单用途命令类(对数据执行一个特定功能的类,如创建用户)和查询类(查询数据库以查找特定数据的各个类)组成。这些通过Windsor安装程序注入我的Asp.net MVC控制器类。
例如,我在自定义container.Register(Component.For<CreateUserCommand>().ImplementedBy<CreateUserCommand>());
类中运行IWindsorInstaller
来实例化我的控制器中的CreateUserCommand
。
问题在于,由于每个命令/查询类都是单一的目的,我最终将会遇到很多这样的类,并且维护我的安装程序类将是一个痛苦的屁股。在我看来,对于T4来说这将是一个完美的工作,因为我可以运行T4并让它重新生成安装程序类以自动注册我的所有命令和查询类。
不幸的是,因为在我不知道如何进行实际实现之前我从未完成过T4。我已经阅读了T4的基础知识,但我的主要困惑是如何通过T4实际找到我的所有命令和查询类。
在纸面上,我可以找到所有命令/查询类,因为它们是在MyApp.DomainModel.Commands.*
和MyApp.DomainModel.Queries.*
命名空间中定义的。例如,CreateUserCommand
类位于MyApp.DomainModel.Queries.Users
命名空间中。但是,我不知道如何在运行时实际查看命名空间,更不用说递归了。
我可以为这些类创建一个ICommand
和IQuery
接口,如果在T4中比命名空间更容易找到,但我不知道怎么会找到所有ICommand/IQuery
子类都通过T4。
我确实知道反思,但是从阅读中我已经阅读了很多说在T4中使用反射是一个坏主意和/或无法正常工作。
如果有人能指出任何有助于我实现这一目标的事情,我将非常感激!
答案 0 :(得分:8)
使用来自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 #>
<# }
}
#>