We have an app A that has a reference to an assembly B that contains some static methods. Assembly B is in the same Visual Studio solution as app A.
We want the users of our app A to be able to write plugins. They build the plugin (at present) by creating a new Class Library solution in Visual Studio, getting the Nuget Package for app A, and adding a reference in their plugin solution to assembly B, so that the plugin code compiles.
They do not need to test their plugin, which is why the code just needs to compile, although it would be nice if they could debug their code when running it in app A.
Once their code has compiled, the DLL for the plugin is put in a share and given to a different team (bureaucracy I know) who put it with the rest of app A's DLLs.
I would like the plugin DLL to use the assembly B DLL that is with all of app A's DLLs.
When I run app A, the Activator class picks up the plugin DLL and correctly creates an instance, but as soon as one of the static methods from assembly B is called, the plugin throws a MissingMethodException.
Things I have tried:
The plugin solution definitely works fine if you create it and compile it within application A's Visual Studio solution.
App A uses framework .Net 4.5, assembly B uses framework .Net 4.0, I have tried building the plugin with both frameworks without success.
The "Specific Version" of the reference to assembly B in the plugin solution was false in all cases tested.
I would welcome immediate solutions to this problem but also broader architectural suggestions on how to get these plugins to work. I apologise if there is a duplicate question of this, I couldn't find one.
For starters you can use "Dotpeek" to decompile dll and see if the method defination exactly matches.
It's a free software available to decompile dotnet libraries.
If you don't have access to .pdb file then i would recommend using "dotnet reflector",or "IL Spy" it will decompile without pdb files.
Also do make sure you are referencing project in visual studio not the output dll.
I managed to fix my problem as follows:
Although the plugin only directly used static methods in Assembly B, these static methods actually made a chain of calls to various OTHER assemblies.
Instead of just adding a reference to Assembly B in my plugin, I did a Nuget command:
Install-Package -Id AppA -ProjectName Plugin
And this downloaded the latest AppA to the packages folder and added a reference to EVERY dll of AppA.
Like before, it compiled, but this time when I dragged the plugin dll into the AppA bin folder, the plugin code ran without throwing an exception.
Related
I created a class library project using C# and .Net.
In this project I used two external dependencies(to be more specific: Microsoft.Win32.Registry(4.6.0) and System.Data.SqlClient(4.7.0) Nuget packages).
After I build this project, I can see the generated DLL file under /bin/debug folder.
Now I want to import this generated DLL in another project and consume its methods. Once imported and I run this project, it complains about not being able to find those two external dependencies I had in class library project.
As a temporary fix, I can import these two missing references in this project and it will work fine and as expected. But this is not what I want(and I guess is not a clean solution as well).
I want to know why the dependencies of class library project is not reflected in generated dll file? And is there any way to fix this?
Many thanks for your help.
If your class library is in the same solution or source control repository as the app that's using it, you should use a project-to-project reference, rather than referencing the assembly directly. As the docs say, this way it automatically detects changes to the class library when you compile the app, but what the docs didn't say is that dependencies flow though as well.
Otherwise, as Lance Li wrote, you should create a NuGet package from your class library. Unfortunately there's a bit of a barrier to get started. Creating the package is easy, but then you need to publish the nupkg file somewhere. For early development (before the package is ready to be shared), the easiest option is to use a local file feed. You'll then need a nuget.config in the app that will use the package to add that local feed as a source, then you can install the package in your consuming project, which will bring dependencies.
As you can see, for development, this is slow and difficult because if your consuming app finds a bug in your package, or if you're trying to develop a new feature in both the consuming app and class library at the same time, it means every time you make code changes to class library, you need to increment the version number, pack a package, publish the package, then update the package version in the consuming project. It's far, far easier to use a ProjectReference which lets you simply edit code, compile, run. Nothing else to think about.
See this, the way you reference that assembly is not a recommended way when both the projects are in same machine.
You're using the file reference(Add reference => browse...). And that's why you have to import these two missing references in this project manually.
So I suggest you add the project reference, if both the two projects are in same solution, you can right-click current project=>add reference=>project tab find that assembly you need.(instead of browsing...)
If the referenced project is not in same solution. Right-click solution in solution explorer=>add existing project to import it. Then add project reference.
Background info (might be relevant):
Using Unity 2017.2 with "Scripting Runtime Version" set to "Experimental (.NET 4.6 equivalent)"
Writing code in Visual Studio 2017 (not MonoDevelop)
I have a Unity project that makes direct use of a third-party DLL ("library A"), which I've added to the project's Assets folder. Library A depends on another DLL, "library B", which I've also added to the Assets folder. Library B is not used by any scripts in the Unity project. Both libraries A and B are written in C# and target .NET 4, i.e., they're both managed code.
Once added to the Assets folder, both libraries A and B are listed under "References" when the project is opened in Visual Studio and "Copy Local" is set to "True" for both (although I don't know if Unity uses that property).
However, when running the project in the Unity editor, various calls to library A raise exceptions that indicate that library B isn't available. The only way I've been able to get it to work is by placing a copy of library B in C:\Program Files\Unity\Editor (the directory containing Unity.exe, the Unity editor executable).
I've used libraries A and B in other, non-Unity projects and never had any issues (Visual Studio copies them both to the output directory as long as they're referenced). Am I missing a Unity-specific step that's necessary to tell it that library B is required?
I ran into this same issue today, and here's what fixed it for me: In the Unity editor, navigate to where the library B is located, select the library, and on the Inspector window under "Plugin load settings", enable the "Load on startup" checkbox. I suppose this is needed because no Unity scripts are directly calling library B.
I just wanted to share how i get this done. I'm using Unity 2019.2.10f1 by the way.
I have many of my own and third party managed dll files in my project, and I copy them all to ProjectFolder\Assets\Resources\
and I've never had any problem calling out to any of the libraries, or those libs calling each other.
Maybe the issue is that since your second library (library B) is not referenced by any scripts, Unity is not bundling it and making it available at debug/runtime.
In my experience, I have found that if you want something to be retained in your build, (any unreferenced assets that may be consumed dynamically at runtime), stick it in the Resources subfolder of Assets.
A second option may be to construct some dummy call to the second 'Library B' (that does nothing, perhaps construct and dump), so that Unity thinks that it is needed and includes it in your build.
Not sure if that helps, but Good Luck!
Unity actually has a special folder called "Plugins" directly under the Assets folder that you can use. This will allow you to add references to dlls made outside of Unity and link against them. You can even have them sorted by targets!
Assets/Plugins/x86
Assets/Plugins/Android
...
The plugins accepted are all these following extensions: .dll, .winmd, .so, .jar, .aar, .xex, .def, .suprx, .prx, .sprx, .rpl, .cpp, .cc, .c, .h, .jslib, .jspre, .bc, .a, .m, .mm, .swift, .xib, .dylib, .framework, .bundle, .plugin
Unity 2020.3 Plugins Documentation
I have more than one .Net projects to work and i want to reference these all projects into one integrated project and add them as a reference in this project and want to run any method or function from this integrated project.So i have added all these projects in the same solution in the directory and added them to the solution and added as a reference.
Now My question
I havent converted those projects to class library as i want the main method to be there to kickoff that function from my integrated project ,if i make it class library will i still be able to access that main method???
I did add those projects reference and made them to class library and also as exe,but in both the cases , when i did import them ,but when i try to call those functions,it doesnt create an instance and doesnt show any options in intelligence,on top of that,once i try to build it back again,it throws an error "The type or namespace name could not be found(are you missing a using directive or an assembly reference?)"
Can someone please answer them !!!!
Internally there is little difference between a .NET exe and a .NET DLL. For most purposes a .NET .exe is just a .NET dll with some data saying "this class has the main function". It is one of those things they copied really well from Java and improoved upon.
There might be secondary differences (I am not sure the .exe provides full COM/.NET interop support, for example). But for most purposes, you can use a Compiled .NET exe like a compiled .NET dll. Including putting it into the references of a 3rd project.
The main issue here is that only the compiled code in the propert directory is considered. Especially if you still plan on working on those backend References, you need to be aware if you referenced the Debug or Release version of the .dll/.exe
I have two C# projects, A and B, in VisualStudio 2010. Project A is a class library. Project B is a ReSharper-Plugin project that references project A (ProjectReference). Both projects compile and worked property when I ran project A in the Experimental Instance.
Now, recently I renamed a static class, with some extension methods, in project A. Both projects still compile. But when I run project B I get an TypeLoadException for the new class name. When I change the class's name back, everything works fine again.
My guess is that project B is compiled against the new code, but run against an outdated dll. I tried everything from clear, over rebuild, to restart, but to no avail. I also manually checked that a fresh dll from project A is placed in project B's bin/Debug folder, which is the case. And I copied over the dll manually, after building project A. The problem persists.
Now I ask myself whether there is another location where the dlls are copied to before running the Experimental Instance. Is this the case? If so, where to? Are there any other places where the old version could come form? Or is there even something completely different that could cause the problem?
Thanks in advance!
Ok. Did you reference the DLL or the Project? In a Visual Studio Solution you can reference projects. If you reference project A in project B then B should always use the latest code from project A.
I managed to figure it out myself, thanks to the right keywords on Google (MissingMethodException and ProjectReference) that led me to a blogpost about a solution to the same symptom. In my case it was not the GAC that caused the problem, but the cached assemblies under
C:\Users\{name}\AppData\Local\Microsoft\VisualStudio\10.0Exp\
This is the location where all the assemblies of the Experimental Instance go. Here lay an outdated VsExtension that depended on project A and within it there was an outdated copy of project A that was loaded. The loading of the new version from the project reference was simply skipped, since a copy of the assembly (with the same version) was already loaded.
So the problem was ultimately caused by the removal of the extension from my solution. From this point of the extension was no longer updated by VS, but it was also not removed! Lessons learned: After major changes of your infrastructure you may want to delete all cached assemblies below the above path...
Thanks for the help, everyone!
I have a dll containing classes to access data in SQL (a sort of ORM system) included in my .cs page with a using statement. For some reason the dll (with definition for a new field) isn't seen by the cs code, though I've uploaded the new dll in bin. It won't see my new field in the dll's helper classes (now compiled into the dll).
Is there a way to troubleshoot the dll, or the cs to tell why this won't see the class I updated and rebuilt? The class works fine locally and on another server, but on my prod server, it bombs.
This is using Sitefinity 3.7 with a Subsonic/Substage module if that sheds some light on it.
If you are using Visual Studio, verify 2 things, first:
try deleting csproj.user and .suo files (visual studio will recreate them)
The second thing is the version of the framework your project is running, and the version of the framework the dll was compiled in.
If your project is using .NET 4.0 but the DLL was built using 2.0 or similar you may not be able to use it, you can add it, but it wont be loaded.
This sounds so familiar... have you check to see if there is another dll on the path that gets resolved? Dynamic-Link Library Search Order
Make sure that your dll was not registered on the production service in the GAC.
How to extract an assembly from the GAC?
Perhaps you have a local copy of the DLL in your project and the DLL that gets updated is elsewhere.
I tend to think the dll you build is 32 bit (X86) dll. where as you are trying to consume it from project that targets "Any CPU".
Is your production server a 64 bit ?
If answer is yes, goto project properties => Build tab (of your cs code's project which is not understanding the dll) and set the Platform target as X86.
If the updated DLL has a different version number, you may need to update the Project Reference to it by deleting and re-adding a reference to the DLL in the bin folder.
If the project generating the DLL is present in the same solution, you may have an issue in creating a file reference (may not be updated) instead of a project reference (will be updated).
fuslog.exe is a great tool when troubleshooting assembly (dll) binding issues.
http://msdn.microsoft.com/en-us/library/e74a18c4.aspx
Another .net developer helped me figure this out. I had a rogue ToString() in there where there should have been a cast to string, allowing nulls. My dll was okay after all. Thanks everyone for your suggestions, I learned a lot.