Hicimos algo similar a esto. Nuestra solución tiene los siguientes elementos:
- host personalizado
- personalizado clase base de la plantilla ("hereda" la propiedad de directiva de plantilla) Plantillas
- host específico (propiedad "hostspecific" de la directiva de plantilla)
El host personalizado se agrega por el objeto que la galería de símbolos quiere invocar en los métodos.
interface ICallbackInterface
{
void CallbackFxn();
}
[Serializable]
public class MyCustomHost : ITextTemplatingEngineHost, ITextTemplatingSessionHost, IStencilFileRecordManagement
{
private ICallbackInterface callback = null;
public MyCustomHost(ICallbackInterface cb)
{
callback = cb;
}
public void CallbackFxn()
{
callback.CallbackFxn();
}
}
public abstract class MyTemplateBase : TextTransformation
{
public virtual MyCustomHost CustomHost
{
get
{
dynamic metame = this;
MyCustomHost rval = null;
try
{
/// <summary>
/// The "Host" property will be added to the generated class by the T4 environment whenever a
/// "hostspecific" template is processed.
/// </summary>
rval = metame.Host as MyCustomHost;
}
catch (RuntimeBinderException e)
{
logger.ErrorException(
"Received the following exception while processing a stencil template", e);
}
return rval;
}
}
}
Ahora, en alguna de nuestras plantillas, podemos invocar métodos en el objeto que realmente se inició el tratamiento mediante la propiedad de host personalizado, por ejemplo:
<# CustomHost.CallbackFxn(); #>
Además, no utilizamos T4 en VS o usando un archivo ejecutable por separado: enlazamos con los ensamblajes Microsoft.VisualStudio.TextTemplating.10.0 y Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.
EDITAR
Estamos utilizando plantillas T4 permiten a los usuarios definir sus propios plugins para su uso en un paso en particular en nuestro flujo de trabajo producto. Por lo que las plantillas de usuario se cargan en nuestro sistema, y se procesan de esta manera:
using Microsoft.VisualStudio.TextTemplating;
class UserPluginWorkflowComponent : ICallbackInterface
{
public void CallbackFxn()
{
// invoked by user plugin
}
public void ExecuteUserPlugin()
{
MyCustomHost host = new MyCustomHost(this);
host.TemplateFileValue = "UserPluginTemplateFilename";
Engine engine = new Engine();
string pluginResult = engine.ProcessTemplate(
userPluginTemplateFileContents,
host);
if (!host.Errors.HasErrors)
{
// use pluginResult in some meaningful way
}
}
}
entiendo algo de lo que ha dicho, pero podría por favor, profundizar en esto: 'No se puede simplemente pasar de referencia existente en el motor T4 a menos que anfitrión usted mismo'? Además, solo quiero que lo sepa, tanto el archivo .tt como la clase de usuario forman parte de la misma solución – brainydexter
Right. Bueno, no hay forma de entregar la referencia. La plantilla T4 en realidad se ejecuta en su propio dominio. Por varias razones. Si aloja el procesamiento T4, debería poder pasar una referencia al procesamiento, pero eso no es algo que haya visto antes. Lo mejor que puede hacer es referenciar un conjunto con las cosas que desea utilizar o agregar, como parte del código auxiliar de clase T4. Oleg Sych bloguea sobre T4, busca detalles sobre cómo hacerlo http://www.olegsych.com/2008/02/t4-assembly-directive/ –