I'v a problem with Fakes Framework and internal class.
I've just readed and used the advice here: How to mock/isolate internal classes in VS 2012 with Fakes Framework shims?
but, I still not see internal classes.
I've this solution:
ACQTool (class library project)
ACQTool.UnitTests (test project)
in ACQTool namespace there is ACQTool.Utils internal class.
in ACQTool/AssemblyInfo.cs I've added these lines:
[assembly: InternalsVisibleTo("ACQTool.UnitTests, PublicKey=57ad8399-13fd-4d4d-90fd-c521c2164d25")]
[assembly: InternalsVisibleTo("ACQTool.Fakes, PublicKey=0024..47bc")]
[assembly: InternalsVisibleTo("Microsoft.QualityTools.Testing.Fakes, PublicKey=0024..47bc")]
After build, I can use ACQTool.Utils in test class, but not exist ACQTool.Fakes.ShimUtils/StubUtils.
Help me please.
It's kinda weird I just replicated your problem and surely it wasn't generating the internals in Fake assembly at first. I followed below steps and it started working even for other namespaces too:
Add a public class under the namespace Utils.
Rebuild the Test project and the internal will start showing up.
Remove that public class and rebuild again.
I removed everything from Utils namespace and added new internal class and it is working fine since then.
It's just a workaround to generate namespace that contains internals.
Probably You should paste Public key generated by sn.exe tool.
Usually it stored somewhere like:
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe"
call it from command line:
sn.exe -p SomeName.snk SomeName.PublicKey
sn.exe -tp SomeName.PublicKey
and paste the output to the "InternalsVisibleTo" Public key param.
Important note from that msdn page that I missed: The Fakes framework uses the same key to sign all generated assemblies, so the public key if signing should ALWAYS be
PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc
Related
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)
Problem Definition: I have a class library project named IRI.Ket.ShapefileFormat with some internal classes and structures. I introduced another project as a friend assembly to this class library. Then I was able to build my solution and run the program successfully. But while coding, intellisence dose not recognize those internal types and methods. And if I write them manually, they are not colored as expected.
I'm working on Visual Studio 2013 Ultimate edition.
Edit: In the picutre above why Shapefile (this is the internal class type that is defined in the class library and I'm using it in a friend assembly) is not colored like DataColumn? Is this a bug?
More Strange Issue: Every time the solution can be built successfully but after a while some errors appear in the error list and say e.g. Shapefile.Read is inaccessible due to its protection level! Here is a snapshot (all of these methods are internal). Its strange I didn't know projects with errors may be built successfully :)
I finally found what was going wrong. I had lots of class library project with the same public key. These libraries should be introduced as friend assembly.
[assembly: InternalsVisibleTo("Friend1, PublicKey=00240000048000009...")]
[assembly: InternalsVisibleTo("Friend2, PublicKey=00240000048000009...")]
[assembly: InternalsVisibleTo("Friend3, PublicKey=00240000048000009...")]
[assembly: InternalsVisibleTo("Friend4, PublicKey=00240000048000009...")]
So I thought it's a kind of hard coding to repeat the public key every time and I make a const string variable somewhere and use that in the attribute declaration. However in compile time the compiler was able to access it and build the project successfully but in the design time there was no idea how to resolve it.
//somewhere
const string key = "PublicKey=00240000048000009...";
//
And then I changed those lines like this:
[assembly: InternalsVisibleTo("Friend1, " + key)]
[assembly: InternalsVisibleTo("Friend2, " + key)]
[assembly: InternalsVisibleTo("Friend3, " + key)]
[assembly: InternalsVisibleTo("Friend4, " + key)]
So I changed these lines and used the hard code version and now IntelliSense and Syntax coloring are working.
If you have access to the build of IRI.Ket.ShapefileFormat find the assembly.cs file and add the following:
[assembly: InternalsVisibleTo("name of assembly here")]
Put the name of your project that is assessing the Shapefile class between the string quotes above.
Then your project can have access to IRI.Ket.ShapefileFormat's internal types.
Background: I am a novice in C#, and use Visual Studios 2010 Express.
I have a class (let's call it myclass) which I want to use in multiple projects. I used to add classes with Project->Add Existing Item... Which creates a copy of myclass.cs.
Now I just found out that when I build the original myclass.cs it creates a myclass.dll and places it in the release folder of my project.
But when I try to use this DLL, I get the following error:
The type or namespace name 'myclass' could not be found(are you
missing a using directive or an assembly refference?
Which is weird to me, because I already have referenced it (it is also in the Reference folder of my Solution Explorer). And I already have added this to my code:
using myclass;
So what am I doing wrong?
Update: When I tried my old method (add existing item -> myclass.cs) the error message goes away. So it's not a matter of spelling things correctly.
Add the dll first:
Click on references in your project-explorer in visual studio and add your dll then you can use it as you expected it.
Add the reference in your project and check that the target Framework version of that assembly fits the project.
Check the namespaces inside the assembly and then use them like:
using YourAssemblyNamespace.class
Okay so I found the answer myself. It turns out that when you use the using function, it automatically searches for all public classes in the namespace you want to use.
If it can't find a public class, it refuses to recognize the DLL.
Furthermore, not specifying a class makes it internal.
So:
class myclass // internal!
private class myclass // private!
public class myclass // only this makes it visible for others!
Everything was okay after changing class myclass into public class myclass.
I have a solution in Visual Studio 2010 containing 6 projects (1 web application, 4 c# class libraries, 1 c# console application).
The console application is my test harness and use this to test external web services, output from methods from within my other libraries and general experimentation. This test console application has only one dependency on another project dependency, one of the C# libraries.
The referenced C# library is pretty simple:
namespace GowallaAPI
{
public class Gowalla
{
private static readonly ILog log = LogManager.GetLogger(typeof(Gowalla));
public SpotsInRadius GetGowallaSpotsInRadius(decimal lat, decimal lon, int radius) {
//snip
}
//other methods removed for brevity//
}
}
I have added to my console application a project reference:
And I've also right-clicked on References and selected Add Reference...
Then, I've gone to my console application and added;
using Gowalla;
Then hit build. I get this:
The type or namespace name 'Gowalla'
could not be found (are you missing a
using directive or an assembly
reference?)
I am completely baffled. I have:
Remove the dependencies completely (and then rebuilt with Gowalla references removed), and added them again.
I have removed the dependencies completely (like #1) and then added them as assemblies only (Add Reference...).
Checked that the target framework for both console application and class library is .NET 4.0 - they are.
Checked that all necessary items within the Gowalla class library are marked as Compile in the Build property.
Jiggled the build order of the project so that I am at least building the console application AFTER the library is built.
Done some shouting and swearing.
Given up and then returned.
Moved the Gowalla C# library out to its own project entirely and then referenced the assembly (like in 2).
Playing the having a constructor in Gowalla and not:
public Gowalla()
{
}
... and nothing has worked!
Can anyone see something obvious? Am I being utterly stupid? I have been on this for hours and I wonder quietly if this is a classic 'wood for the trees' moment...
Help appreciated.
EDIT 1: This is the Gowalla.dll exposed from Reflector:
ANSWER: After #gov's helpful suggestion to remove the GowallaAPI library and try and add something else I did that and started adding in the old code from the GowallaAPI library. Everything worked until I added:
private static readonly ILog log = LogManager.GetLogger(typeof(Gowalla));
log4net for some utterly bizarre reason kept throwing the build. Alas, after removing the line (the reference to log4net remains), the project built and worked perfectly thereafter. Thank you to #gov for setting me on the right path! :D
I had the exact same problem with log4net and it was resolved after changing target framework of the hosting project from ".NET Framework 4.0 Client Profile" to ".NET Framework 4.0"
I suggested him various things in the comments looks like one of them worked out.
#dooburt just forget about GowallaAPI and create a separate project like i say , sample.common and have a public class called utilities or so add that project here , just check a new project of type library and see whats the problem
Take a look at the .csproj XML, see if there is anything odd about the reference, one of these:
<Reference Include="Gowalla" ... />
<ProjectReference Include=".\path to\Gowalla.csproj" ... />
Have a look at the target framework of your class library and the test harness. I was having this error when the class library was set to .Net Framework 4 and the test harness was .Net Framework 4 Client Profile.
Visual Studio 2008(C#).....I have 3 project in one solution(win application). In every project I've been signing using project properties signing tab to one MySigned.snk. How to manage build configuration so my project doesn't error on every build?
I use [assembly: InternalsVisibleTo("MYproject1, PublicKey=.....")] properties so the other project class can access internal class of base class on other project.
Error becasuse I used backgroundprocess to update every form on my project.But on development environment what suppose I have to do so The project safely on during development? thx before...
I use [assembly:
InternalsVisibleTo("MYproject1,
PublicKey=.....")] properties so the
other project class can access
internal class of base class on other
project.
This is not related to the issue.
In every project I've been signing
using project properties signing tab
to one MySigned.snk. How to manage
build configuration so my project
doesn't error on every build?
I assume it is because the assembly versions are auto-incrementing:
Use project references always. This way, you will make sure everything is built against latest version numbers
Removing * from the AssemblyInfo's assembly version attribute will help here but it is advisable to keep it there.