I am working through a tutorial on SignalR using F# and I have run into a problem. The SignalR IHubConnectionContext has an .All property that is dynamic. You are supposed to define the method here that the client will wire up to receive notifications from the server. It works fine in C#. However, in F#, I am getting:
The field, constructor or member 'yourMethodHere' is not defined
Does anyone have any ideas? Thanks in advance.
I've used self hosting signalr in F# it works just fine. I also have two different libraries that can bridge this gulf you are having.
A.
You can use my apache licensed open source library FSharp.Interop.Dynamic (PCL w/ .net 4.5, WinRT, Silverlight 5.0) that implements the late binding operator ? using the DLR.
open FSharp.Interop.Dynamic
...
Clients.All?yourMethodHere(some, args)
B.
If you want a little more typing. I also wrote another apache licensed library ImpromptuInterface (.net 4.0 or Silverlight 5.0) that will generate an Interface to dlr proxy. Such that you can define an interface to talk to dlr objects.
type IClientsAll =
abstract yourMethodHere : string * string -> unit
...
open ImpromptuInterface
...
let clientsAll = Clients.All.ActLike<IClientsAll>()
clientsAll.yourMethodHere(some, args)
Related
After implementing a type checker in Rascal using TypePal, how do I hook it up to the Eclipse IDE? Any resources or repositories to the solution to this problem would be appreciated, Thanks.
in Eclipse search path of the Rascal Navigator view in your project you will find the rascal_eclipse library which contains a good example: demo::lang::Pico::Plugin
in this module you see how to register a language with Eclipse:
registerLanguage("Pico Language", "pico", parsePico); where parsePico is a function reference. Pass your own parameters here. The registerLanguage function comes from util::IDE.
now you can open files with the "IMP editor" in Eclipse and they will use your parser and show syntax highlighting.
next up is registering other effects with the IDE. The library function to call is registerAnnotator. You pass it a function that takes a parse tree for your language and annotates it with error messages:
the messages may be distributed over the tree, using #message or
using a list of #messages at the top of the tree
the error messages will be added as annotations in the editor and registered with the Problem View automatically.
So you have to wire the output of TypePal into the annotator function yourself. Which should be a one-liner.
Alternatively, running type-checks can also be useful after a "save" action. In this case you can register another type of contribition (also in the Pico demo), called builder: builder(set[Message] ((&T<:Tree) tree) messages), and register that with the registerContributions function.
The Message ADT is the same for the annotator and the builder. Both have the effect of adding editor annotations and problems in the view.
Here is some example code taken from an older open-source DSL project called "Bird", https://github.com/SWAT-engineering/bird:
Tree checkBird(Tree input){
model = birdTModelFromTree(input, pathConf = config(input#\loc)); // your function that collects & solves
types = getFacts(model);
return input[#messages={*getMessages(model)}]
[#hyperlinks=getUseDef(model)]
[#docs=(l:"<prettyPrintAType(types[l])>" | l <- types)]
;
}
birdTModelFromTree calls collectAndSolve from TypePal and returns the TModel
getMessage comes from TypePal's Utilities and extracts a list[Message] from the TModel that can be directly communicated to Eclipse via the #messages annotation.
The entire checkBird function is registered as an annotator using the util::IDE function registerAnnotator.
This code hasn't been used for a while, so if you run into trouble, please contact again?
I try to write some custom lint rules. To achieve this, I used the analyzer_plugin package and I set up my project as it should be. Here is a simplified excerpt of the main class :
class LintAnalyzerPlugin extends ServerPlugin {
#override
Future<void> analyzeFile({required AnalysisContext analysisContext, required String path}) async {
channel.sendNotification(
AnalysisErrorsParams(path, [getAnalysisError(path)]).toNotification(),
);
}
}
channel.sendNotification is called but no message is displayed into VS Code Problems panel.
After some investigation, I found out that the JSON generated for the sent notification use Dart server Legacy protocol. But the Dart analyzer server run by Dart Code extension wait for LSP (Microsoft Language Server Protocol).
Fortunately the extension offers a setting to start the server with the Legacy protocol:
"dart.useLegacyAnalyzerProtocol": true
And now the VS Code Problems panel populates sent notifications.
Unfortunately Dart Code extension advises to use LSP because the Legacy protocol will eventually be removed some day.
Is it possible to generate LSP? Or did I miss something?
If anyone has any suggestions, I'm all ears.
I am trying to disable CORS in TEdgeBrowser and found a lot of solutions by using ICoreWebView2EnvironmentOptions because TEdgeBrowser is implement by WebView2.
In Microsoft's document, the sample code seems to used for Visual C++ and C++ Builder is not applicable:
auto options = Microsoft::WRL::Make<CoreWebView2ExperimentalEnvironmentOptions>();
Here is the code I have tried in C++ Builder 11:
_di_ICoreWebView2EnvironmentOptions *m_WV2_EnvOpt = new _di_ICoreWebView2EnvironmentOptions();
m_WV2EnvOpt->put_AdditionalBrowserArguments(L"--disable-web-security");
It would fail in m_WV2EnvOpt->put_AdditionalBrowserArguments().
I have no idea and maybe I got the wrong way. Can someone help me?
_di_ICoreWebView2EnvironmentOptions is a typedef for DelphiInterface holding a ICoreWebView2EnvironmentOptions* pointer. You don't use new on DelphiInterface itself, you new a class that implements the interface, eg:
class TCoreWebView2EnvironmentOptionsImpl : public ICoreWebView2EnvironmentOptions
{
// implement IUnknown and ICoreWebView2EnvironmentOptions as needed...
};
_di_ICoreWebView2EnvironmentOptions m_WV2_EnvOpt = new TCoreWebView2EnvironmentOptionsImpl;
However, WRL objects are not used this way.
In this case, the WebView2 library exposes ICoreWebView2EnvironmentOptions as a COM object, so you can use CoCreateInstance() to instantiate it (the CLSID for the WebView2 library is 26D34152-879F-4065-BEA2-3DAA2CFADFB8, and the IID for ICoreWebView2EnvironmentOptions is 2FDE08A8-1E9A-4766-8C05-95A9CEB9D1C5), eg:
_di_ICoreWebView2EnvironmentOptions m_WV2_EnvOpt;
CoCreateInstance(LIBID_WebView2, NULL, CLSCTX_INPROC_SERVER, IID_ICoreWebView2EnvironmentOptions, (LPVOID*)&m_WV2_EnvOpt);
However, that doesn't help you in this situation, because you would have to provide the created ICoreWebView2EnvironmentOptions object when creating the WebView2 object, and AFAIK TEdgeBrowser simply does not allow you to do that.
You could try setting the WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS environment variable before the WebView2 object is created, but AFAIK this method does not support the --disable-web-security option.
I am doing automation in my company. We are a C# workshop.
Currently I am working on automated build. NANT is flow control tool. While NANT is not actively developed (last binary released on June 2012 and github repo is not active), MSBuild is better. Therefore, I prefer MSBuild but retiring NANT is still questionable - what is the cost?
I have come up with some pros and cons, but I know collective intelligence is better. Thanks for your help!
Update:
I have read the question, but the second answer rises a concern for me. On build machine there are multiple .NET frameworks, will it be troublesome?
MSBuild
Pros:
Commercial support
Community is growing
Intergrated with VS and TFS
Keep pace with .Net
Cons:
Rewrite current script
Not familiar by people
NANT
Pros:
Already in use
Familiar by people
Cons:
Not updated for a long time (since 2012)
Community is not active
Lack of new .Net support
We wrote FlubuCore (rewrite of Flubu). It's an open source C# library for building projects and executing deployment scripts using C# code.
Main advantages of flubu that I see are:
.Net Core support.
Easy to learn and to use because you write build script entirely in C#.
Fluent interface and intelisense.
Quite a lot of built in tasks (compile, running tests, managing iis, creating deploy package, publishing nuget packages, executing powershell scripts...)
Write your own custom c# code in script and execute it..
Run any external program or command in script with RunProgramTask.
Reference any .net library or c# source code file in buildscript. Now also available option to reference nuget package in build script.
Write tests, debug your build script..
Use flubu tasks in any other .net application.
Web api is available for flubu. Useful for automated deployments remotely.
Write your own flubu tasks and extend flubu fluent interface with them.
You can find flubu on nuget:
Search for FlubuCore.Runner if u need it for .net project
Search for dotnet-flubu if u need it for.net core project
Example of how flubu is used in .net:
protected override void ConfigureBuildProperties(IBuildPropertiesContext context) {
context.Properties.Set(BuildProps.NUnitConsolePath,
# "packages\NUnit.ConsoleRunner.3.6.0\tools\nunit3-console.exe");
context.Properties.Set(BuildProps.ProductId, "FlubuExample");
context.Properties.Set(BuildProps.ProductName, "FlubuExample");
context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}
protected override void ConfigureTargets(ITaskContext session) {
var loadSolution = session.CreateTarget("load.solution")
.SetAsHidden()
.AddTask(x => x.LoadSolutionTask());
var updateVersion = session.CreateTarget("update.version")
.DependsOn(loadSolution)
.SetAsHidden()
.Do(TargetFetchBuildVersion);
session.CreateTarget("generate.commonassinfo")
.SetDescription("Generates common assembly info")
.DependsOn(updateVersion)
.TaskExtensions().GenerateCommonAssemblyInfo()
var compile = session.CreateTarget("compile")
.SetDescription("Compiles the solution.")
.AddTask(x => x.CompileSolutionTask())
.DependsOn("generate.commonassinfo");
var unitTest = session.CreateTarget("unit.tests")
.SetDescription("Runs unit tests")
.DependsOn(loadSolution)
.AddTask(x => x.NUnitTaskForNunitV3("FlubuExample.Tests"));
session.CreateTarget("abc").AddTask(x => x.RunProgramTask(# "packages\LibZ.Tool\1.2.0\tools\libz.exe"));
session.CreateTarget("Rebuild")
.SetDescription("Rebuilds the solution.")
.SetAsDefault()
.DependsOn(compile, unitTest);
}
//// Some custom code
public static void TargetFetchBuildVersion(ITaskContext context) {
var version = context.Tasks().FetchBuildVersionFromFileTask().Execute(context);
int svnRevisionNumber = 0; //in real scenario you would fetch revision number from subversion.
int buildNumber = 0; // in real scenario you would fetch build version from build server.
version = new Version(version.Major, version.Minor, buildNumber, svnRevisionNumber);
context.Properties.Set(BuildProps.BuildVersion, version);
}
Example of how flubu is used in .net core
public class MyBuildScript : DefaultBuildScript
{
protected override void ConfigureBuildProperties(IBuildPropertiesContext context)
{
context.Properties.Set(BuildProps.CompanyName, "Flubu");
context.Properties.Set(BuildProps.CompanyCopyright, "Copyright (C) 2010-2016 Flubu");
context.Properties.Set(BuildProps.ProductId, "FlubuExample");
context.Properties.Set(BuildProps.ProductName, "FlubuExample");
context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}
protected override void ConfigureTargets(ITaskContext context)
{
var buildVersion = context.CreateTarget("buildVersion")
.SetAsHidden()
.SetDescription("Fetches flubu version from FlubuExample.ProjectVersion.txt file.")
.AddTask(x => x.FetchBuildVersionFromFileTask());
var compile = context
.CreateTarget("compile")
.SetDescription("Compiles the VS solution and sets version to FlubuExample.csproj")
.AddCoreTask(x => x.UpdateNetCoreVersionTask("FlubuExample/FlubuExample.csproj"))
.AddCoreTask(x => x.Restore())
.AddCoreTask(x => x.Build())
.DependsOn(buildVersion);
var package = context
.CreateTarget("Package")
.CoreTaskExtensions()
.DotnetPublish("FlubuExample")
.CreateZipPackageFromProjects("FlubuExample", "netstandard2.0", "FlubuExample")
.BackToTarget();
//// Can be used instead of CreateZipPackageFromProject. See MVC_NET4.61 project for full example of PackageTask
//// context.CreateTarget("Package2").AddTask(x =>
x.PackageTask("FlubuExample"));
var test = context.CreateTarget("test")
.AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests"))
.AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests2"));
context.CreateTarget("Rebuild")
.SetAsDefault()
.DependsOn(compile, test, package);
}
}
Detailed presentation and documentation can be found here:
https://github.com/flubu-core/flubu.core
You can find full examples here:
https://github.com/flubu-core/examples
Thanks for all answers. We have decided to use Cake since we are a C# workshop.
There is a property nant.settings.currentframework which is used to set target framework in case you have multiple .net framework
<property name="nant.settings.currentframework" value="net-2.0" />
As per .92 build:
nant.settings.currentframework The current target framework, eg. 'net-1.0'.
nant.settings.currentframework.description Deprecated. Description of the current target framework.
nant.settings.currentframework.frameworkdirectory Deprecated. The framework directory of the current target framework.
nant.settings.currentframework.sdkdirectory Deprecated. The framework SDK directory of the current target framework.
nant.settings.currentframework.frameworkassemblydirectory Deprecated. The framework assembly directory of the current target framework.
nant.settings.currentframework.runtimeengine Deprecated. The runtime engine of the current target framework if used eg. mono.exe.
I have an interface like this:
#Remote
public interface ClientDataAccessRemote
And the EJB implements it:
#Stateless
public class ClientDataAccess implements ClientDataAccessRemote
And in the remote client I can access the EJB with this:
#EJB
private static ClientDataAccessRemote clientDataAccess;
This is everything I did and it works. The client and the EJB reside on the same server. Would it still work if they were separated? And how would the container find the EJB with that interface? I implemented this with Netbeans and I didnĀ“t have to specify any locations or anything like that. How does this work?
Unfortunatelly #EJB annotation works for local (single JVM) injections only. For separate hosts you need to fallback to plain JNDI lookup.
AFAIK there are some proprietary non-portable solutions to perform remote dependency injections, like for WebLogic server (here), but I wouldn't go that way.
JNDI lookup works but is overly complicated and quite ugly:
you need to know server vendor and add its client libraries to your app's dependencies,
you pollute application with:
cryptic vendor-specific URI formats
vendor-specific naming service port numer (often defaults to 1099, but who knows for sure...)
vendor-specific jndi-name pattern
Here is example lookup for bean hosted on remote JBoss 4.x instance:
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
InitialContext context = null;
ClientDataAccessRemote cl = null;
try {
context = new InitialContext(properties);
cl = (ClientDataAccessRemote) context.lookup("ClientDataAccess/remote");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Given your EJB is part of EAR you need to prefix name of EJBean with name of EAR:
cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote");
Above example is JBoss specific, I'm not even sure if it will work with JBoss 5.x series without modifications.
Apparently EJB 3.1 specification brings some unification to jndi naming, but I haven't got pleasure to work with it yet.
If this example scared you a little, maybe a better solution would be exposing your EJB as web services (SOAP or REST style).
It brings problems of it's own, but is portable at least.