I am using online c# compiler just to determine the class and method name.See the code given below, I am intentionally generating an error.
Expected Output is:
Hello, world!
ExceptionTest
, basically from where the exception has been generated.
OUTPUT, I m getting is
Hello, world!
System.Reflection.RuntimeMethodInfo
//Rextester.Program.Main is the entry point for your code. Don't change it.
//Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
try
{
//Your code goes here
Console.WriteLine("Hello, world!");
var abc = new Xyz();
abc.ExTest();
}
catch(Exception ex)
{
Console.WriteLine(new StackTrace().GetFrame(1).GetMethod().DeclaringType.FullName);
}
}
}
public class Xyz
{
public void ExTest()
{
var abc = new Abc();
abc.ExceptionTest();
}
}
public class Abc
{
public void ExceptionTest()
{
throw new Exception();
}
}
}
Please note, this is compiled on an online tool http://rextester.com/. I havent ran it on Visual Studio.
Simply, you could use Exception TargetSite;
catch(Exception ex)
{
Console.WriteLine(ex.TargetSite.Name);
}
Related
I'm developing a .Net Standard 2.0 library offering dynamic compilation but there are always missing references.
A consumer using .Net Core, calls an Api with his source code as text, implementing a known interface by the library.
//Consumer Program.cs
using DynamicCompilationNetStandard2._0;
var source = """
using DynamicCompilationNetStandard2._0;
using System.Linq.Expressions;
namespace Consumer
{
public class MyTask : ITask
{
public void CanRun<T>(Expression<Func<T, bool>> predicate)
{
}
public void Run()
{
Console.WriteLine("Finished");
}
}
}
""";
Executor.Execute(source);
The library's Executor class:
using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using System.Linq.Expressions;
namespace DynamicCompilationNetStandard2._0;
public static class Executor
{
public static void Execute(string source)
{
var syntaxTree = SyntaxFactory.ParseSyntaxTree(source);
var compilation = CSharpCompilation.Create(assemblyName: Path.GetRandomFileName())
.WithReferenceAssemblies(ReferenceAssemblyKind.NetStandard20)
.AddReferences(
MetadataReference.CreateFromFile(typeof(ITask).Assembly.Location))
.AddReferences(ReferenceAssemblies.NetStandard20)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddSyntaxTrees(syntaxTree);
using (var ms = new MemoryStream())
{
var result = compilation.Emit(ms);
if (!result.Success)
{
throw new Exception(result.ToString()); //CRASH
}
ms.Seek(0, SeekOrigin.Begin);
var assembly = Assembly.Load(ms.ToArray());
try
{
var types = assembly.GetTypes();
}
catch (Exception ex)
{
throw; //CRASH
}
dynamic task = assembly.CreateInstance("Consumer.MyTask");
task.Run();
}
}
}
public interface ITask
{
void CanRun<T>(Expression<Func<T, bool>> predicate);
void Run();
}
I'm using basic-reference-assemblies to add references to reference assemblies instead of implementations. Still I get theses errors:
How can I import missing references and fixing this simple project?
Here is the source code: https://github.com/adampaquette/DynamicCompilationTests
Thanks!
Ok the problem was an implicit reference to System. After adding using System; in the source string, it worked.
I have like below.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Syncfusion.Gitlab
{
public class Branches
{
public void CreateBranch(List<string> projectName, string sourceBranch, string destinationBranch)
{
}
public void CreateTag(List<string> projectName, string sourceBranch,string tagname)
{
}
public static List<string> GetBranchList(string projectId)
{
}
public static List<ProjectData> GetProjectList()
{
}
}
public class ExcelOperation
{
public void GenerateExcel(List<ProjectDetails> finalExcelData, List<string>projectUrl,List<string>tagsorBranchUrl)
{
}
}
}
I can able to test the method and got the positive output. But I do not know how to test these two method public static List<string> GetBranchList(string projectId), public static List<ProjectData> GetProjectList()
My sample test code is below. Below method is successfully passed in NUnit test.
[TestMethod]
public void CreateTags()
{
List<string> project = new List<string>();
project.Add("test1");
string sourceBranch = "master";
string tagsName = "v1.0.0";
branch.CreateTag(project, sourceBranch, tagsName);
}
How can I test the that two methods?
Update:
I can get the answer with the help of first answer. But Now I have anouther doubt.
How could I test for wrong input? I mean I know that the input I was given Is wrong but I need the green tick mark for that testing. That means the input given is wrong so the output also wrong therfore the testing is right.
In my below image. I need public void GetBranchListforWrongInput() also green tick mark.
How could I do it?
Unit testing static method is pretty much as same as testing non-static methods. It might get complex based on what logic you have in the static method.
But simplest way for your case would be as following.
[TestMethod]
public void TestGetBranchList()
{
string projectId = "someProjectId";
var result = Branches.GetBranchList(projectId);
//Assert if result has expected result.
}
[TestMethod]
public void TestGetProjectList()
{
var result = Branches.GetProjectList();
//Assert if result has expected result.
}
[TestMethod]
public void TestCreateBranch()
{
//Prepare TestData
List<string> projectName = new List<string> {"someProject"};
string sourceBranch = "sourceBranch"
string destinationBranch = "destBranch";
Branches branchesObj = new Branches();
// Call method by passing the test data.
branchesObj.CreateBranch(projectName, sourceBranch, destinationBranch);
}
This should help you resolve your issue.
I am essentially trying to call a C# form from a vbscript. I have been able to get the interoperability to work on non-forms. The following works:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using InteropTestingForm;
[assembly:System.CLSCompliant(true)]
[assembly: ComVisible(true)]
[assembly:Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
namespace InteropTesting
{
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
public class TestReply
{
public string salutation;
public string name;
public string time;
}
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa4")]
public class TestObj
{
public TestObj() { }
public TestReply SayHello(string addressee)
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(Form1());
return SayHello(addressee, "hello");
}
public TestReply SayHello(string addressee, string greeting)
{
string x = String.Format("{0}, {1}!", greeting, addressee);
Console.WriteLine("{0}", x);
TestReply r = new TestReply
{
salutation = greeting,
name = addressee,
time = System.DateTime.Now.ToString("u")
};
return r;
}
}
}
As can be seen in my SayHello() function, I want to run another form, possibly in the same namespace. I am not sure how to accomplish this. I keep getting the following error: "The type or namespace name Form1() could not be found (are you missing a using directive or an assembly reference)? when I try to run the following command from a Visual Studio command prompt:
csc.exe /t:library /debug+ /keyfile:InteropTesting.snk /out:InteropTesting.dll TestObj.cs
I wrote the aspect class and the target class 'using C# Visual Studio 2008.net' but every time I run the application to interweave them only the target class executed but I can't execute aspect class i tried to attach references to rapier-loom and tried to uninstall rapier-loom and install it again but the same problem occurs....what is the problem ?
this is the aspect class:
using System;
using Loom;
using Loom.JoinPoints;
namespace HelloAspect
{
public class TraceAspect : Aspect
{
[Loom.JoinPoints.IncludeAll]
[Call(Advice.Around)]
public T Trace<T>([JPContext]Context ctx, params object[] args)
{
Console.WriteLine(ctx.Instance + "." + ctx.CurrentMethod.Name + " called");
ctx.Invoke(args);
return default(T);
}
}
}
this is the Application method:
using System;
using Loom;
using Loom.JoinPoints;
namespace HelloAspect
{
class Program
{
static void Main(string[] args)
{
string name;
Console.Write("Your name: ");
name = Console.ReadLine();
TraceAspect aspect1 = new TraceAspect();
Target target = Loom.Weaver.Create<Target>(aspect1);
target.Hello(name);
Console.ReadLine();
}
}
}
the Target class is:
public class Target
{
public virtual void Hello(string name)
{
Console.WriteLine("Hello {0}!", name);
}
}
The problem is that you implicitly call the ToString() method of the Target class from your advice method via the ctx.Instance call. This will lead in a endless recursion because ToString is also interwoven by the advice method.
Not sure if this is possible but im wondering how I catch the return of two methods that are assigned to the same delegate (multicast). I basically wondered if there is a way to catch each return value? Perhaps I have to iterate over it, not really sure..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MutiCastDelegate2
{
class Program
{
delegate string HelloWorldDelegate();
static void Main(string[] args)
{
HelloWorldDelegate myDel1 = ReturnHelloWorld;
HelloWorldDelegate myDel2 = ReturnHelloWorld2;
HelloWorldDelegate myMultiDelegate = myDel1 + myDel2;
Console.WriteLine(myMultiDelegate());
Console.ReadLine();
}
public static string ReturnHelloWorld()
{
return "Return Hello World";
}
public static string ReturnHelloWorld2()
{
return "Return Hello World 2";
}
}
}
You can use MulticastDelegate.GetInvocationList() to get access to each delegate in the list, then you just have to call each one and retrieve the results:
var delegates = myMultiDelegate.GetInvocationList();
foreach (var d in delegates)
{
string result = (string) d.DynamicInvoke();
}