Static link classes - need to know calling project name - c#

My Setup :
Project A
Class Log
{
public static void WriteLog(string msg)
{
Trace.write(GetTimestamp(), GetAppDominNameCallingWriteLog(), msg);
}
}
Project B
contains Static link Log.cs (Add as link)
Project C
contains Static link Log.cs (Add as link)
Project D
contains Static link Log.cs (Add as link)
Using one log file for all the project. Now I need to get the project name (GetAppDominNameCallingWriteLog()) in the Log class. How can i achieve this without passing Project name to WriteLog().
e.g. Project C calls Log.Writelog("logging msg")
the result should be 201511121232 Project C logging msg
Project D calls Log.Writelog("logging msg")
the result should be 201511121232 Project D logging msg
Tried with Thread.AppDomain(), it always return Project A.
Sorry I forgot to add this case : Project C is referenced in Project A.

You can find out the executing project using the below code
AppDomain.CurrentDomain.FriendlyName;
I have also checked this with the Thread class. It returns the result correctly
System.Threading.Thread.GetDomain().FriendlyName;
UPDATE
Based on the additional information provided in the comments, you can identify the calling Assembly using Reflection
System.Reflection.Assembly.GetCallingAssembly().FullName;
Working Example
static void Main(string[] args)
{
//Direct call to the Log class from ConsoleApplication3
Log.Write();
//Indirect call to the Log class through a Class Library called ClassLibrary1
Class1.LogIt();
Console.ReadLine();
}
And the output is

Related

Specifying cs file to build with dotnet CLI

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");
}
}

Main Menu driven programme for different Projects

