I´ve used the bond-compiler gbc to create some object and a service definition for me:
namespace Something;
struct SomeStruct
{
0: string SomeName;
}
struct SomeResponse
{
0: string ResponseString;
}
service SomeService
{
SomeResponse DoSomething(SomeStruct);
}
The compiler generated a class definition Something_services.cs with this Signature:
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.8.0.0")]
public abstract class SomeServiceServiceBase : ISomeService, global::Bond.Comm.IService
I was wondering about the IService Interface and wanted to know more about this and came to the Bond Communications Framework Doku (https://microsoft.github.io/bond/manual/bond_comm.html). The first thing to read was, that Bond.Comm is deprecated and you should use Bond-over-gRPC (https://microsoft.github.io/bond/manual/bond_over_grpc.html) instead.
I have two questions:
Does someone know, why this is depracted but by default still used by the compiler?
Is there someone who can explain the difference between Bond.Comm and Bond-over-gRPC?
Thanks in advance!
EDIT
And a third question occured: How to use the --grpc-flag mentioned in the documentation?
The Bond C# gRPC bindings first shipped in Bond C# 5.3.0, which was released on 2017-04-14. You will need to upgrade all your Bond NuGet packages to 5.3.0 to start using it.
You are seeing the compiler generate the Comm files by default because you're using a version earlier than 5.3.0.
As noted in the changelog for the 5.3.0 release (and the Bond Comm 0.11.0 release), Bond Comm files are no longer generated by default for C#. To keep using Bond Comm C#, you'll need to start passing --comm to gbc. There's an example that shows what change is needed.
If you want to start using the C# gRPC bindings, you'll need to pass the --grpc option. The gRPC example shows how to do this as well.
Related
I have an old line of c# code that looks basically like this:
foo.set_Parent(parent);
It has compiled fine for years. Now in VS2015 I get the error:
CS0571 'Foo.Parent.set': cannot explicitly call operator or accessor
So I can rewrite the line as:
foo.Parent=parent;
This builds fine in VS2015, but in VS2013 it gives the error:
'Foo.Parent' is not supported by the language; try directly calling
accessor methods 'Foo.get_Parent()' or Foo.set_Parent(Foo)'
So the simple fix is to simply ifdef these two lines based upon which version of the compiler is running. But how do you detect which version of the compiler is executing?
And for the record, no, I can't just dictate that everyone on the team simultaneously upgrades to VS2015.
Additional info -
For everyone smelling a rat, I'll go ahead and drag out the ugly truth, although I don't think it will change much of anything. The class Foo is from an ancient Borland assembly that is all bound up in Delphi (and yes, we're migrating away but not there yet). So the actual code, that compiles up to VS2013, looks like this:
using Borland.Vcl;
using RepGen;
using SnapReportsForm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace MigrantCOM {
[ComVisible(true)]
[Guid("48245BA3-736B-4F98-BDC5-AD86F77E39F4")]
[ProgId("MigrantCOM.Exports")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MigrantCLRExports { // : MarshalByRefObject
public string Test(string s) { return s+s; }
}
[ComVisible(true)]
[Guid("1154D364-B588-4C31-88B9-141072303117")]
[ProgId("MigrantCOM.SnapRepCOM")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class SnapRepCOM {
TRepGen repGen;
TStringList snapRefs=new TStringList();
TForm parent=new TForm(null);
TMemo designerMemo;
List<TReference> references=new List<TReference>();
TRunAsSnapContext runAsSnapContext=new TRunAsSnapContext();
public SnapRepCOM() {
designerMemo=new TMemo(parent); designerMemo.set_Parent(parent);
...
}
So the class being instantiated is Borland.Vcl.TMemo which is part of the old Delphi assembly.
I'm leaving this as an answer, linking an image will fit better here than in a comment.
So if you want to use VS 2015 but still use the same good ol' version of the C# language that worked for years, you can configure your project to target a specific version:
This adds <LangVersion>5</LangVersion> in the csproj.
I have the simplest of apps that I thought I would try on my device before I got too engrossed. However, I am getting the strangest error message when I run it on my iPhone (as apposed to the the emulator on my macbook).
Table has no (public) columns .
I am using the SQLite.Net PCL and I have built it from git hub as I had some problems with it not having the platform dlls for IOS otherwise.
Relevant code.
In my models I have this:
public class Setting
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
[Indexed]
public string Key { get; set; }
public string Value { get; set; }
}
The code that throws this error message is the simple:
using (SQLiteConnection db = GetCon ()) {
db.CreateTable<Setting> ();
}
but in my opinion the strangest thing is that this code works fine on the emulator but crashes the application on the iphone itself.
If anyone has some ideas that would be great.
EDIT:
This error is thrown on the SQLite.Net-PCL library on this file line 380 but only on the device and not on the emulator.
For others to whom this may concern, I found the answer to my problem. The issue was with the Type not having any properties (the type in question the simple model class). Knowing that to be rubbish I found the following links that gave more information which I will relate in this post in case the links go dead:
Type.GetProperties returning nothing
NOTE: Be careful with assembly linker
If you're building with linker enabled you may need to use the class
somewhere, so it will not be ripped off at compile time. Sometimes,
only instantiating the class in your code is not enough, the linker
may detect that the instance is never used and will remove it anyway.
http://developer.xamarin.com/guides/ios/advanced_topics/linker/
The linking process can be customized via the linker behavior
drop-down in Project Options. To access this double-click on the iOS
project and browse to iOS Build > Linker Options, as illustrated below
(see link for details)
I have for now left it to be unlinked, however, I will try before release to get the linker to ignore these classes. Thanks for all your help.
I found my problem was just a (not that subtle) programming error. I was working with the TypeInfo class and wanted to use the Sqlite Connection method:
CreateTable (Type type);
What I had in my hand was a TypeInfo instance which I needed to convert back to the System.Type. I accidentally without thinking used the GetType() method instead of AsType() method which is obvious when you think about it. The clue I got was in the exception message along with the OP message was does System.Runtime have public properties?
var type = table.TypeInfo.AsType();
// var type = table.TypeInfo.GetType(); *WRONG*
connection.CreateTable(type);
I was under the impression Mono's compiler was usable in Microsoft.NET
edit: updated blog posting here that I originally missed that explains some of it (is consistent with Justin's answers)
I created a simple class to try to use it
[TestFixture]
class Class1
{
[Test]
public void EXPR()
{
Evaluator.Run("using System;");
int sum = (int)Evaluator.Evaluate("1+2");
}
}
And a project in Visual Studio 2010 that references C:\Program Files (x86)\Mono-2.10.1\lib\mono\4.0\Mono.CSharp.dll.
However when I try to run this task I get the following exception, thrown at the Evaluator.Run call:
System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'Mono.CSharp.Evaluator' threw an exception.
Source=Mono.CSharp
TypeName=Mono.CSharp.Evaluator
StackTrace:
at Mono.CSharp.Evaluator.Run(String statement)
at Experiments.Class1.EXPR() in W:\Experiments\Class1.cs:line 16
InnerException: System.TypeLoadException
Message=Method 'Mono.CSharp.Location.ToString()' is security transparent, but is a member of a security critical type.
Source=Mono.CSharp
TypeName=Mono.CSharp.Location.ToString()
StackTrace:
at Mono.CSharp.Evaluator..cctor()
InnerException:
A google confirms one other person asking this question but no answer. I tried to start reading the microsoft article on security transparent code but got confused quite quickly. Would someone be able to suggest a quick workaround to allow me to use this? And possibly summarise the security implications, if any, to me (in the context of my situation - in the future I hope to package it with a thick client application, to be used both internally and by end-users)
It has worked under .NET since April of last year.
Small point but I notice you are missing a semi-colon in your expression for sum.
int sum = (int)Evaluator.Evaluate("1+2;");
I only have Mono 2.11 (from git) at the moment and they have changed to using a multi-instance version of the compiler instead of the static version. So, my code looks a little different:
using System;
using Mono.CSharp;
namespace REPLtest
{
class MainClass
{
public static void Main (string[] args)
{
var r = new Report (new ConsoleReportPrinter ());
var cmd = new CommandLineParser (r);
var settings = cmd.ParseArguments (args);
if (settings == null || r.Errors > 0)
Environment.Exit (1);
var evaluator = new Evaluator (settings, r);
evaluator.Run("using System;");
int sum = (int) evaluator.Evaluate("1+2;");
Console.WriteLine ("The sum of 1 + 2 is {0}", sum);
}
}
}
EDIT: I guess I should confirm that I did in fact successfully execute this on .NET 4 (using Visual C# Express 2010 on Windows XP)
EDIT AGAIN: If you have Visual Studio, you can download the latest version of Mono.CSharp and compile it yourself. There is a .sln (solution file) included with the source so you can build it on Windows without Mono. The resulting assembly would run the code above. Miguel has a post explaining the new Mono.CSharp here.
FINAL EDIT: I uploaded the compiled Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
It looks like this is a bug in Mono.
.NET 4 abandoned Code Access Security but kept the concept of Security Transparent Code. In a nutshell, low-level code that does stuff, like call unmanaged code, must be "security critical". Application level code is marked "transparent". "Transparent" code cannot call into "security critical" code.
It sounds like Mono.CSharp.Location.ToString() needs to be marked with the [SecuritySafeCritical] attribute if you want the Mono 2.10 code to work with .NET 4. Maybe even better would be marking all of Mono.CSharp as SecuritySafeCritical.
http://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute.aspx
PS. Sorry to have multiple answers for one question. After I realized that 2.11 would work, I became more curious about what the error with 2.10 meant. I cannot really combine this answer with the others.
I decided I should have kept the code more like the question but I did not want to overwrite my previous answer:
The code below works with version 2.11 of Mono.CSharp (available here including a solution file for building with Visual Studio/.NET). It was tested with .NET 4 on Windows XP. I do not have access to Mono 2.10 at the moment.
[TestFixture]
class Class1
{
private Evaluator evaluator;
public Class1()
{
var report = new Report(new ConsoleReportPrinter());
evaluator = new Evaluator(new CompilerSettings(), report);
}
[Test]
public void EXPR()
{
evaluator.Run("using System;");
int sum = (int)evaluator.Evaluate("1+2;");
}
}
EDIT: I uploaded the Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
IronRuby and VS2010 noob question:
I'm trying to do a spike to test the feasibility of interop between a C# project and an existing RubyGem rather than re-invent that particular wheel in .net. I've downloaded and installed IronRuby and the RubyGems package, as well as the gem I'd ultimately like to use.
Running .rb files or working in the iirb Ruby console is without problems. I can load the both the RubyGems package, and the gem itself and use it, so, at least for that use case, my environment is set up correctly.
However, when I try to do the same sort of thing from within a C# (4.0) console app, it complains about the very first line:
require 'RubyGems'
With the error:
no such file to load -- rubygems
My Console app looks like this:
using System;
using IronRuby;
namespace RubyInteropSpike
{
class Program
{
static void Main(string[] args)
{
var runtime = Ruby.CreateRuntime();
var scope = runtime.ExecuteFile("test.rb");
Console.ReadKey();
}
}
}
Removing the dependencies and just doing some basic self-contained Ruby stuff works fine, but including any kind of 'requires' statement seems to cause it to fail.
I'm hoping that I just need to pass some additional information (paths, etc) to the ruby runtime when I create it, and really hoping that this isn't some kind of limitation, because that would make me sad.
Short answer: Yes, this will work how you want it to.You need to use the engine's SetSearchPaths method to do what you wish.
A more complete example
(Assumes you loaded your IronRuby to C:\IronRubyRC2 as the root install dir)
var engine = IronRuby.Ruby.CreateEngine();
engine.SetSearchPaths(new[] {
#"C:\IronRubyRC2\Lib\ironruby",
#"C:\IronRubyRC2\Lib\ruby\1.8",
#"C:\IronRubyRC2\Lib\ruby\site_ruby\1.8"
});
engine.Execute("require 'rubygems'"); // without SetSearchPaths, you get a LoadError
/*
engine.Execute("require 'restclient'"); // install through igem, then check with igem list
engine.Execute("puts RestClient.get('http://localhost/').body");
*/
Console.ReadKey();
VS 2008
I have this code snippet I found on a VB website.
But for some reason I am having trouble converting it to C#.
My.Computer.Network.IsAvailable
Many thanks,
using System.Net.NetworkInformation;
internal class Program
{
private static void Main()
{
NetworkInterface.GetIsNetworkAvailable();
}
}
Yes, garethm is right, this class (Network) is from a VB.NET library - you need to reference the Microsoft.VisualBasic assembly if using in a C# project.
Microsoft.VisualBasic.Devices.Network n = new Microsoft.VisualBasic.Devices.Network();
if (n.IsAvailable)
{
// do stuff
}
Works for me - my network is available :).
As far as how Network relates to NetworkInterface class, it depends on what you want to do next. For instance, Network has such nice stuff as NetworkAvailabilityChanged event, and UploadFile method. On the other hand, NetworkInterface can give you a bunch of specific technical info such as speed or whether it supports multicast.
BTW, there is nothing undocumented about using a class from Microsoft.VisualBasic namespace - it's the core idea behind .NET that you can use classes from assemblies regardless of the language they were written in.
What I generally do is write a small app, then load then project in Reflector and disassemble it.
but you can use this class:
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
Isn't the whole "My" thing from a VB library?
This appears to work. It's probably very undocumented usage though:
Microsoft.VisualBasic.Devices.Network net = new Microsoft.VisualBasic.Devices.Network();
if (net.IsAvailable)
{
Text = "Network is available";
}
else
{
Text = "Network unavailable";
}
Note that I needed to add a reference to Microsoft.VisualBasic to my project.