F# dll in F# script - c#

I have a C# dll that I need to reference in F#. I can do this fine in a .fs file, but I can't seem to get it to work in an F# script (.fsx) It is strange because in my script, I have no problem referencing F# dlls. I thought C# dlls and F# dlls were essentially the same.
EDIT:
I have two dlls (1) csharp.dll and (2) fsharp.dll built with csharp and fsharp respectively. I reference them with:
#r "bin\Debug\csharp.dll"
#r "bin\Debug\fsharp.dll"
which the compiler recognizes. The line where this occurs looks like this:
let new_object = new fsharp.type(Observable<csharp.type>)
Where I'm creating an object defined in fsharp.dll which takes an observer of a type defined in csharp.dll. When I try to run it in FSharp interactive, I get the following error:
error FS0074: The type referenced through 'csharp.type' is defined in an assembly that is not referenced. You must add a reference to assembly 'csharp'.
The thing that doesn't make sense is that csharp.type had been used successfully in a previous line. But when we introduce the csharp.type with an fsharp.type, I get an error all of a sudden saying the csharp type is missing an assembly reference, even though the problem seems to be with the fsharp.type.

It seems you'll need also refer in the script System.Reactive.dll or wherever the class Observable<T> is defined

#Petr is correct. You need to add all references, and their references.
If you are using Visual Studio, I suggest that you install Visual F# Power Tools. When installed, right-click 'References' under your project and choose to 'Generate references for F# interactive'.
This will generate (and keep updated!) the files
{ProjRoot}/Scripts/load-references.fsx
{ProjRoot}/Scripts/load-project.fsx
So in your F# script (assuming it is in the project root), you just do
#load "Scripts/load-project.fsx"
These generated files should go into your version control of choice.

Related

How to set assembly references for Visual Studio solution using CMake?

