我正在尝试构建一个 C# 源生成器,其中我需要引用解决方案中另一个项目中的源文件 (.cs)。有没有一种干净的方法来做到这一点?
为了清楚起见,这是我的背景。
我正在构建一个 Blazor Web 应用程序,其中有一个服务器和一个客户端。我使用属性路由来设置 webapi 中的 url。
[HttpGet]
[Route("api/clients/{id}", Name = "Client")]
public async Task<ClientViewModel> GetById(int id)
{
var client = await _clientLogic.GetById(id);
return _clientViewLogic.ToViewModel(client);
}
Run Code Online (Sandbox Code Playgroud)
我想避免
相反,我想使用这样的东西
var url = GetClientUrl(clientId);
Run Code Online (Sandbox Code Playgroud)
这应该可以通过源生成器轻松实现,该源生成器可以将
[Route("api/clients/{id}", Name = "Client")]
Run Code Online (Sandbox Code Playgroud)
进入
public string GetClientUrl(string id)
{
return $"api/clients/{id}";
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我使用 Blazor 时,我需要将代码放入由我的服务器项目和客户端项目引用的共享项目中。但是,如果我将源生成器添加到共享项目,那么我只有该项目的编译上下文,并且无法访问服务器项目内的路由属性来构建我的函数。
所以我的完整问题是,有没有办法从链接到我的共享项目的源生成器访问我的服务器编译上下文?
我认为解决此问题的一种方法是忽略源生成器提供的编译上下文,并通过对路径或其他内容进行硬编码来基于解决方案中的所有项目创建一个新的编译上下文。这应该可以,但感觉不太干净。
我正在尝试使用MEF为asp.net webforms制作某种插件系统.
到目前为止,我已经找到了一个解决方案,主机网站将在其插件文件夹中搜索加载名为Module的其他网站.模块(插件)只是另一个网站项目,因此它的bin子文件夹中有自己的程序集.
您当然已经知道,ASP.NET应用程序不会在其bin文件夹之外加载dll .因此,如果我尝试访问模块页面(例如:plugins/MyModule/Page.aspx).我会收到一个错误,说服务器无法加载程序集MyModule.我可以将模块的程序集放在主bin文件夹中,一切都会正常工作,但我想将所有模块文件保存在同一个文件夹中.
所以我正在寻找一种在bin文件夹之外加载程序集的方法.我已经尝试搞乱web.config文件,但无法提供有效的解决方案.
然后我来到BuildManager类并编写了这段代码:
string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
foreach (string f in Directory.GetDirectories(pluginPath))
{
string binPath = Path.Combine(f, "bin");
if (Directory.Exists(binPath))
{
foreach (String file in Directory.GetFiles(binPath, "*.dll"))
{
Assembly a = Assembly.LoadFrom(file);
BuildManager.AddReferencedAssembly(a);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它在plugin文件夹中搜索包含bin文件夹的任何其他子文件夹,并使用BuildManager加载相应的程序集.要使此代码有效,我必须在global.aspx程序集的PreApplicationStartMethod中调用它.
现在当我导航到插件页面(插件/ MyModule/Page.aspx)时,它不会给我以前的错误,但页面是空白的.我检查了源代码,没有html,没有.我试图调试页面,但从未调用Page_Load方法.所以我想某种方式从来没有调用Page.aspx背后的代码.
编辑:
所以在搜索了一下之后我找到了一个解决方案:
当我加载模块程序集时,我将其引用存储在一个dictionnay中.然后在 …