Возможно, вопрос сформулирован несколько сумбурно.
Использую немного расширенный custom MvcWebPageRazorHost, встал вопрос в том, чтобы сделать автоматический импорт пространств имен (NamespacesImport) в WebPageRazorHost (дабы не прописывать довольно-таки большой список в web.config, ну и еще по ряду причин). Это должно срабатывать в runtime и designtime.
Структура примерно следующая: есть проект Core (назовем его так).
Внутри два класса:
namespace Core
{
public class CustomWebRazorHostFactory : MvcWebRazorHostFactory
{
public override WebPageRazorHost CreateHost(string virtualPath, string physicalPath)
{
return CustomWebPageRazorHost.CreateFromAnother(base.CreateHost(virtualPath, physicalPath));
}
}
class CustomWebPageRazorHost : MvcWebPageRazorHost
{
public static CustomWebPageRazorHost CreateFromAnother(WebPageRazorHost host)
{
var newHost = new CustomWebPageRazorHost(host.VirtualPath, host.PhysicalPath);
newHost.DefaultBaseClass = typeof(CustomWebViewPage<>).FullName.Replace("`1", "");
newHost.DefaultClassName = host.DefaultClassName;
newHost.DefaultDebugCompilation = host.DefaultDebugCompilation;
newHost.DefaultPageBaseClass = typeof(CustomWebViewPage<>).FullName.Replace("`1", "");
newHost.DesignTimeMode = host.DesignTimeMode;
newHost.EnableInstrumentation = host.EnableInstrumentation;
newHost.GeneratedClassContext = host.GeneratedClassContext;
newHost.InstrumentedSourceFilePath = host.InstrumentedSourceFilePath;
newHost.IsIndentingWithTabs = host.IsIndentingWithTabs;
newHost.TabSize = host.TabSize;
foreach (string current in host.NamespaceImports) newHost.NamespaceImports.Add(current);
return newHost;
}
protected CustomWebPageRazorHost(string s1, string s2) : base(s1, s2)
{
try
{
this.NamespaceImports.Add("System.Web.Helpers");
this.NamespaceImports.Add("System.Web.Mvc");
this.NamespaceImports.Add("System.Web.Mvc.Html");
this.NamespaceImports.Add("System.Web.Routing");
this.NamespaceImports.Add("System.Collections");
var namespaces = Utils.ReflectionHelper.GetEngineNamespaces();
foreach (var _namespace in namespaces)
{
this.NamespaceImports.Add(_namespace);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
}
Есть проект Web (назовем его так), который подключает Core и в web.config регистрирует "host factoryType" следующим образом:
<host factoryType="Core.CustomWebRazorHostFactory, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=..." />
Внутри GetEngineNamespaces происходит вся магия. Если упрощенно - получаем определенный список сборок (Assembly), забираем оттуда определенные типы (GetExportedTypes плюс немного фильтрации) и получаем искомые пространства имен и пихаем в this.NamespaceImports.
С рантаймом не возникает проблем. В память домена уже загружены все нужные сборки и достаточно просто их проитерировать и получить типы.
Возник небольшой затык с design-time, во время работы с представлением в проекте Web в Visual Studio.
Во-первых, пришлось подписывать библиотеку Core строгим именем и регистрировать в GAC, иначе в designtime студия не видит Core и соответственно не видит тип CustomWebRazorHostFactory.
Во-вторых, в designtime в AppDomain в VisualStudio находится только сборка Core. Попробую разъяснить.
Если запустить студию и открыть все решение (solution), затем открыть еще одну копию студии и подцепиться к первой отладчиком ("Attach to process"), то можно отследить, что происходит внутри GetEngineNamespaces в момент открытия представления в редакторе студии. Ну, я и прослеживаю. AppDomain содержит примерно 500 загруженных сборок, это всё - сборки самой студии, расширения, сторонние компоненты и прочее. Плюс там есть загруженная сборка Core, т.к. GetEngineNamespaces вызывается внутри неё. НО! Кроме Core, есть еще ряд типов внутри Web, пространства имен которых мне надо отразить в NamespacesImport. Но сборки Web нет в AppDomain студии, т.к. это открытая в Solution сборка.
Итак, вопрос дня - каким образом можно дотянуться до какого-то контекста внутри студии, чтобы вытащить оттуда те же типы и пространства имен, которые, условно говоря, видит Intellisense внутри Web?
P.S. Если иметь ТРи проекта, Core, WebAdditional и Web, подключить WebAdditional и Core внутрь Web, то в designtime представления в Web будет опять же только Core, но мне надо и WebAdditional увидеть.