I am having trouble with what seems to be a trivial use of inheritance in an f# project.
File 1:
namespace MercurySchool.Models
[<AbstractClass>]
type Resource() =
abstract member Href: string with get, set
abstract member Method: string with get, set
abstract member Relations: string[] with get, set
abstract member Id: int with get, set
abstract member Name: string with get, set
abstract member Description: string with get, set
File 2:
namespace MercurySchool.Models
type School() =
inherit Resource()
In File 2 I am getting the following errors:
No constructors are available for the type 'Resource'
The type 'Resource' is not defined.
Feels like there's a simple resolution, but so far it escapes me.
Some background:
Following example and documentation I have found.[reference]
Using VS 2017 Community. Recently updated.
The problem indeed appears to be the order of compilation, as Fydor suggested.
I changed the fsdprog file from this:
<ItemGroup>
<Compile Include="Models\*.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
to a more explicit declaration:
<ItemGroup>
<Compile Include="Models\Resource.fs" />
<Compile Include="Models\school.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
After a few other changes unrelated to this question, the project builds.
Related
I am trying to use SwaggerProvider with Fable (is this even possible?)
//.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="App.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fable.Browser.Dom" Version="2.2.0" />
<PackageReference Include="Fable.Core" Version="3.2.3" />
<PackageReference Include="SwaggerProvider" Version="1.0.1" />
</ItemGroup>
</Project>
//App.fs, code from https://fsprojects.github.io/SwaggerProvider/#/#new-project
module App
open Browser.Dom
open SwaggerProvider
let [<Literal>] Schema = "https://petstore.swagger.io/v2/swagger.json"
type PetStore = OpenApiClientProvider<Schema>
// Get a reference to our button and cast the Element to an HTMLButtonElement
let myButton = document.querySelector(".my-button") :?> Browser.Types.HTMLButtonElement
// Register our listener
myButton.onclick <- fun _ ->
let client = PetStore.Client()
let s =
client.GetInventory()
|> Async.AwaitTask
|> Async.RunSynchronously
|> sprintf "%O"
myButton.innerText <- s
Visual Studio Code Intellisense works fine, which means that everything is ok at design time.
However, when I try to start the project with npm start I get the following exceptions
C:/Root/Work/Horth/Work/Yatp/Client/Fable/src/App.fs(7,17): (7,46) error FSHARP: The type provider 'SwaggerProvider.OpenApiClientTypeProvider' reported an error: Could not load file or assembly 'System.Text.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Could not find or load a specific file. (0x80131621) (code 3033)
C:/Root/Work/Horth/Work/Yatp/Client/Fable/src/App.fs(17,27): (17,33) error FSHARP: The type 'PetStore' does not define the field, constructor or member 'Client'. (code 39)
What am I doing wrong?
If Fable doesn't support type providers (or this type provider), what is the recommended way to consume an OpenApi/Swagger rest api from a Fable application?
I report here the answer from SwaggerProvider maintainer.
SwaggerProvider does not support Fable, we do not emit code compatible
with browsers.
I recommend to try another project -
https://github.com/Zaid-Ajaj/Hawaii Hawaii pretty flexible and
configurable CLI tool that can generate F# clients based on
Swagger/OpenApi schema compatible with Fable.
When mapping an optionset on a virtual entity to its external data source got the following error:
Type mismatch of the external attribute of type ‘System.Nullable`1[System.Int32]’ expected a 'System.Nullable`1[[System.Int32, Microsoft.Xrm.DataProvider.OData.614d0bd27de7e9119c27005056876672.e98901a683e7e9119c27005056876672, Version=1.1.20.0, Culture=neutral, PublicKeyToken=null]]'
Thanks in advance
one cannot map using Int32, hence your error. Using virtual entities in D365 one has to use an enumeration for setting up and mapping optionsets. View the schema from your odata endpoint using $metadata:
example : https://yourowndatasource.azurewebsites.net/$metadata
it will return something like the below, find your defined schema enumtypes :
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="AK.IG.VirtualEntity.DataSource.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EnumType Name="ak_Lead_EventTypeCode">
<Member Name="EugenesCode" Value="821220006" />
<Member Name="LeadSource" Value="821220001" />
<Member Name="LeadGenProcess" 821220001="3" />
...
</EnumType>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
With that use exactly the naming convention :
EnumType.Name
Member Name
I try to add some custom fields to NLog using extensibility.
Part of my nlog.config file looks like that : (simplified for exhibit)
<nlog>
<extensions>
<add assembly="Logzio.DotNet.NLog"/>
</extensions>
<variable name="currentUser" value="test" />
<targets async="true">
<target name="logzio" type="Logzio" token="myToken">
<contextproperty name="currentUser" layout="${currentUser}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logzio" />
</rules>
</nlog>
In every controller, I have something like that (I'm using ASP.NET MVC5)
private static Logger logger = LogManager.GetCurrentClassLogger();
Then I send my logs to logzio using
logger.Fatal("Something bad happens");
Right now, currentUser always have the value test, which is logical.
However, despite of the documentation, I don't understand how to dynamically change currentUser value by the ID of my current logged user.
Should I create a sort of factory ? (if yes, how ? I'm not at ease with factories)
Should I change my logger variable ? If so, how ?
A piece of code would be extremly welcome.
Thank you for pointing my out where I'm wrong
EDIT
After #Rolf's answer, I've created this custom layout renderer
[LayoutRenderer("custom-layout")]
public class CustomLayoutRenderer : LayoutRenderer
{
public string IdUser { get; set; }
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
logEvent.Properties.Add("currentUser", "HowToPassCustomDataHere?");
builder.Append("test from custom-layout");
}
}
and I changed the nlog.config accordingly, adding
layout="${message} ${custom-layout}"
to my <target>
However, I still don't understand how to pass custom value to currentUser. In logz.io, I have "HowToPassCustomDataHere?" as a value of currentUser.
(BTW, ${aspnet-user-identity} is great and works fine ; however I'd like to understand how to pass a custom value to my layout renderer. In my case, something like ${aspnet-user-id})
You can try one of these NLog layoutrenderers to acquire the current username:
${aspnet-user-identity} Wiki
${windows-identity} Wiki
You can also create your own custom NLog LayoutRenderer: https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer
Example of how to provide it as currentUser:
<target name="logzio" type="Logzio" token="myToken">
<contextproperty name="currentUser" layout="${aspnet-user-identity}" />
</target>
There is a 3rd party library I need to use, that includes a class decorated with the [Application] attribute. This causes compiler errors since I have my own application class that uses an [Application] attribute. I would like my application class to inherit from the 3rd party lib's application class.
public class MyApplication : ThirdPartyApplication
{
}
however since I can't decorate my class with the [Application] attribute I have no way to specify in the Manifest that it should run "MyApplication" and not "ThirdPartyApplication".
If I manually add an entry into AndroidManifest.xml
<application
android:name="com.your.packagename.MyApplication"
android:icon="#drawable/luncher_icon"
android:label="#string/app_name">
It will get replaced after the project gets built with
<application
android:name="mdxxx.ThirdPartyApplication"
android:icon="#drawable/luncher_icon"
android:label="#string/app_name">
Does anyone know how to handle this situation in Xamarin Android?
Keep in mind that the 3rd party library can not be modified.
An alternate solution would be a way to disable all manifest generating attributes and manually create the AndroidManifest. There does not seem to be any way to do this either.
The below post is the exact situation I am having but in pure Android. Note that due to the above issues that this solution will not work for Xamarin.
how-to-handle-multiple-application-classes-in-android
So I was able to figure out a solution but it boarders on being a hack.
In short the android manifest is going to be modified using MSBuild.
Step 1: Have your custom application class inherit from the the Third Party lib's custom application and decorate your class with the "Register" tag.
[Register("com.namespace.MyApplication")]
public class MyApplication : ThirdPartyApplication
{
}
Step 2: Have your project include the RoslynCodeTaskFactory NuGet package
Step 3: Unload your project, then add the following in the Project tag
<UsingTask TaskName="UpdateManifest" TaskFactory="CodeTaskFactory" AssemblyFile="$(RoslynCodeTaskFactory)" Condition=" '$(RoslynCodeTaskFactory)' != '' ">
<ParameterGroup>
<AndroidManifestFilename ParameterType="System.String" Required="true" />
<ApplicationName ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.Xml" />
<Code Type="Fragment" Language="cs"><![CDATA[
XmlDocument doc = new XmlDocument();
doc.Load(AndroidManifestFilename);
XmlNode node = doc.DocumentElement.SelectSingleNode("/manifest/application");
node.Attributes["android:name"].InnerText = ApplicationName;
doc.Save(AndroidManifestFilename);
]]></Code>
</Task>
</UsingTask>
<Target Name="CleanManifest" AfterTargets="_GenerateJavaStubs">
<UpdateManifest AndroidManifestFilename="$(ProjectDir)\obj\$(Configuration)\android\AndroidManifest.xml" ApplicationName="com.namespace.MyApplication" />
</Target>
Step 4: Reload the project and build. The manifest should now point to custom application class. If you get a class not found runtime exception most likely you forgot to add [Register] from Step 1.
I want to use ConfigurableActiveDirectoryMembershipProvider in my code. I have my current settings as
<add name="XXXXMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershi pProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="XXXXConnectionString"
connectionUsername="user"
connectionPassword="password"
connectionProtection="Secure" />
I have changed this to
<add connectionStringName=""
name="XXXXDomainADMembershipProvider"
type="Spring.Web.Providers.MembershipProviderAdapter, Spring.Web" />
and added in to my spring config file as
<object id="XXXXDomainADMembershipProvider"
type="Spring.Web.Providers.ConfigurableActiveDirec toryMembershipProvider">
<property name="connectionStringName" value="XXXXDomainConnectionString" />
<property name="connectionUsername" value="user" />
<property name="connectionPassword" value="password" />
</object>
But I am getting the following error
Error creating context 'spring.root': Could not load type from string value 'Spring.Web.Providers.ConfigurableActiveDirectoryM embershipProvider'.
I checked the Spring.WebQuickStart source code and the class Spring.Web.Providers.ConfigurableActiveDirectoryMembershipProvider has been commented out.
Is that the reason I am getting the above error?
Yes, I think you are correct. The error you are getting is exactly the error Spring returns when you are trying to configure an object using a type that can not be loaded. For instance if the class does not exist at all, which appears to be the case here.
You can double check if the ConfigurableActiveDirectoryMembershipProvider class exists by using the object browser to explore the Spring.Web.Providers namespace in the Spring.Web assembly you are using in your project.
You are right that the class is commented out in the current state of the trunk code. It has a small TBD note, so I think they are not sure if they want to implement this. But it could be that it wasn't commented out in the version of Spring.Web you are using, so you should still check it using the object explorer.
Strangely enough, the ConfigurableActiveDirectoryMembershipProvideris mentioned in the documentation - you might want to post this on the Spring.Net forum they're likely to help you.