Why are some references missed when running my application? - visual-studio

I have the following project structure using a Domain Model, StructureMap and Fluent NHibernate:
The problem I'm having is that Fluent NHibernate requires all of the following to be the bin directory of the website for it to work at runtime:
Antlr3.Runtime.dll *
Castle.Core.dll
Castle.DynamicProxy2.dll
FluentNHibernate.dll *
Iesi.Collections.dll *
log4net.dll *
NHibernate.ByteCode.Castle.dll
NHibernate.dll *
The problem I'm having is that not all of these assemblies are output to my website's bin directory. Currently only the items with a * are output correctly. The items in bold are missing from the bin directory.
Now, I would of assumed that the reason for this is because I have not added them as references to my Fluent NHibernate project. The only references I currently have are to NHibernate.dll and FluentNHibernate.dll. These two references alone are enough to bring through the items marked with a *, but they do not bring through the missing items.
So, I then thought that to get them to all come through I'd just add them as references to the Fluent NHibernate project. Unfortunately, this made no difference; the same items were still missing from the bin directory.
I've never really understood how visual studios decides which assemblies to copy over. I always assumed it was any assembly marked as Copy Local=true, but this doesn't seem to be the case in this scenario.
Of course I could just add all the assembly references into Website, but then that'd completed defeat the point of loosely coupling the projects through StructureMap.
Does anyone have any idea why the assemblies are missing and how I can get them to copy over correctly?

You can either add references to the project that requires those files be present in the output directory (Website in your case) or you can add a post-build step in your build script to copy them across.
This is a case of VS and the compiler being "smart" about whether references are actually required or not. The C# compiler optimizes out those references that aren't actually required. Adding a reference to non-required assembly in VS will ensure it appears in the output directory of that project. However, dependent projects will only get that same assembly if it's actually used by the project referencing it. That is, if the C# compiler hasn't optimized its reference out. That's why you would need to add the reference to the Website project, if you go that route.
Personally, I did exactly that. I don't really think this is tight coupling since NH still resolves the assemblies dynamically at runtime. And it's not like I can't just substitute in other byte code assemblies manually and restart my app. But it's also not like I would do that without adequate testing, so in a way I consider myself to be coupled to Castle on the basis of that. And, therefore, I'm not irked by the references.

Related

Avoiding build twice when using a shared project together with build generated code

