I'm having a bit of trouble with a T4 template I'm trying to write. The T4 template uses a bit of reflection to load an assembly and any referenced assemblies. It seems to work fine when I debug the template (Right click the template and click "Debug T4 Template") however when I just save the template or right click and select "Run Custom Tool" it throws an exception.
It has trouble resolving a dependency, specifically loading Autofac. I have a feeling that for some reason when NOT debugging AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve
and AppDomain.CurrentDomain.AssemblyResolve
is not being called as I would have expected.
My code is below:
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(TargetDir)Project.Data.dll" #>
<#@ assembly name="$(TargetDir)Autofac.dll" #>
<#@ assembly name="$(TargetDir)Autofac.Configuration.dll" #>
<#@ import namespace="Project.Data" #>
<#@ import namespace="Project.Data.Providers" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<#
WriteLine("/*");
var assembly = Assembly.ReflectionOnlyLoadFrom(@"F:\path\to\project\bin\Debug\Project.Data.dll");
var assemblyResolve = new ResolveEventHandler((object sender, ResolveEventArgs args) => {
var assemblyFullyQualifiedName = args.Name;
var assemblyName = assemblyFullyQualifiedName.Split(new []{", "}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
try {
return Assembly.ReflectionOnlyLoad(args.Name);
} catch {
return Assembly.ReflectionOnlyLoadFrom(Path.Combine(@"F:\path\to\project\bin\Debug\", assemblyName + ".dll"));
}
});
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += assemblyResolve;
AppDomain.CurrentDomain.AssemblyResolve += assemblyResolve;
try
{
var interfaces = assembly.GetTypes().Where(t => t.IsInterface);
}
catch (Exception ex)
{
if (ex is System.Reflection.ReflectionTypeLoadException)
{
var typeLoadException = ex as ReflectionTypeLoadException;
var loaderExceptions = typeLoadException.LoaderExceptions;
foreach(var exception in loaderExceptions){
WriteLine(exception.ToString());
}
}
else
{
WriteLine(ex.ToString());
}
}
WriteLine("*/");
#>
namespace <#= assembly.GetName().Name #>
{
public partial class DataProvider
{
}
}
And the specific error that is occurring is:
System.IO.FileNotFoundException: Could not load file or assembly 'http://file/F:\path\to\assembly\Autofac, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da.dll' or one of its dependencies. The system cannot find the file specified.
File name: 'http://file/path\to\assembly\Autofac, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da.dll'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.ReflectionOnlyLoadFrom(String assemblyFile)
at Microsoft.VisualStudio.TextTemplatingFD5544346661EEC20F954BD62AA5EAB89B5E8944DC6D4E6787D6BFE5AED9146D94FC53BA12AC5453238920966C27888A177DBCB5F2BBB916506741D67C179387.GeneratedTextTransformation.<TransformText>b__0(Object sender, ResolveEventArgs args) in f:\dev\project\src\project.Data\DataProvider.tt:line 25
at System.AppDomain.OnReflectionOnlyAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
Any help is much appreciated.
Aucun commentaire:
Enregistrer un commentaire