Using 6.0 nightly revision 13736
Being able to edit the templates in visual studio proper has been a loooong time wish of mine, and even where I am with the issues I'm facing this is still a huge step in the right direction for me. That being said, I'm running into significant roadblocks while using visual studio for template editing. Some of them are similar to longstanding template development headaches from codesmith in general.
Assembly Reference Headaches -
Heres a screengrab of the solution to help explain.
Basically I have two projects, the top one is just a placeholder for all of the template editing that I do, and the bottom project is a class library being compiled for use in the templates. I added a vs project reference to the codesmith project which references the class library project (this copies the .dll to the template's /bin/<build configuration> directory).
So far so good, nothing too crazy here, just a single template, which inherits from a template defined in code that exists in a seperate project.
The code for the compiled class library isnt that relevant, it defines a class that inherits from CodeTemplate (which is in turn used as the base for the .cst).
So far so good, I can compile my template, render my template. But now I need to edit some of the compiled base template code, so I change some of the attributes on one of my properties defined in MigrationProjectTemplate.cs (class library). So I make my changes, they compile, however when I try to refresh my local copy with the newly build changes, I find that I cant - something is holding a lock on the old .dll, referenced from my .cst.
I can't delete it, rename it, etc.
Closing all open files in the solution has no effect.
Doing a 'clean solution' has no effect. The lock on the library is from inside of the codesmith plugin, and unfortunately since I cant force the codesmith plugin to stop referencing the library, that means that devenv.exe is holding the lock, and now the only way to get rid of that lock is to shutdown/restart visual studio.
For what its worth, doing a cs /clearcache from an admin console while experiencing this problem fails to clear cs's internal cache, saying access is denied to the cached version of this same .dll.
The end result is that if I want to do template development inside of the ide, and need to update a referenced assembly dll, I have to close down my entire development environment, copy the file over, and then open vs back up. If there was a way to force the in-process codesmith to kill its internal references to the assembly, then there would be a working manual workaround, but even thats kind of a brute force solution. In my opinion, when a project containing templates is 'cleaned', codesmith should clear its working cache for any templates in that project, and release any locks on libraries referenced in templates in the project.
http://www.jheidt.com------------------------------Member of the .NetTiers teamhttp://www.nettiers.com------------------------------
We'll take a look into this and let you guys know what we find.
CodeSmith Tools, LLC. Software Development Engineer
.NetTiers team | Visit http://www.nettiers.net
Thanks for the response. The class library is set to build in the add-in's folder. The modified date is updated each time the library is built. I am referencing the assembly in my template and generating from within visual studio.
I have compiled the library 3 different times without making any changes to the source and it will always update the modified date.
We took a look into this and found that this behavior is a result of the referenced template assembly is already loaded in the gac. Thus when the newly compiled template instance is created, the in memory assembly is used. We may change this behavior in a future version of the template editor. As a work around, you can generate a template from a CSP file as that uses a separate AppDomain for generating.
My referenced assemblies in my original example are not strongly named, let alone placed in the GAC and this behavior still affects me.
This currently isn't supported until we support out of process support (even when references placed in the GAC). Its a limitation of .NET to not be able to unload unused assembly references. This holds true for any application (you have to restart the application to load a newer assembly or new up a new AppDomain).
Thanks for getting into this and replying. I have to say that its a bit dissapointing, but it is what it is. From writing a few add-in/plug-in based applications I know the pain of dynamic assembly binding, so I understand it can be tricky.
A few quick questions then, since this means that basically I have to fall back to the old code-behind/include source file method, which is really less than ideal since I lose some IDE/tooling support since everything needs to be slapped into one file, and when any referenced utility projects are updated I will need to restart the ide or also include those entire projects source-code in the Src=... source file. Anyways, you see where I'm coming from on this.
My questions then:
1) Assuming you are creating a seperate appdomain for the compiled template and its references, would it be possible to turn on shadow loading of the referenced assemblies so at least there are not hard locks on the actual files, ie: what IIS does with ASP.NET references, you get for free, since fusion will redirect/rebind the classes/modules/etc to the updated assembly? I haven't really looked at how Generator is binding the generated assembly for the template, but in theory this would be possible, hopefully.
2) Could you please look into the Debug.Write / Trace.Write issue I mentioned earlier? I think I brough it up in an e-mail, and you wanted to check to see if Resharper was preventing the trace output, I created a fresh virtual machine Win7 image and installed vs2010 w/sp1 & updates, no extensions or add-ins except Generator and still receive no Trace/Debug output from templates (Debug="true" is set). I know that the debug statements are getting execued because if I fire up SysInternals DbgView.exe I see my messages.
3) What is the attribute syntax for the new property grid to tell the grid to use the UI it uses already for a given type, but to show that design time editor for a different type of property.
Example: When I create a property of type HashSet<string>, the design time UI doesnt grok that type, but the editor for List<string> should work since they share a few interfaces,
also is there a list of the UI editors (example: [Editor(typeof(DropDownListPropertyEditor), typeof(System.Drawing.Design.UITypeEditor))] ) that are provided out of the box?