I have a visual studio solution with multiple projects. One generates code files as part of pre-build (grpc classes via Grpc.Tools). There is also a shared project that extends the partial classes built as part of that pre-build.
However, sometimes for one reason or another - like compiling the client half of this (client uses the shared project to extend its own classes), compilation will error because the shared project can't find the generated classes yet. Presumably they don't exist. It's fixed easily by compiling the project twice.
Is there something I can do in this scenario? Is it possible to somehow move validating/compiling the shared project "further down" the compilation pipeline? Or even just set that particular project to try and compile twice if there's an error? Or is this the kind of thing that realistically I should just live with given what I'm doing - I haven't found any other references to this problem. It's not that big of an issue and it wouldn't happen very often, but I'd like to handle it reasonably if I can.
Edit
If I wasn't clear, this is a shared project, as in a .shproj, a project that is not compiled separately. The project that references it includes it and builds it all together as one.
If project B depends on project A, then project A must be built before project B. Visual Studio is smart enough to figure out the build order this way. Incidentally, this is also one of the reasons (among many) why circular dependencies simply cannot work.
I suspect that your projects are currently not linked via a dependency, as this issue wouldn't occur if there were such a link. Perhaps your second project is accessing the first project's files via the file system? That's just a guess though.
You can use this "A before B which depends on A" behavior of the build process to your advantage. Have project B (i.e. the project you need to go second) add project A (i.e. the project you need to go first) as a dependency. This forces VS to build them in the appropriate order.
Some remarks:
I am unsure if VS is able to omit dependencies that you add but not actually depend on (i.e. you never reference its content). I can't find any confirmation on this point (but absence of proof is not proof of absence!) But even if that is the case, that could be easily worked around by having a dummy class in B which actually references and uses something from project A.
Keep in mind that during a regular build, VS does not rebuild projects that have not changed since the last build. If this is an issue for you (unsure if it is, you didn't add enough context), make sure to always rebuild or clean to make sure that a new build will be triggered.
However, sometimes for one reason or another - like compiling the client half of this (client uses the shared project to extend its own classes), compilation will error because the shared project can't find the generated classes yet. Presumably they don't exist. It's fixed easily by compiling the project twice.
That it is only sometimes and can be fixed by "trying again" points at one thing - you got race condition. But a race condition during compilation, is not a thing I heard off or encountered before.
I got a few possible cultripts. But in the end, race conditions are notoriously hard to debug:
- Maybe the compiler that deals with the shared project returns before it is finished - wich should be impossible - or
- Maybe something causes the main projects to compile before the shared projects files are ready.
- Maybe a 3rd party tool - like a Virus scanner or auto backup maker inteferes?
- Maybe the shared projects compiled files are hosted on a network drive, and there sometimes is just the slightest delay between "compiled" and "visible to all other computers in the network"?
Usually the proper ways for dependant compilation should deal with such issues. That indicates that what you got there, is propably not the most stable setup.

How can you identify which project produces a particular dll?

Is there anyway within Visual Studio / TFS to identify which project produces which dll?
I'm aware you can look under a particular project's properties and see what the name of the dll is, but in the circumstance where you have loads and loads of projects this doesn't seem very efficient.
I've got the situation where I've got a project that references a dll, which includes a method I want to examine, but I don't know what project produces this dll.
Unfortunately, no. The only way I know is that you may could use a decompile extension. (Strongly not recommend to use) Through the source code after decompile, you can view namespace and judge which project produces the dll. (Under normal circumstances)
And you may also have to face some problems such as:
Legal issues
Need to pay for the extension
Only work for C#/.Net
The source code may be confusion and not standard
This should be a one time activity, you can go ahead and take a look into the project file, in case of C# project the csproj file.
If you do not want to do it opening each file, then i would say write a small tool to read all the project files and look for the name.
BTW, this will be different for different projects, and you need to find out the proper location to look.

Solution/MultiProject Template in VS2010

Looking to make a Solution/Multiproject Template.
While I'm aware a solution template does not exist, I've been researching/trying with some of success. (Link from here (http://stackoverflow.com/questions/2717110/how-to-create-a-solution-template-in-vs2010) have been a big help.
The only issue I'm facing is that, when creating a project from my template, the solution contains brand-new copies of all of the projects involved. What I require is that only ONE project is made as a fresh copy, and that the other projects in the template should reference already-existing projects.
I've made single project templates that hold the DLL references to other projects (which is fine, but it's not what I need.) I need a multi-project template where all but one project involved reference already existing projects...
How would I go about this?
edit:
I'm also finding that any dbml designer.cs that's added to a project are not included in the newly generated solution/projects. They are copied across, but I then have to manually include them in the project. Why is this, and how do I get araound it?
How about using the Feature Builder Power Tool? http://visualstudiogallery.msdn.microsoft.com/67b720f4-9a50-41cb-86a2-82e33b7c5fc4/
It should give you all the freedom to create whatever logic you want during solution setup...
So I couldn't find a workaround for this issue.
What I have managed to do though is make a decent enough template that should be run once, with all references (being relative) pointing to an outside lib folder.
This means I can use the template on a new machine, copy some dlls to a new lib folder, and then work away from there. Not an ideal solution, but it works...

Visual Studio - Can't remove binary reference from website project

I'm planning to test an upgrade from NHibernate 2 to 3. First port of call seems to be to remove the reference to NHibernate.dll from the website project.
If I simply delete the file from the bin folder, it reappears when I build the website. So the website knows it's supposed to be there. If I open the properties for the website and look at the list of references, NHibernate.dll is not there. In fact, none of my binary references are there, only the project and .NET references.
That's me stuck. Anyone help?
Could it be that you have other libraries referencing NHibernate (e.g. BusinessLogic or DAL)? If so, you need to change the reference there.
If that is not the case, try replacing it in the bin folder directly. Don't forget to replace the other DLLs as well (Iesi.Collections.dll for 3.1 and Iesi.Collections.dll, Remotion.Data.Linq.dll, Antlr3.Runtime.dll for 3.0, and the DLLs for the proxies (lazy loading).
By the way, something that proved to be helpful in such situations is having a designated folder for all external DLLs that do not belong to the .NET Framework and referencing the DLLs from there. In doing so, when updating you only need to replace the DLL in that folder and it will automatically be used.

Visual Studio solution structure using Codesmith frameworks (NetTiers / Plinqo)

I have been using the Codesmith framework NetTiers to generate a DAL etc., into a folder called, say, 'NetTiers', outside my main project's folder, and referencing the DLLs within that folder from my main project.
I've started using the Plinqo framework, and want to use the generated files from that framework within the same project as the one I'm using with NetTiers. (The reason I'm using both frameworks is that I want to get/learn the newer LINQ goodness from Plinqo, yet also have the familiar NetTiers code DAL, BLL syntax available, for compatibility.)
My question is: what's the best Visual Studio solution and file structure to use when using Codesmith templates like these? Should the frameworks' generated code be contained outside the main project and added as projects to the overall solution? Or should each template's generated code have its own solution? Should the generated files be within the main project's file structure?
I've tried combinations of each of these, and they each have their pros and cons. I'd like to know if there's a tried and tested pattern.
When it comes to .netTiers, I always compile the generated solution and add the assemblies as references to my project. This makes it much easier to upgrade/diff and regen.
However, there are going to be some cases where you would want to add your custom logic so keep this in mind.
Thanks
-Blake Niemyjski
I tend to just keep the .csp and the generated folder outside of my main app's folder. When adding a reference Visual Studio copies in the .DLLs from the built generated code. All of the generated projects sit under a main folder such as D:\CodeSmith Projects\
If you want to version control the .csp file it might be beneficial to move it in with the rest of your version controlled app files to tie it all together.
We put the generated projects inside our solution. In fact on my current project I generated the nettiers files to the location that I wanted the files to be, and Started adding my own project files to that...But we have always kept the files in the solution, that way if i need to add something to the code in the concrete classes I can do it without having to open a whole new project.
We have tried both scenarios. We settled for including the assemblies in a dependencies folder, which was shared by multiple projects.
We had problems with TFS when the projects were included in the solution. the downside, is that you can't so easily step into the .NetTiers generated code when debugging, though after a while you get used to this, and accept that whatever is in .NetTiers stays within .NetTiers!

Resources