Reference not found using VolatileAssembly

Jan 27, 2010 at 11:55 AM

I'm using VS2010 Beta 2, with the last version of T4 Toolbox (9.12). When I use VolatileAssembly I have to specify the building directory to reference a dll, also if I have setted CopyLocal = true in the project reference to the same dll.

This works:

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\Debug\MyAssembly.dll" #>

 

This does not:

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="MyAssembly.dll" #>

 

Any suggestion?

Coordinator
Feb 1, 2010 at 12:23 PM

Sure, use the first option :). Seriously though, what is your concern about it?

Oleg

Feb 1, 2010 at 1:39 PM

"bin\Debug" is the folder where the application build, and where any reference is copied during the building process. In the documentation about VolatileAssemblty it's write that is sufficient "add a reference to CodeGenerationLibrary from the project that contains the T4 template and set CopyLocal=true", in my case to MyAssembly, but it's not work. The MyAssembly.dll is present in the building folder but it's not found when the template is execute; I have to specified the relative path of the building folder. So, my question is: the documentation is wrong or I'm making the wrong think? And if the documentation is not wrong, I have to specify every relative folder of building (one for debug x86, one for release x86, one for debug x64,...)?

Thanks for the assistance. ^__^

Cristiano

Coordinator
Feb 2, 2010 at 12:26 AM

This may have been already reported here: http://t4toolbox.codeplex.com/WorkItem/View.aspx?WorkItemId=15622

Until it's fixed, please use relative path as a workaround.

Oleg

Apr 18, 2010 at 11:39 AM
Edited Apr 19, 2010 at 8:23 AM

Hi,

I installed VS2010 RTM last week and I migrated our VS2008 solution successfully. Unfortunately, I also got the same VolatileAssembly issue mentioned in this case, so I installed the lastest version of T4Toolbpox (V10.3), but the error won't go away.

The situation is as follows:

- We have a template project where the base templates are stored.
- We have multiple projects which include T4-Templates in differently deep folders. These T4-Templates are all including the base templates using a relative path.

So to illustrate this, let's assume we have a Project T with a base template and two project A und B, each with one template (which include the base template):

- T\BaseTemplate.tt

- A\Folder1\TemplateA.tt

- B\Folder2\Folder3\TemplateB.tt

In TemplateA.tt, we include the base template like this: <#@ include file="..\T\BaseTemplate.tt" #>
And in TemplateB.tt, we include it like this: <#@ include file="..\..\T\BaseTemplate.tt" #>
In BaseTemplate.tt, we need to reference the assembly from Project A, so we put this line into BaseTemplate.tt:

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" Name="A.dll" #>

As mentioned, when I tried to run TemplateA or TemplateB, I always get the same error: VolatileAssembly directive: Assembly 'A.dll' resolved as 'A.dll' could not be found. 

Note: All project assemblies are compiled into a common output directory, not into individual bin/debug folders

Thanks for further help,


Reto

Apr 21, 2010 at 3:33 PM

I posted this as an issue #17332, and I posted a patch for it as well.

Coordinator
Apr 21, 2010 at 10:09 PM

Reto,

Thanks for digging into this. Can you achieve the same result by using $(ProjectDir)$(OutDir) in the name parameter of the VolatileAssembly directive instead of hardcoding it in the directive processor?

Oleg

Apr 22, 2010 at 12:06 PM

Hi Oleg,

Yes, you can of course, but I figured as the main purpose of the VolatileAssembly directive is to reference one of your own assemblies from within your project or solution, it should be a default functionality from the directive processor to look for the assembly in the projects output directory, don't you agree? Actually, I first thought that's what ResolveAssemblyReference() is all about, but evidently it doesn't look in the output directory, even though that's really the first place to look, no?

Reto

Coordinator
Apr 22, 2010 at 1:45 PM

I guess it depends on why you need to reference the assembly from your template. If the assembly contains only code generation utilities, used only at design time, I would not expect it to be in the project's output directory. I would like to think more about it and hear what other people's thoughts are.

Oleg

Apr 22, 2010 at 5:30 PM

I agree that this is not a very common usage. On the other hand, one of the reasons VolatileAssembly exists is because of this, as you mention in your blog http://www.olegsych.com/2008/02/t4-assembly-directive/:

quote from the blog:

Assembly Locking

