How to build a Roslyn syntax tree from scratch? - c#

I want to do some very basic code-gen (converting a service API spec to some C# classes for communicating with the service). I found this question that seems to suggest I can call Syntax.CompilationUnit() to create a new CompilationUnityntax, however I'm unable to make this code compile; I can't find a CompilationUnit method on any of the Syntax classes I can find (nor can I locate any docs on this) :(
CSharpSyntaxTree.Create appears to need a CSharpSyntaxNode, but I can't figure out how to create one of them either :/
I'm using VS 2015 RC with the latest Microsoft.CodeAnalysis NuGet package (1.0.0-rc2).

Seems that Syntax is now SyntaxFactory:
var comp = SyntaxFactory.CompilationUnit()
.AddMembers(
SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName("ACO"))
.AddMembers(
SyntaxFactory.ClassDeclaration("MainForm")
.AddMembers(
SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName("System.Windows.Forms.Timer"), "Ticker")
.AddAccessorListAccessors(
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))),
SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "Main")
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.WithBody(SyntaxFactory.Block())
)
)
);

Related

Reference to type error when adding the DotNetSeleniumExtras package extension

I'm creating a test automation framework in C# .Net using Appium to automate IOS and Android and wanted to use Page Object Design Pattern. So I wanted to utilize the PageFactory extension.
By adding the DotNetSeleniumExtras.PageObjects.Core as NuGet package results in an error (red squiggly lines). 4 errors
CS7069: Reference to type 'IFindsById" claims it is defined in 'WebDriver', but it could not be found.
I needed this extension DotNetSeleniumExtras.PageObjects.Core in order for me to instantiate the Page objects and be able to implement the Page Object Design pattern.
Please let me know if I'm missing something here or if there are any workarounds. Thanks in advance!
Below is my code for added context:
using NUnit.Framework;
using OpenQA.Selenium.Appium.iOS;
using OpenQA.Selenium.Appium.PageObjects;
using SeleniumExtras.PageObjects;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
namespace NativeApp_TestAutomation.Tests.Specs.IOS
{
[TestFixture]
public class LoginTest
{
private IOSDriver<IOSElement> _driver;
private HomeScreen _pageObject;
[OneTimeSetUp]
public void BeforeAll()
{
var capabilities = Capabilities.GetIOSCapabilities("");
var serverUri = Env.ServerIsRemote() ? AppiumServer.RemoteServerUri : AppiumServer.LocalServiceUri;
_driver = new IOSDriver<IOSElement>(serverUri, capabilities, Env.LaunchTimeoutSeconds);
var timeSpan = new TimeOutDuration(new TimeSpan(0, 0, 0, 5, 0));
_pageObject = new HomeScreen(_driver);
PageFactory.InitElements(_driver, _pageObject, new AppiumPageObjectMemberDecorator(timeSpan));
}
}
}
I'm getting the red squiggly lines here with all having the same errors.
One of the most common reasons for that is a mixture of version and assemblies because of different versions and their compatibility.
If you can try following steps the issues most likely would be solved:
Appium.net latest come out with dependency on DotNetSeleniumExtras.PageObjects v3.11.0 and WebDriver 3.141.0
DotNetSeleniumExtras.Core of v3.12.0 (do not use latest, target v3.12.0) come out with dependency on WebDriver 3.12.0
DotNetSeleniumExtras.PageObjects v3.11.0 rely on WebDriver 3.11.0
So by adding WebDriver 3.12.0 version conflict should be fixed.
This one is a simplest approach - if previous version have enough features then It's done and you can just wait for updates.
The second option that can help you is a binding redirects. The idea is pretty simple, you need to ensure that app know where your WebDriver and it is of correct version.
One good explanation is here (but believe me this is the last thing you want to do, fixed in one place become broken in another) Adding a bindingRedirect to a .Net Standard library

How to access android system settings with Unity in C#