I'm working with C code where the production compiler and CI runs in Linux but the development environment is Windows and VS. The test framework used is NUnit, which is written in C# and imported as a DLL via Nuget.
I'm used to C and writing target oriented CMake but VS solutions and .NET is unknown territory for me and the weird mix of C and C# doesn't make things easier. To complicate things further there is a tool generating a mock for the platform code which the C code is to run on (I think the platform Mock is written in C++).
So, I'm using CMake 3.15.3 and Visual Studio 2017, and the setup I need to get working is the following.
A top CMakeLists.txt like:
cmake_minimum_required(VERSION 3.3)
project(MyApplication)
include(SUTWrapper)
add_subdirectory(source)
add_subdirectory(suttest)
A CMakeLists.txt in ./source/ like:
find_package(PlatformInterface)
add_library(${CMAKE_PROJECT_NAME} STATIC
MyApplication.c)
target_link_libraries(${CMAKE_PROJECT_NAME}
PUBLIC
PlatformInterface)
A CmakeLists.txt in ./suttest/ like:
enable_language(CSharp)
add_executable(${CMAKE_PROJECT_NAME}_tests
MyApplication_suite1.cs
Program.cs
TestUtils.cs)
add_sut_wrapper()
add_test(
NAME
Test${CMAKE_PROJECT_NAME}
COMMAND
MyApplication_tests.exe
CONFIGURATIONS
Debug)
And in the cmake folder containing all the CMake modules, the file SUTWrapper.cmake:
function(add_sut_wrapper)
set(PATH_TO_WRAPPER path/to/wrapper/here)
add_library(${CMAKE_PROJECT_NAME}_wrapper STATIC
${PATH_TO_WRAPPER}/foo.cs
${PATH_TO_WRAPPER}/bar.cs
${PATH_TO_WRAPPER}/baz.cs)
set_property(
TARGET ${CMAKE_PROJECT_NAME}_wrapper
PROPERTY
VS_DOTNET_REFERENCES "System")
set_property(
TARGET ${CMAKE_PROJECT_NAME}_tests
PROPERTY
VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")
set(PATH_TO_PLATFORM_MOCK path/to/PlatformMock/here/)
add_library(${CMAKE_PROJECT_NAME}_Platform_Mock STATIC
${PATH_TO_PLATFORM_MOCK}/Swc_${CMAKE_PROJECT_NAME}.cpp)
add_library(${CMAKE_PROJECT_NAME}_shared SHARED
../source/MyApplication.c)
target_link_libraries(${CMAKE_PROJECT_NAME}_shared
PUBLIC
PlatformInterface
${CMAKE_PROJECT_NAME}_Platform_Mock)
target_link_libraries(${CMAKE_PROJECT_NAME}_tests
PUBLIC
${CMAKE_PROJECT_NAME}_shared)
endfunction()
Then there is another file in the cmake folder, FindPlatformInterface.cmake:
add_library(PlatformInterface INTERFACE)
target_include_directories(PlatformInterface
INTERFACE
path/to/PlatformInterface/headers/here
path/to/more/PlatformInterface/headers/here)
The unorthodox use of find_package for PlatformInterface is a temporary work around and the add_sut_wrapper function is a way to handle that a whole mountain of wrapper code is already generated before this CMake project is built. I'm working with plenty of legacy forcing some odd work arounds, sorry for the weirdness.
As I understand it the NUnit setup expects the test to be built as an executable linking to a DLL of the Application code (which in turn is linked with the PlatformInterface, PlatformMock).
This all generates a VS solution when running CMake, without any warnings, but when I try to build the solution in VS I get this error:
Error CS0246 The type or namespace name 'Vector' could not be found
(are you missing a using directive or an assembly
reference?) MyApplication_tests
Vector is a namespace in the static library called MyApplication_wrapper. So obviously I link the code containing Vector. I got a similar problem before, with the namespace System and with linking to NUnit, I solved that by adding
set_property(
TARGET ${CMAKE_PROJECT_NAME}_wrapper
PROPERTY
VS_DOTNET_REFERENCES "System")
set_property(
TARGET ${CMAKE_PROJECT_NAME}_tests
PROPERTY
VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")
to the function add_sut_wrapper. I just can't figure out how to add the assembly reference for Vector.
I'v had to obfuscate the names and paths a bit and I tried to remove some irrelevant details but I think the essentials are there.
If you want the Vector namespace to be accessible from your MyApplication_tests target, you have to link the wrapper library containing Vector to that target. Try changing your target_link_libraries() call to include MyApplication_tests.
Also, using STATIC C# targets in CMake is discouraged, and is not guaranteed to be supported in the future. The C# terminology doesn't really use the "static" and "shared" library terms used in C/C++; rather, "netmodule" and "assembly" are typically used (see this blog post). You should use assemblies (SHARED) when defining C# libraries using CMake:
add_library(${CMAKE_PROJECT_NAME}_wrapper SHARED
${PATH_TO_WRAPPER}/foo.cs
${PATH_TO_WRAPPER}/bar.cs
${PATH_TO_WRAPPER}/baz.cs)
...
target_link_libraries(${CMAKE_PROJECT_NAME}_tests
PUBLIC
${CMAKE_PROJECT_NAME}_wrapper
${CMAKE_PROJECT_NAME}_shared)

.Net Projects Integration and reference to those doesnt work properly

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

The type is defined in an assembly that is not referenced, how to find the cause?

I know the error message is common and there are plenty of questions on SO about this error, but no solutions have helped me so far, so I decided to ask the question. Difference to most of similar questions is me using App_Code directory.
Error message:
CS0012: The type 'Project.Rights.OperationsProvider' is defined in an
assembly that is not referenced. You must add a reference to assembly
'Project.Rights, version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Source File:
c:\inetpub\wwwroot\Test\Website\App_Code\Company\Project\BusinessLogic\Manager.cs
Following suggestions here and here, I have deleted all instances of Project.Rights.dll inside C:\Windows\Microsoft.NET/*.*
According to this, I checked if .cs files in question have build action set to "Compile". They do.
I have also double checked that the .cs file containing the "Project.Rights.OperationsProvider" type is deployed to App_Code directory.
For some reason, application is not looking for the type in the App_Code directory. Since I've deleted all instances of Project.Rights.dll (that I know of), I don't know which assembly the error message is mentioning.
When you get this error it isn't always obvious what is going on, but as the error says - you are missing a reference. Take the following line of code as an example:
MyObjectType a = new MyObjectType("parameter");
It looks simple enough and you probably have referenced "MyObjectType" correctly. But lets say one of the overloads for the "MyObjectType" constructor takes a type that you don't have referenced. For example there is an overload defined as:
public MyObjectType(TypeFromOtherAssembly parameter) {
// ... normal constructor code ...
}
That is at least one case where you will get this error. So, look for this type of pattern where you have referenced the type but not all the types of the properties or method parameters that are possible for functions being called on that type.
Hopefully this at least gets you going in the right direction!
Check target framework in the projects.
In my case "You must add a reference to assembly" actually meant, that caller and reference projects didn't have the same target framework. The caller project had .Net 4.5 , but referenced library had target 4.6.1.
I am sure, that MS compiler can be smarter and log more meaningful error message. I've added a suggestion to https://github.com/dotnet/roslyn/issues/14756
In my case this was because doing a NuGet package update had only updated references to a dll dependency in some but not all projects in my solution - resulting in conflicting versions. Using a grep-style tool to search text within *.csproj files in my solution it was then easy to see the projects that still needed to be updated.
When you get this error, it means that code you are using makes a reference to a type that is in an assembly, but the assembly is not part of your project so it can't use it.
Deleting Project.Rights.dll is the opposite of what you want. You need to make sure your project can reference the assembly. So it must either be placed in the Global Assembly Cache or your web application's ~/Bin directory.
Edit-If you don't want to use the assembly, then deleting it is not the proper solution either. Instead, you must remove all references to it in your code. Since the assembly isn't directly needed by code you've written, but instead by something else you're referencing, you'll have to replace that referenced assembly with something that doesn't have Project.Rights.dll as a dependency.
In my case, I was referencing a library that was being built to the wrong Platform/Configuration (I had just created the referenced library).
Furthermore, I was unable to fix the problem in Visual Studio Configuration Manager -- unable to switch and create new Platforms and Configurations for this library. I fixed it by correcting the entries in the ProjectConfigurationPlatforms section of the .sln file for that project. All its permutations were set to Debug|Any CPU (I'm not sure how I did that). I overwrote the entries for the broken project with the ones for a working project and changed the GUID for each entry.
Entries for functioning project
{9E93345C-7A51-4E9A-ACB0-DAAB8F1A1267}.Release|x64.ActiveCfg = Release|x64
{9E93345C-7A51-4E9A-ACB0-DAAB8F1A1267}.Release|x64.Build.0 = Release|x64
Entries for corrupted project
{94562215-903C-47F3-BF64-8B90EF43FD27}.Release|x64.ActiveCfg = Debug|Any CPU
{94562215-903C-47F3-BF64-8B90EF43FD27}.Release|x64.Build.0 = Debug|Any CPU
Corrupted entries now fixed
{94562215-903C-47F3-BF64-8B90EF43FD27}.Release|x64.ActiveCfg = Release|x64
{94562215-903C-47F3-BF64-8B90EF43FD27}.Release|x64.Build.0 = Release|x64
I hope this helps someone.
It just happened to me that different projects were referencing different copies of the same dll.
I made sure all referenced the same file on disk, and the error disappeared as I expected.
Unloading and reloading the class library in Visual Studio solved this for me.
For me, this was caused by the project both directly and indirectly (through another dependency) referencing two different builds of Bouncy Castle that had different assembly names. One of the Bouncy Castle builds was the NuGet package, the other one was a debug build of the source downloaded from GitHub. Both were nominally version 1.8.1, but the project settings of the GitHub code set the assembly name to BouncyCastle whereas the NuGet package had the assembly name BouncyCastle.Crypto. Changing the project settings, thus aligning the assembly names, fixed the problem.
It didn't work for me when I've tried to add the reference from the .NET Assemblies tab.
It worked, though, when I've added the reference with BROWSE to C:\Windows\Microsoft.NET\Framework\v4.0.30319
I had this issue on a newly created solution that used existing projects. For some reason, one project could not "see" one other project, even though it had the same reference as every other project, and the referenced project was also building. I suspect that it was failing to detect something having to do with multiple target frameworks, because it was building in one framework but not the other.
Cleaning and rebuilding didn't work, and restarting VS didn't work.
What ended up working was opening a "Developer Command Prompt for VS 2019" and then issuing a msbuild MySolution.sln command. This completed successfully, and afterwards VS started building successfully also.
one of main reason can be the property of DLL
you must before do any thing to check the specific version property if it true make it false
Reason:
maybe the source code joined with other (old)version when you build it , but this Library upgraded with new update the version now different in the Assembly Cash and your application forbidden to get new DLL ,and after disable specific version property your applacaten will be free to get the new version of DLL references
Maybe a library (DLL file) you are using requires another library. In my case, I referenced a library that contained a database entity model - but I forgot to reference the entity framework library.
This can also mean you use a library, which exposes (public) types that are defined in a library. Even when you do not use these specifically in your library (the one that doesn't build).
What this probably prevents is you writing code that uses a class (which in its signature has the types from a library not referenced) that you cannot use.
For me the reason why the error appeared was that the WebForm where the error was reported has been moved from another folder, but the name of its codefile class remained unchanged and didn't correspond to the actual path.
Initial state:
Original file path: /Folder1/Subfolder1/MyWebForm.aspx.cs
Original codefile class name: Folder1_Subfolder1_MyWebForm
After the file was moved:
File path: /Folder1/MyWebForm.aspx.cs
Codefile class name (unchanged, with the error shown): Folder1_Subfolder1_MyWebForm
The solution:
Rename your codefile class Folder1_Subfolder1_MyWebForm
to one corresponding with the new path: Folder1_MyWebForm
All at once - problem solved, no errors reporting..
The type 'Domain.tblUser' is defined in an assembly that is not
referenced. You must add a reference to assembly 'Domain,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
**Solved:**
Add reference of my domain library layer to my web app libary layer
Note: Make sure your references are correct according to you DI container
In my case this was because I used
Implicit Operator
between BLL and DAL classes.when I want to use BLL Layer In Application Layer I got this error.
I changed
implicit operator
to
explicit operator
it be OK.
Thanks
In my case the version of the dll referenced was actually newer than the one that I had before.
I just needed to roll back to the previous release and that fixed it.
I have a similar problem, and I remove the RuntimeFrameworkVersion, and the problem was fixed.
Try to remove 1.1.1 or
My problem was that the Output Type for one of my projects was set to Console Application. To fix this, I right-clicked the project, chose Properties, clicked the Application tab, and change Output Type (from Console Application) to Class Library. After I re-compiled, this error went away.
Clean your solution and rebuild worked for me (in Visual Studio, these are options you get when you right click in your solution explorer), the error is gone in my project.

Referencing a Windows Phone Runtime Component DLL/WinMD from another project

I need to implement a wrapper to expose some native C++ code to C#, and have followed this tutorial:
http://www.silverlightshow.net/items/Windows-Phone-8-Native-Code-Support.aspx
So far in my C# test project, I don't have problems instantiating a class written in C++/CX from the Runtime Component project and using methods from that class, so long as I reference the entire project (.sln).
Visual Studio doesn't allow me to reference the Runtime Component DLL alone, but does allow me to reference the .winmd file in the project. C# then recognizes the namespace correctly, however at runtime I get a TypeLoadException when trying to create the same object.
This doesn't appear to be a namespace problem (as mentioned here: Changing namespace name of C++ component in Windows Phone causes exception), since everything is alright so long as I create a project reference (or does referencing a project vs a .winmd affect the namespace somehow?).
Is it possible to bundle the Runtime Component in some form that an end user can reference it without needing to provide the entire project?
You need to add following the to WMAppManifest.xml
<ActivatableClasses>
<InProcessServer>
<Path>YourComponent.dll</Path>
<ActivatableClass ThreadingModel="both" ActivatableClassId="YourComponentNamespace.YourComponent"/>
</InProcessServer>
</ActivatableClasses>
With YourComponent being the name of your WinMD.
I think what you are seeing is a manifestation of the problem described here.
In short, when creating a WinRT component using C++, just referencing the output DLL or the output winmd is not sufficient. You need both.
I had this same problem, and (eventually) figured out that the .dll and .winmd file needed to have the same name (which was the same as the namespace they defined) and be in the same directory.
For example, if your classes are in the X::Y namespace, the files must be X.Y.dll and X.Y.winmd.
Then all I needed to do was add a reference to the .winmd file in my project (by right-clicking on the References folder for that project in the Solution Explorer, choosing "Add Reference...", then choosing "Browse" from the dialog that comes up). I didn't need to add anything to the manifest file.

How do I compile C# code as a library instead of an executable?

I have a C# console application in Visual Studio 2010. It has a Main() method as well as a bunch of utility classes. I'd like those utility classes to be available to other solutions. From reading online it seems that I need to compile it as a Class Library (DLL). So here's what I did:
Went in Visual Studio to "Project > [ProjectName] Properties > Application" and changed "Output type" from "Console Application" to "Class Library"
Rebuilt; ProjectName.dll was created in bin/Debug.
Created a new Console Application
Solution Explorer > Add Reference > browse to ProjectName.DLL, select it.
However, neither IntelliSense nor the Object Browser could find the classes inside that DLL.
I tried recompiling several different Console Applications as Class Libraries and got the same result. I also noticed that it works if I initially create the solution as a Class Library, but not if I convert it to one later.
Any tips?
You do not need to build it as a dll. VS 2010 (and IIRC 2008) allow referencing exe assemblies. All you need is for they relevant types to be declared public - top-level classes defualt to internal if you don't add a specifier.
You can switch output type to Class library in project properties as well - then you will have an output as dll instead exe file
What I've always done (since this is what you do with C++ static libraries, which is what I normally use - though I think it has some advantages for C# too) is add the class library's project to the solution, then add a reference to it in the project (or projects) that uses it.
When you go to add a reference, the list of potential references includes items from the solution, so it should be fairly obvious what to do. You should then get intellisense for your library.
One advantage of doing things this way is that if you need to edit files in the library project, it's very straightforward because they are close to hand, and the project then gets rebuilt automatically when you compile the solution.
Make sure that the classes in your dll project are public.
At first, from the point of view of managed libraries it does not matter what kind of Output type is your managed library. I mean that you can successfully reference ConsoleApplication1.exe from ConsoleApplication2.exe project (so you have no reason to convert ConsoleApplication1.exe to ConsoleApplication1.dll).
At second, I've tried to reproduce your situation, but... without effect. My VS displays types/methods from ConsoleApplication1.dll. One reason I can suppose is that you have forgotten to set visibility modifier (public keyword) for your utility classes.

Categories

Resources