For an assignment i had different DataStructures (in C#) that I needed to implement. That part was easy. But I am also required to make a main menu driven programme for all those projects. So i searched a bit and found out a way. For example i had a project named linkedlist with namespace as Implementing_LinkedList and another project queue and namespace as Implementing_queue. To make a menu driven programme i just created another project named Assignment with namespace assignment. Mainconsole. Then i changed the namespace of linkedlist project to Assignment.Implementing_LinkedList and similarly with queue.Also made all the methods and classes public. Then i just called the main method of linkedlist inside main method of assignment as follows
Implementing_LinkedList.Program.Main();
Main method is inside a class named program in linked list project and it worked. Now i want to know how this worked because specifically .MainConsole part and if there is any other way to acheive this.
(Also i am pretty new to Stack overflow so pardon me for the extra long question but i didn't want to skip any details)
You don't have to rename namespaces or anything. Each program's Main() function is static and it can be called from any other function using a fully qualified name.
Program1.cs
namespace Project1
{
public static class Program1
{
public static Main(string[] argc)
{
// code here
}
}
}
Program2.cs
namespace Project2
{
public static class Program2
{
public static Main(string[] argc)
{
// code here
}
}
}
MenuProgram.cs
namespace MenuProject
{
public static class MenuProgram
{
public static Main(string[] argc)
{
// call all projects in sequence
Project1.Program1.Main();
Project2.Program2.Main();
}
}
}
This assumes the menu project has all the sources of the sub projects included. If they are separate project files, then you need to Add Reference... to those projects from the project file references.

Use dependency from one project to another in the same solution

Is it a way of using a dependency from a project to another while they are in the same solution? For example:
ComputerVisionProject (solution):
1. ComputerVision.FaceRecognition
2. ComputerVision.Core
3 .ComputerVision.UI
In the first project: ComputerVision.FaceRecognition, I install a nugget, for example, "OpenCV" and I can use all the functions from it with "using OpenCV", but only in the ComputerVision.FaceRecognition project.
What I want is to use the same functions in the second project, ComputerVision.Core. but I don't want to install again the nugget, and seems that only "using OpenCV" doesn't work (even if I add the entire project as a reference to the second one) Is it possible to make another type of reference or something like: "using ComputerVision.FaceRecognition.OpenCV" ?
Use a project reference.
https://learn.microsoft.com/en-us/visualstudio/ide/managing-references-in-a-project?view=vs-2019
To test; create a new solution with two projects within it.
Within one project, add a nuget package. Say, Newtonsoft.Json
Add a project reference from your second project to the first
Dependencies should now look like so;
Now within TestConsoleApp, you can add using statements to access the nuget package used in TestConsoleApp2.
eg;
using System;
using Newtonsoft.Json;
namespace TestConsoleApp
{
class Program
{
static void Main(string[] args)
{
var output = JsonConvert.SerializeObject(new ExampleObject() { field = "value" });
Console.WriteLine(output);
}
}
public class ExampleObject
{
public string field;
}
}
When run outputs {"field":"value"}

Is a referenced method definition not picked by CLR from the referenced assembly at run time?

I am observing a very strange behavior in my simple C# console application. I can't understand why CLR is working that way under the hood. Here are my code samples:
My Main program:
class Program
{
static void Main(string[] args)
{
Employee emp = new Employee();
Console.WriteLine( emp.EmployeeName());
}
}
The console application project containing the above Main method references another C# class library project named CustomDataObjects. It is as below:
namespace CustomDataObjects
{
public class Employee
{
public string GetEmployeeName()
{
return "Foo";
}
}
}
I build everything and it works perfectly fine. Main function prints "Foo" on console.
Now I changed my CustomDataObjects project as below. I changed the signature of GetEmployeeName method and introduced a new mandatory parameter named empName
namespace CustomDataObjects
{
public class Employee
{
public string GetEmployeeName(string empName)
{
return empName;
}
}
}
I did not recompile my console project after making these changes. I simply recompiled CustomDataObjects project after making above changes. Then, I copied the newly built CustomDataObjects.dll and CustomDataObjects.pdb files into \bin\debug directory of main console project.
Now I try to run the executable file of main console application from bin\debug directory of main console project. To my surprise it doesn't crash. If I'm not wrong, on the second run CLR should have tried to look for definition of GetEmployeeName with older signature which doesn't have any parameter and since CustomDataObjects.dll has changed it should observe the mismatch and cause a run-time crash. Why did it not happen this way? My console application is running on .Net v4.0

Accessing class members defined in another *.cs file

I'm writing an update checker for my program and I'm using xml from a remote server. The request is working fine and it does what I want. The problem is that I can't call the function from another file. (See code below)
The files
home.cs - The place i want to call the RequestVersion()
version.cs - Where the RequestVersion() is located
The code
version.cs
namespace MyName
{
class version
{
public string[] RequestVersion()
{
XmlDocument doc = new XmlDocument();
try
{
string[] version_data = new string[3];
doc.Load("link_here");
foreach (XmlNode node in doc.DocumentElement)
{
string version = node.Attributes[0].Value;
string date = node["date"].InnerText;
string changelog = node["changelog"].InnerText;
version_data[0] = version;
version_data[1] = date;
version_data[2] = changelog;
return version_data;
}
}
catch (Exception xml_ex)
{
}
return null;
}
}
}
(returns an array)
home.cs
private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
{
//This is the place from where i want to access the array!
}
And my XML structure:
<?xml version="1.0" encoding="UTF-8"?>
<SerialMate>
<release version="1.0.0">
<date>12-10-2014</date>
<changelog>Test</changelog>
</release>
</SerialMate>
(I'm not adding any new <release> tags on the xml so it always has 1)
The question
So, my question is: How do it access the array elements from the RequestVersion() within home.cs?
I don't really understand your problem, but:
version v = new version();
string[] s = v.RequestVersion();
Referencing code within other files and projects
Within the same project it makes absolutely no difference whether the code is in the same or in different files. The only things which matter are the access modifiers (public, protected, internal, and private).
If the two code pieces are in different projects, then the compiled code will be compiled into two different assemblies (*.exe or *.dll). Therefore one project will have to reference the other one. Typically the start up project (*.exe) will reference a class library project (*.dll).
If the two projects are within the same solution, you can add a so called project reference. Right click on the class library project in the solution explorer and click “Copy As Project Reference”. In the startup project, right click on “References” and click “Paste Reference”.
If the two projects are within different solutions you will have to add a reference to the class library DLL (usually the one in bin/Release) from within the startup project. Right click “References” and click “Add Reference…”. In the references dialog choose “Browse” and select the DLL.
Also make sure not to create circular dependencies (project A references project B and project B references project A). If you have such a dependency, you can usually resolve it by placing the code that has to be accessed by the two projects into a third project C. Then change the references to: A references C and B references C.
Calling the method of another class
Types (a class in your case) and their members (properties, methods, events …) must be declared as public in order to be accessible from other projects. Within the same project they can also be declared as internal. (They can also be declared as protected if you want to derive new classes.)
If a member is declared as static or if it is a constant, you can access it by specifying the type name dot the member name:
var result = MyClass.MyMethod();
If the member is an instance member you must call it from an instance of the type (an object):
MyClass obj = new MyClass();
var result = Obj.MyMethod();

Categories