I'm making an app and need to be able to check if settings like : Bluetooth/Phone Rotation/Flashlight/Plane Mode/GPS/Phone Brightness/Silent Mode, are activated on an android phone.
I haven't found any way to do it within Unity, using C#. I found ways to do it using Xamarin but none of them work with Unity (or maybe I haven't done it right), the only way I found is using Java and making it into a plugin and call it in a C# script. But I can't find a clear way to make this work. If this is the only solution could you please explain how to do it, all the documentation I find is from old versions from 2014.
I think there is a simple solution for this but I simply can't find it. And the manifest part is not a problem, I'll add the permissions needed.
In Java the methods you want to call should be public or static, you must build your java source as a library (in build.gradle: apply plugin: 'com.android.library'), and add the .aar to Unity's Assets/Plugins/Android/ folder.
Then you can instantiate your plugin in Unity like so:
// this class string is the package at the top of your Java class extended with the class name, e.g.:
// package com.yourcompany.you.package;
string classString = "com.yourcompany.you.package.className";
// Get the class
var tempAjc = new AndroidJavaClass(classString);
// Here you can call a static method on the class that returns an instance of the class if you want to pass some parameters upon creation
_androidObject = tempAjc.CallStatic<AndroidJavaObject>("CreateInstance",
new object[] {arg1, arg2});
// non static call on your new instance
_androidObject.Call("PassingMoreStuff", initParam);
// if you want to return something from Java to Unity:
int javaVal = _androidObject.Call<int>(methodName, parameters);

Xamarin PCL Refit 3.0.1 , Doesn't look like a Refit interface

I recently started working on a Xamarin Android/iOS project with a PCL class where I want to put all the logic in. Like my Refit interfaces, ReactiveUI ViewModels et cetera, but every time when trying to execute my code I get a error saying that my interface is not a Refit interface. Currently my interface looks like this.
public interface IMyApi
{
[Post("/authenticate")]
IObservable<Models.ApiResponses.AuthenticationResponse> SigninRaw([Body] JObject credentials);
[Get("/service")]
IObservable<Models.ApiResponses.MyListResponse> GetServiceListRaw();
[Get("/service/{id}/idstatus")]
IObservable<Models.ApiResponses.IdResponse> GetIdStatusRaw(string Id);
}
As far as I know this looks good and this also works when I'm trying to load this from a specific platform like iOS project. But when trying to do it from a PCL if fails! I have installed the Refit package in both of my platform specific project Android & iOS and I referenced a dll in the PCL, what did I miss?
If there is need for more information or you have any question, please do not hesitate to ask.
Well without further ado, thank you for reading and hopefully someone can assist me with this, because I starting to loose my mind the past couple of days.
Edit: added calling method.
Here I calling it from a ViewModel
var client = new HttpClient(NetCache.UserInitiated)
{
BaseAddress = new Uri("https://api.address.com")
};
var api = RestService.For<IMyApi>(client); <= here it crashes
var response = api.SigninRaw(token);
I've managed to track this down, there are actually a few issues at play. Fortunately there are ways to work around them.
The first problem is that the PCL interfaces aren't being detected in the first place. Refit runs a utility at compile time (InterfaceStubGenerator) which scans the subfolders for interface classes and generates implementation code for each one. These are all packed into an intermediate file called RestStubs.g.cs which gets included in with the assembly. This utility, however, is only run on the projects that Refit has been added to via nuget, and since that doesn't include PCL projects the interfaces in those projects never get processed. The solution is to call this utility manually in a pre-build step and include the generated file in each of the platform projects. Go to your PCL project's property settings and add the following to the pre-build steps:
..\..\..\..\packages\refit.3.0.1\tools\InterfaceStubGenerator.exe ..\..\..\ProjName.Droid\RefitStubs.cs ..\..\..\ProjName
..\..\..\..\packages\refit.3.0.1\tools\InterfaceStubGenerator.exe ..\..\..\ProjName.iOS\RefitStubs.cs ..\..\..\ProjName
That will generate RefitStubs.cs for your platform projects, so add each file to it's respective project.
Ordinarily that would be the end of it were it not for another problem. The RestService.For<> generics that you call to get the implementations make the assumption that the implementation classes reside in the same assembly as their corresponding interfaces. Obviously that isn't the case for PCL projects. To get around this you need to implement your own version of the RestService class, this will probably serve most of your needs:
public static class PclRestService
{
public static T For<T>(string hostUrl)
{
var className = "AutoGenerated" + typeof(T).Name;
var typeName = typeof(T).Namespace + "." + typeof(T).Name.Replace(typeof(T).Name, className);
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var generatedType = assembly.GetType(typeName);
var requestBuilder = RequestBuilder.ForType<T>();
var client = new HttpClient(new HttpClientHandler()) { BaseAddress = new Uri(hostUrl) };
return (T)Activator.CreateInstance(generatedType, client, requestBuilder);
}
}
You then call it like so:
var netService = PclRestService.For<IMyApi>("http://jsonplaceholder.typicode.com");
var result = await netService.GetDataOrSomething();
One last problem you may encounter is multiple declarations of the PreserveAttribute class, which is declared at the top of the stub files. So long as you don't add Refit interfaces to your platform projects this shouldn't happen, but if it does then you have 3 options:
modify the InterfaceStubGenerator utility to not create that code
write a pre-processor to strip that code out once it has been generated
go to Refit's "refit.targets" file and comment-out the line "<Exec Command="$(RefitExecCmd)" />
The Refit tools folder includes the template file used to generate stub files but for some strange reason it's ignored altogether and statically linked to the application, so editing it in the tools folder doesn't do anything at all.

