I have a VS solution set up using build scripts to copy the compiled DLL into another project. The base project builds fine, and copies correctly to the target.
However, the target project won't compile as it can not find a particular class within the namespace:
foo.cs
namespace foo {
public class bar {
public static string myVar {
get { return "A string"; }
}
}
}
myPage.aspx.cs
using foo;
namespace foo.foo2 {
partial class bar2 {
protected void Page_Load(object sender, EventArgs e) {
// can access foo.bar here in the source project but not once the DLL is compiled and copied to target
var myVar = bar.myVar; // The name 'bar' does not exist in the current context
}
}
}
Why would this compile correctly in the source project, but prevent the target from building?
EDIT: Second project builds fine if I exclude myPage.aspx from the project. But I shouldn't have to do that.
You have very likely an incorrect assembly referenced.
Make sure you use the correct physical assembly. Sometimes, a dead (old) version lies around (such as in the GAC) and this one is referenced rather than the believed new version.
Easiest way to confirm is to rename the assembly file to something else and reference the newly named assembly. bar.myVar should show up immediately.
Related
We are in the beginning stages of converting a c# Winforms App from .NET Framework to .NET 6. We can get the project to build and run in .NET 6, but when it comes to a dynamically loaded assembly, we are having issues. We can get the assembly to load but attempting to access the custom class within it returns a null. I recreated this scenario in two smaller projects as an example.
Solution 1/Project 1 - The code for the assembly to be loaded into the main application. This is a class library that creates the TestAssembly.dll
namespace Custom.TestAssembly
{
public class TestClass : CallingModule
{
public override object GetValue()
{
return "Hello World";
}
}
}
Solution 2/Project 1 - This is a project and class within the main application's solution. This is a class library that creates the Custom.TestAssembly.dll
namespace Custom.TestAssembly
{
public class CallingModule
{
public virtual object? GetValue()
{
return null;
}
}
}
Solution 2/Project 2 - A button has been placed on a form. When it is clicked, the assembly should be loaded, which it is. However, attempting to extract the class from the assembly always returns a NULL.
Form1.cs
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Loader;
namespace TestCallingApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Assembly dynamicAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(#"C:\LocationOf\TestAssembly.dll");
Module customizationModule = dynamicAssembly.GetModule("TestAssembly.dll");
Type customClientModule = customizationModule.GetType("Custom.TestAssembly.TestClass"); //THIS RETURNS A NULL??
}
}
}
Just trying to understand what I am missing. Any thoughts? Or a better way to load runtime assemblies and access classes within them in .NET 6?
Did you reference Solution 2/Project 1 ?
Since they have the same assembly name Custom.TestAssembly, the runtime will not load it again if already loaded in memory.
You can, however, load it under a different AssemblyLoadContext, there's an example on MSDN as well.
Also, you may want to take a look at DotNetCorePlugins, which takes care of assembly loading, reloading, isolation, shared type, and dependency resolving.
Suppose I have two files in my current working directory:
// file1.cs
Console.WriteLine("file1");
//file 2.cs
Console.WriteLine("file2");
In powershell, I do a dotnet new and delete the automatically generated Program.cs file. Then I do a dotnet build and get an error:
Only one compilation unit can have top level statements
I understand why this occurs, but I would like to be able to have full control of which .cs file is being targetted, while the other ones get ignored.
Is there any way to achieve this without having to create a whole new project for every file?
Doing this with .NET doesn't seem to be possible as of now. An issue on the dotnet/sdk GitHub has requested for this feature to be implemented.
However, you can use the C Sharp Compiler to compile a Windows executable and specify a .cs file with csc file1.cs
file1.cs:
using System;
Console.WriteLine("File 1");
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements
These files both use top-level statements. It implies that they both contain the Main method where program execution starts. You can only have one entry point. Generally, C# code is going to be contained within classes. Define a class in one (or both) files and put your methods within.
// Program.cs
public class Program
{
static void Main()
{
Console.WriteLine("Program.cs");
}
}
// Util.cs
public class Util
{
public static void Display()
{
Console.WriteLine("Util.cs");
}
}
I'm attempting to create a Solidworks plugin with AngelSix's SolidDna library.
I've used the standard setup as per the examples:
public class Integration : AddInIntegration
{
// All overrides left blank
public override void ApplicationStartup()
{
}
public override void ConfigureServices(FrameworkConstruction construction)
{
}
public override void PreConnectToSolidWorks()
{
}
public override void PreLoadPlugIns()
{
}
}
public class MySolidDnaPlugin : SolidPlugIn
{
public override string AddInTitle { get; } = "foo";
public override string AddInDescription { get; } = "bar";
public override void ConnectedToSolidWorks()
{
// This works fine...
Boo.Lang.List l = new Boo.Lang.List();
// ....But this doesn't :(
Boo.Lang.Compiler.BooCompiler c = new Boo.Lang.Compiler.BooCompiler();
}
public override void DisconnectedFromSolidWorks()
{
}
}
I'm attempting to add support for scripting in Boo, so users can edit the scripts on the fly. I've added a reference to Boo.Lang.dll, Boo.Lang.Compiler.dll and Boo.Lang.Parser.dll, and all 3 DLLs are definitely copied to the /bin folder.
I'm able to use classes from the Boo.Lang namespace, but as soon as I try and use the Boo.Lang.Compiler namespace it throws an error:
Could not load file or assembly 'Boo.Lang, Version=2.0.9.4, Culture=neutral, PublicKeyToken-32c39770e9a21a67' or one of its dependencies. The system cannot file the file specified.
The same code/setup works fine when running outside Solidworks, e.g. in a console app.
The SolidDna docs show the process of registering the plugin DLLs with regasm.exe /codebase, so I tried running that with the 3 Boo DLLs, but that doesn't make any difference.
Any suggestions or pointers?
My guess would be that you added those binaries to addin folder, while process is looking for those files in solidworks.exe folder.
I suggest you to confirm it with ProcMon tool.
If that is the case there are multiple ways to resolve this:
1 add those binaries to solidworks folder
2 add those folders to any of the folders in the path environment variable
3 add your addin folder to path environment variable
4 If those binaries as well as your addin are .net assemblies you can use ilmerge to combine them into one.
5 If your addin is .net assembly and you have access to appdomain object you can subscribe to AssemblyResolve event and provide path dynamically.
I have faced a strange situation recently which I do not understand and ask someone of you to describe me what I did wrong or what I am missing here.
The solution is build from 3 projects (some of code parts has been cut out to make it more readable):
Project 1 - Main
namespace TestRun
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom(PluginPath);
foreach (Type type in assembly.GetTypes())
{
if (type.IsSubclassOf(Plugins.Plugin) &&
type.IsAbstract == false)
{
if(Parameters != null && Parameters.Length > 0)
Result = (T) Activator.CreateInstance(type, Parameters);
else
Result = (T) Activator.CreateInstance(type);
}
}
}
}
}
This one is responsible for loading all files with dll extension from a given folder (plugins).
Next I have a main plugin class:
namespace Plugins
{
public interface IPlugin
{
void func();
}
public abstract class Plugin : IPlugin
{
//Basic implementation
}
}
And a plugin assemblies:
namespace DevicePlugins
{
public class DevicePlugin : Plugins.Plugin
{
{...}
}
}
The problem is that if Project 1 has the reference to the plugin assembly (i.E. DevicePlugins) it cannot create an instance of an object from this assembly (DevicePlugin).
I do not get any error or exception - only information about "Result" from Project 1 - "Value cannot be evaluated".
If I remove the reference to the plugin's assembly from Project 1 (I mean that in the Project 1 I have not the reference to DevicePlugins assembly) everything is working like a charm (I can create an object of DevicePlugin from DevicePlugins assembly).
Moreover, when I have the reference I can initiate an object in the normal way
DevicePlugins.DevicePlugin plug = new DevicePlugins.DevicePlugin();
Can someone tell me what am I missing or do not understand??
Why it working in that way?
When you add an assembly reference to a project, it builds a dependency on the assembly into the executable and this causes the assembly to be loaded at runtime into the execution context.
As you are actually loading the same assembly twice into the execution context (once manually using LoadFrom, once by assembly reference), you should check the behaviour of LoadFrom for your specific case. If you are doing what I think you are, which is loading the assembly from a "plugins" folder, then LoadFrom will start behaving incorrectly with regards to what you want to achieve, I believe.
Read up on MSDN for the specifics: http://msdn.microsoft.com/en-us/library/1009fa28(v=vs.110).aspx
I'm trying to allow a user to enter data into a textbox that will be added to the web.config file. I've added the relevent lines to the web.config file but when I make this class all goes wrong.
I keep getting the are you missing a using directive or assembly refenrence error whenever I try to run my app. I have looked at the other times this question has been asked and can't seem to figure out where I'm going wrong. The thing is that I am extremely new to Visual Studio and am just left blank at what could be the answer.
Below here is the class file that's generating the error. I hope I've included everything you need to assist me. Thank you.
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
namespace WebConfigDemo
{
public class CompanyConfigSection : ConfigurationSection
{
[ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
public CompanyConfigCollection Companies
{
get
{
return (CompanyConfigCollection)this[""];
}
set
{
this[""] = value;
}
}
}
public class CompanyConfigElement : ConfigurationElement
{
[ConfigurationProperty("id", IsKey = true, IsRequired = true)]
public int Id
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return this["name"].ToString();
}
set
{
this["name"] = value;
}
}
} '
public class CompanyConfigCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new CompanyConfigElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((CompanyConfigElement)element).Id;
}
}
public class CompaniesConfig
{
private static readonly Dictionary<int, CompanyConfigElement>
Elements;
static CompaniesConfig()
{
Elements = new Dictionary<int, CompanyConfigElement>();
var section = (CompanyConfigSection)ConfigurationManager.GetSection ("companies");
foreach (CompanyConfigElement system in section.Companies)
Elements.Add(system.Id, system);
}
public static CompanyConfigElement GetCompany(int companyId)
{
return Elements[companyId];
}
public static List<CompanyConfigElement> Companies
{
get
{
return Elements.Values.ToList();
}
}
}
} '
Any help is appreciated
You probably don't have the System.Configuration dll added to the project references. It is not there by default, and you have to add it manually.
Right-click on the References and search for System.Configuration in the .net assemblies.
Check to see if it is in your references...
Right-click and select Add Reference...
Find System.Configuration in the list of .Net Assemblies, select it, and click Ok...
The assembly should now appear in your references...
.Net framework of the referencing dll should be same as the .Net framework version of the Project in which dll is referred
If you've tried the above solutions and haven't found the answer, make sure that the .NET versions of all projects are the same.
I ran into this problem when importing a .NET version 4.6.1 into a .NET version 4.6.2 project. Without any warnings from Visual Basic!
More Info: The type or namespace name could not be found
Your using statements appear to be correct.
Are you, perhaps, missing the assembly reference to System.configuration.dll?
Right click the "References" folder in your project and click on "Add Reference..."
This problem would be caused by your application missing a reference to an external dll that you are trying to use code from. Usually Visual Studio should give you an idea about which objects that it doesn't know what to do with so that should be a step in the right direction.
You need to look in the solution explorer and right click on project references and then go to add -> and look up the one you need. It's most likely the System.Configuration assembly as most people have pointed out here while should be under the Framework option in the references window. That should resolve your issue.
I have observed a quote ' in your 1st line and also at the end of your last line.
'using System.Collections.Generic;
Is this present in your original code or some formatting mistake?
I had the same problem earlier today. I could not figure out why the class file I was trying to reference was not being seen by the compiler. I had recently changed the namespace of the class file in question to a different but already existing namespace. (I also had using references to the class's new and previous namespaces where I was trying to instantiate it)
Where the compiler was telling me I was missing a reference when trying to instantiate the class, I right clicked and hit "generate class stub". Once Visual Studio generated a class stub for me, I coped and pasted the code from the old class file into this stub, saved the stub and when I tried to compile again it worked! No issues.
Might be a solution specific to my build, but its worth a try.
In some cases, when necessary using has been obviously added and studio can't see this namespace, studio restart can save the day.
I was getting warnings about different versions in .NET framework; I ignored them.
The project compiles fine making the change in the solution's properties.
I'm using Visual Studio Code and could not use instructions from above so I found another way to fix the problem with referencing to namespace from another file.
All what need to be done is to add include to your .csproj file e.g:
<ItemGroup>
<Compile Include="filename.cs" />
</ItemGroup>
Then you can use namespaces from filename.cs
The following technique worked for me:
1) Right click on the project Solution -> Click on Clean solution
2) Right click on the project Solution -> Click on Rebuild solution