System.Diagnostics.StackFrame.GetFrame(index) not found in mscorlib - c#

I created two console applications, both targeting v4.5.2 of the .NET framework.
class MyDisposable : IDisposable
{
public void Dispose()
{
var callerName = new StackTrace().GetFrame(1)?.GetMethod()?.Name;
Console.WriteLine($"Dispose called by {callerName}.");
}
}
which run perfectly well.
In the other, I have the following, which are in effect the same.
return Disposable.Create(() =>
{
var stackFrame = new StackFrame();
var callingMethodBase = stackFrame.GetFrame(1)?.GetMethod();
...
});
But Visual Studio intellisense reports:
'StackFrame' does not contain a definition for
'GetFrame' and no extension method 'GetFrame'
accepting a first argument of type 'StackFrame'
could be found (are you missing a using
directive or an assembly reference?)
When I Go to Definition on the StackFramesclass, I see the method GetFrames is absent from the class declaration of the StackFrame class. Both the assembly versions for mscorlib are the same, i.e. v4.0.0.0.
Why is that?

In the first example you are using StackTrace, but in the second you are using StackFrame.
StackTrace has the method GetFrame(), but StackFrame doesn't.

Related

Implement a simple IFindSaga

I have a simple IFindSaga implemented, I referred and followed the same steps that was provided in particular software document for SQL Persistence Saga Finding Logic. I'm getting an error at session.GetSagaData<SagaData> stating that: "SynchronizedStorageSession does not contain a definition for GetSagaData and no extension method GetSagaData accepting a first argument of type SynchronizedStorageSession could be found (are you missing a using directive or an assembly reference)." Please help me to solve this.
This is my code where I have implemented IFindSaga
public class TrackerFind : IFindSagas<SagaData>.Using<ITrackerData>
{
public Task<SagaData> FindBy(ITrackerData message, SynchronizedStorageSession session, ReadOnlyContextBag context)
{
return session.GetSagaData<SagaData>(
context: context,
whereClause: "JSON_VALUE(Data,'$.PaymentTransactionId') = #propertyValue",
appendParameters: (builder, append) =>
{
var parameter = builder();
parameter.ParameterName = "propertyValue";
parameter.Value = message.TrackerID;
append(parameter);
});
}
}
"GetSagaData" is an extension method which is part of "NserviceBus" namespace.
include following statement
using NServiceBus;
This worked for me. I am not getting that error now
use nuget
package NServiceBus.Persistence.Sql

Automatically resolving dependencies when compiling using Roslyn

I'm currently writing an application that currently loads a project via Roslyn's workspace API, turns a specified C# file into a syntax tree then creates an in memory assembly form it, then eventually extracts the IL.
This is all working fine, however as soon as I reference any external libraries within the said C# file, the compilation fails as Roslyn doesn't know where to resolve those references.
Here's a simplified version of what I'm currently doing:
MetadataReference[] metaDatareferences = {
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(DynamicAttribute).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(AssemblyMetadata).GetTypeInfo().Assembly.Location),
};
var sourceLanguage = new CSharpLanguage();
var syntaxTree = sourceLanguage.ParseText(sourceCode, SourceCodeKind.Regular);
var options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: OptimizationLevel.Debug,
allowUnsafe: true
);
CSharpCompilation compilation = CSharpCompilation.Create("ExampleAssembly", options: options);
var stream = new MemoryStream();
var result = compilation.
AddReferences(metaDatareferences)
.AddSyntaxTrees(syntaxTree)
.Emit(stream);
// Success is false
if (!emitResult.Success)
{
foreach (var diagnostic in emitResult.Diagnostics)
{
Debug.WriteLine(diagnostic.ToString());
}
}
The output of the Debug.WriteLine is:
(1,7): error CS0246: The type or namespace name 'MediatR' could not be found (are you missing a using directive or an assembly reference?)
(9,32): error CS0246: The type or namespace name 'Mediator' could not be found (are you missing a using directive or an assembly reference?)
And the file my Roslyn project is reading is simply this:
using MediatR;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var mediator = new Mediator(null, null);
}
}
}
My question is, does Roslyn provide an API for automatically load any dependencies a file may have? I was hopeful that the Roslyn workspace would allow this to be done, but I've not been able to find anything.
If the MediatR console project is a project.json project, then you can use ProjectJsonWorkspace from "Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-1-003177". You can point it at your project.json and get a Compilation object, this will have done all the hard work for you of getting the project references, file references, etc... Then you can just emit your IL from here.
Here is an example:
var compilation = new ProjectJsonWorkspace(#"PathToYour\project.json").CurrentSolution.Projects.First().GetCompilationAsync().Result;
var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);
Or if you need total control, you could continue to use CSharpCompilation.Create, copying in what you need from the compilation object here, and passing in a SyntaxTree.
Hope that helps.

C# won't recognize getAttribute

I transferred VB.Net app to C# and when I build it. This error showed up -
'mshtml.IHTMLImgElement' does not contain a definition for
'getattribute' and no extension method 'getattribute' accepting a
first argument of type 'mshtml.IHTMLImgElement' could be found (are
you missing a using directive or an assembly reference?)
So how can I replace this getattribute call?
This is the code
private void captcha()
{
mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2) WebBrowser1.Document.DomDocument;
mshtml.IHTMLControlRange imgrange = (mshtml.IHTMLControlRange) (((mshtml.HTMLBody) doc.body).createControlRange());
foreach (mshtml.IHTMLImgElement img in doc.images)
{
if (img.getattribute("src").ToString().Contains("urltoimg"))
{
imgrange.add((mshtml.IHTMLControlElement) img);
imgrange.execCommand("copy", false, null);
PictureBox1.Image = (System.Drawing.Image) (Clipboard.GetDataObject().GetData(DataFormats.Bitmap));
break;
}
}
}
Try "GetAttribute".
VB is case-insensitive, so "getattribute" would work in VB, however C# (and virtually every other language) is case-sensitive.
You need to cast the mshtml.IHTMLImgElement to an mshtml.IHTMLElement, which will then give you the getAttribute() method
You could replace this line as:
if (((mshtml.IHTMLElement)img.getAttribute("src")).ToString().Contains("urltoimg"))
Note the casing as 'getAttribute', not 'getattribute'.