In order to improve performance, T4 engine reuses templating AppDomain for multiple template transformation, which causes all referenced assembly files to be locked. This presents a problem if you are using your own assembly during code generation, because the assembly file cannot be recompiled until the file is unlocked by T4. You can force T4 to unload the file by closing and reopening the Visual Studio solution or by restarting Visual Studio itself. Alternatively, consider using VolatileAssembly custom directive available in T4 Toolbox, which creates a shadow copy of the assembly before loading it.

I don't have a strong opinion on this matter, I can also live with adding the $(ProjectDir)$(OutDir) to the VolatileAssembly directive inside my tt-Files, but I figured it could be quite handy if this is a standard behaviour, especially as this also allows you reference other 3rd party assemblies in your project which are not in the GAC.

Reto

Coordinator
Apr 23, 2010 at 4:35 PM

I wouldn't be opposed to changing it if other people weigh in.

Oleg

Apr 23, 2010 at 8:36 PM
Edited Apr 23, 2010 at 8:39 PM

All --

My opinion does not count for much on the matter as such use is far beyond the scope of our T4toolbox usage in this shop.

That said, and in that context, and with all due respect to the nice gentleman at hand, I still would "weigh in" by saying-- YAGNI

:-)

HTH.

Thank you.

-- Mark Kamoski

 

May 20, 2011 at 4:19 PM

Hello there,

From what I can gather from the comments in this thread, VS Macros will work in the name of the VolatileAssembly Attribute, but they are not??

I started out with $(TargetDir), changed it to $(ProjectDir)$(OutDir) as Oleg has suggested, but still with no luck. 

I am trying to get it to transform on build locally, (I will tackle the automated build server afterwards). Just in case, I repaired my SDK install to include any latest fixes.

This is my csproj snippet (if it helps):

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- process *.tt templates on each build  -->
  <PropertyGroup>
    <TransformOnBuild>true</TransformOnBuild>
    <!-- <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
    <OverwriteReadOnlyOuputFiles>true</OverwriteReadOnlyOuputFiles> -->
    <IncludeFolders>C:\Program Files\T4 Toolbox</IncludeFolders>
  </PropertyGroup>
  <ItemGroup>
    <!-- Add VS\...\PublicAssemblies to the list of places
			 to look for assemblies used by templates.
    <T4ReferencePath Include="$(VsIdePath)PublicAssemblies\" />
    <T4ReferencePath Include="$(ProjectDir)$(OutDir)" /> -->
    <DirectiveProcessor Include="T4Toolbox.XsdProcessor">
      <Class>T4Toolbox.XsdProcessor</Class>
      <CodeBase>C:\Program Files\T4 Toolbox\Bin\T4Toolbox.10.0.dll</CodeBase>
    </DirectiveProcessor>
    <DirectiveProcessor Include="T4Toolbox.DteProcessor">
      <Class>T4Toolbox.DteProcessor</Class>
      <CodeBase>C:\Program Files\T4 Toolbox\Bin\T4Toolbox.10.0.dll</CodeBase>
    </DirectiveProcessor>
    <DirectiveProcessor Include="T4Toolbox.TransformationContextProcessor">
      <Class>T4Toolbox.TransformationContextProcessor</Class>
      <CodeBase>C:\Program Files\T4 Toolbox\Bin\T4Toolbox.10.0.dll</CodeBase>
    </DirectiveProcessor>
    <DirectiveProcessor Include="T4Toolbox.VolatileAssemblyProcessor">
      <Class>T4Toolbox.VolatileAssemblyProcessor</Class>
      <CodeBase>C:\Program Files\T4 Toolbox\Bin\T4Toolbox.10.0.dll</CodeBase>
    </DirectiveProcessor>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
  <PropertyGroup>
    <PreBuildEvent>
    </PreBuildEvent>
  </PropertyGroup>

Using Absolute References is not an option for me, I don't know how to carry on from here... :(

<#@ volatileassembly  processor="T4Toolbox.VolatileAssemblyProcessor"  name="$(ProjectDir)$(OutDir)adazzle.mediaApp.Entities.dll" #>

 


 

May 20, 2011 at 5:21 PM

Hi erynmacdonald,

It's a while back, and we're not using that code anymore, but I just checked the template code which worked at that time for us.

This is how we referenced the assembly:

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" Name="$(TargetDir)MyOwnAssembly.dll" #>

<#@ import namespace="MyOwnAssembly" #>

It seems that your sample looks the same, so I'm not sure why it won't work on your side.

Regards,
Reto