Validate HL7 with C# and nHapi for .NET

I'm looking to validate an HL7 2.3 standard message using C# and .NET version of nHapi project:
https://github.com/duaneedwards/nHapi
I've downloaded the dll's and added to my project both NHapi.Base.dll and NHapi.Model.V23.dll.
I know I should use:
NHapi.Base.validation.MessageValidator
But I can't figure out how IValidationContext theContext should be configured in order to check 2.3 version.
In addition, I can't find any appropriate API docs for it.
Can someone assist?
Methods to validate the message are embedded into the parser. The Implementation of specific rules was intentionally left to implementers (to improve the flexibility). What you need to do is to create the new context:
public class CustomContext : DefaultValidationContext //:IValidationContext
{
//Define the rules and rule Bindings
}
public class Rule1 : IMessageRule
{
//Check whatever you want in the fully parsed message
//For example, check for the mandatory segment, groups cardinalities etc.
}
then
PipeParser p = new PipeParser();
CustomContext myContext = new CustomContext();
p.ValidationContext = myContext;
This is a good starting point: NHapi Documentation
Even I was looking for some solution to validate HL7 V2 messages using NHapi and could not find any good articles. So I decided to go through the NHapi object module to see any helpful information to validate the structure and I found something.
The NHapi HL7 v2 IMessage is implemented using IType interface and it has a property called ExtraComponent. NHapi parser does not throw any exceptions on invalid structure but populates the ExtraComponent property. So if you find ExtraComponent.numComponents() to be more than 0 then you have structural issues on the message.
I have written a validator code in C#. You can download it from github.
https://github.com/shivkumarhaldikar/NHapiValidatator

How to add a link to a file in visual studio using EnvDTE

I am writing a custom scaffolder for our project. And this scaffolder should add links to DTO declarations for client side app.
I have a possibility to retrieve an instance of project item,
$folder = Get-ProjectFolder "Views\Shared"
and I already found that it is possible to add links using ProjectNode.AddNewFileNodeToHierarchy(string, string) method.
I can get a reference to the DTE service by simply accessing $DTE variable predefined in PowerConsole.
The question is how to get instance of ProjectNode I am interested in?
Ok, it was easier than I thought.
Here is a snippet I finished with:
$targetFolder = Get-ProjectFolder "Services" -Project "ServiceModel.Silverlight"
$sourceFile = Get-ProjectItem $ServiceInterfaceOutputPath -Project "ServiceModel"
$sourceFile.Open()
$targetFolder.AddFromFile($($sourceFile.Document.FullName))
In case you are not working with t4 scaffolder, this link can be helpfull : http://social.msdn.microsoft.com/Forums/en/vsx/thread/168d23c8-eee8-4486-a412-147b67673593

Categories

Resources