Nancy test doesn't find route in other assembly

I have the following spec (using Machine.Specifications or mSpec):
public class when_a_user_logs_in_successfully
{
static Browser _browser;
static BrowserResponse _response;
Establish context = () =>
{
var bootstrapper = new ConfigurableBootstrapper();
_browser = new Browser(bootstrapper);
};
Because of = () => _response = _browser.Get("/Login", with => with.HttpRequest());
It should_return_a_successful_response = () => _response.Body.ShouldNotBeNull();
}
The route from the spec should find the following module:
public class LoginModule : NancyModule
{
public LoginModule()
{
Get["/Login"] = parameters => "test";
}
}
But for some reason, the response has a status of "NotFound" and a Body that throws an exception saying the stream is closed/disposed. My specs solution has a reference to the assembly that contains the LoginModule. What else should I do to make the spec find the route in the module?
It's because you don't have any "hard reference" to the other assembly (i.e. you're not using any of the types in there directly), because of that .Net doesn't load it and Nancy won't find it.
We have an AppDomainAssemblyTypeScanner that you can use to load your assemblies (there's a few methods in there you can use to load a wildcard set of DLLs), or you can bodge it by adding a variable of one of the types in your main assembly into your test assembly.
I think in the future we'll have to change the test runner to load every DLL it can find by default, with the option to change that if it causes issues.

Mono Compiler as a Service (MCS)

I'd like to consume Mono's compiler as a service from my regular .NET 3.5 application.
I've downloaded the latest bits (2.6.7), created a simple console application in Visual Studio and referenced the Mono.CSharp dll.
Then, in my console app (straight out of a sample online):
Evaluator.Run("using System; using System.Linq;");
bool ress;
object res;
Evaluator.Evaluate(
"from x in System.IO.Directory.GetFiles (\"C:\\\") select x;",
out res, out ress);
foreach (var v in (IEnumerable)res)
{
Console.Write(v);
Console.Write(' ');
}
This throws an exception at Evaluator.Run (the first line):
Illegal enum value: 2049.
Parameter name: access
This is because the dll was compiled using Mono.exe, not csc.exe, I believe.
I've tried downloading the Mono.CSharp dll directly from http://tirania.org/blog/archive/2010/Apr-27.html in the demo-repl.zip file...and that does not throw an exception...However the out parameter (res) after calling Evaluator.Evaluate is null...so I'm not sure what's going wrong. No exception is thrown...
So, I'd like to figure out why the dll I downloaded from the demo-repl.zip returns null.
EDIT: I figured out why it returns null. It seems like for some reason the compiler isn't picking up the System.Linq namespace...though I can't tell why...If I just Evaluate "System.IO.Directory.GetFiles (\"C:\\")", it works fine.
UPDATE: It definitely seems like there's something wrong with the Mono compiler picking up referenced System assemblies. If I directly copy the sample of their csharp console tool:
csharp> var list = new int [] {1,2,3};
csharp> var b = from x in list
> where x > 1
> select x;
csharp> b;
I get the exception:
{interactive}(1,25): error CS1935: An implementation of `Select' query expressio
n pattern could not be found. Are you missing `System.Linq' using directive or `
System.Core.dll' assembly reference?
Also, in order for the MCS to actually be a feasible solution, I'll need to modify the compiler so that it emits to one single dynamic assembly, instead of emitting one assembly per evaluate call (otherwise it presents a major memory leak, which I've dealt with before in the form of the CSharpCodeProvider). Does anyone have an idea of how difficult this will be or can anyone point me in the right direction here?
Thanks.
Ok, I think I have some answers.
To resolve the assembly load problem, I can either place a call to Assembly.LoadWithPartialName inside Mono.CSharp.Driver.LoadAssembly, or do the following in my application
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
private static bool isResolving;
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (!isResolving)
{
isResolving = true;
var a = Assembly.LoadWithPartialName(args.Name);
isResolving = false;
return a;
}
return null;
}
To make Mono reuse the same dynamic assembly for each Evaluate/Compile call, all I had to change is the following (although there are probably complexities I'm missing here).....
Inside Mono.CSharp.Evaluator, I added the property:
/// <summary>
/// Gets or sets a value indicating whether to auto reset when evaluations are performed and create a new assembly.
/// </summary>
/// <value><c>true</c> if [auto reset]; otherwise, <c>false</c>.</value>
public static bool AutoReset { get; set; }
Then...make sure Reset is called at least once in Init:
static void Init ()
{
Init (new string [0]);
Reset();
}
And finally, in ParseString, simply don't reset unless AutoReset is true...
static CSharpParser ParseString (ParseMode mode, string input, out bool partial_input)
{
.
.
.
if (AutoReset) Reset ();
According to Miguel's blog page you linked, you have to add a reference to System.Core in order to use LINQ on .Net.
csharp> using System.Linq;
csharp> from x in "Foo" select x;

Categories

Resources