Is it possible to define public static readonly field in F#? - f#

This SO question is similar, but I do not see the answer which would satisfy me.
So, how does the equivalent of public static readonly string Name = ...; look in F#?
I can define static member Name = ..., but this creates static readonly property.

I do not think there is a way to get a public static readonly field in F#.
If you use static let, you end up with a private field (and, in fact, I think this is actually compiled as a private field with a private static property Xyz):
type B() =
static let Xyz = 1
You can define actual fields with val, but this does not support initialization (so you need to set it in a static constructor) and the compiler requires such fields to be private:
type A() =
static do A.Xyz <- 1
[<DefaultValue>]
static val mutable private Xyz : int
If you try to make the field public, you will get:
error FS0881: Static 'val' fields in types must be mutable, private and marked with the '[]' attribute. They are initialized to the 'null' or 'zero' value for their type. Consider also using a 'static let mutable' binding in a class type.
I think the error message gives an answer to your question. That said, I cannot think of a good reason why you would need a static public field - a let binding in a module should typically cover the use cases that you might have for a static public field (unless you need this because some library looks for static public fields via reflection...).

Related

Specify type for dynamic variable in named constructor

Consider the following class.
class Test {
final String foo;
final dynamic bar;
Test({this.foo, this.bar});
Test.barInt({this.foo, this.bar});
}
How would the field bar be speified as an int in the named constructur barInt?
You can just specify the type before the parameter:
Test.barInt({this.foo, int this.bar});
be aware that later in the code it is possible to change the value of bar to any type from its setter.
You might want to check out generics for this use case.

Customize swagger schema for a nested type using swashbuckle

I have an api (ASP.NET Core 3.0) that allows users to search a document database using various query parameters to filter and order the results. One of the parameters is an Order parameter that defines how to order the results. The acceptable values are limited to the values of an enum.
I now need to add more behavior to the enum, so I re-wrote it as an Enumeration Class so that I can add object-oriented behavior to it. The problem I now have is that Swashbuckle flattens out the properties of the Enumeration rather than leaving it as a single parameter. Here are my enumeration and parameter classes:
// Enumeration
public class DocSearchOrder : Enumeration {
public static readonly DocSearchOrder DocType = new DocSearchOrder(2, nameof(DocType));
public static readonly DocSearchOrder DocTypeDesc = new DocSearchOrder(3, nameof(DocTypeDesc));
public static readonly DocSearchOrder DocDate = new DocSearchOrder(4, nameof(DocDate));
public static readonly DocSearchOrder DocDateDesc = new DocSearchOrder(5, nameof(DocDateDesc));
public DocSearchOrder(int value, string name) : base(value, name) {
}
}
// Search Parameters
public class DocSearchParameters {
public DocSearchOrder? Order { get; set; }
// Lots of other search parameters
}
Then the method that uses it:
public async Task<IActionResult> GetAsync([FromQuery] DocSearchParameters searchParams) {
// Do the search
}
Swashbuckle flattens searchParams.Order into DocSearchOrder.Id and DocSearchOrder.Name.
The behavior I want to achieve is for my Swagger UI to continue to show a dropdown of the available values (DocSearchOrder.Name) that a user can select from with the parameter named "Order". You then pass one of those string values and a custom model binder converts the string to the Enumeration class instance.
I've tried writing a custom IOperationFilter but that only seems to work for modifying the schema of types passed to the GetAsync method, I can't intercept the schema generation for searchParams.Order. I thought what I'd be able to do is somehow intercept the schema generation for any property that is an Enumeration and generate an enum schema for it instead of an object schema, but I don't know how to intercept it.
So my question is: is there a way to customize the schema generation for a nested type? Or is there another way to go about this and I'm doing it all wrong? :)
How about a regular enum:
public enum DocSearchOrder
{
DocType = 2,
DocTypeDesc = 3,
DocDate = 4,
DocDateDesc = 5
}
I think that would that be easier, and there should not give you much trouble
Here is an example from one of mine:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=TestEnum#/TestEnum/TestEnum_Get

Automatically assign constructor parameters to member variables with Autofac?

When using Autofac I find myself writing a lot of boilerplate code like this:
public class MyClass {
[...]
public MyClass(IFoo foo, IBar bar, IBaz baz) {
_foo = foo;
_bar = bar;
_baz = baz;
}
}
Is there a way of automatically assigning constructor-injected dependencies to their equivalent member variables based on name convention (a la AutoMapper) with Autofac? Or maybe you could use attributes to tell Autofac which properties it should inject, eg.:
[DependencyInjected]
private IFoo _foo;
[DependencyInjected]
private IBar _bar;
[DependencyInjected]
private IBaz _baz;
Is there a way of automatically assigning constructor-injected dependencies to their equivalent member variables based on name convention (a la AutoMapper) with Autofac?
No, not unless you build it yourself. Autofac is only compatible with standard OOP practices, which do not include using Reflection to populate private member variables.
When implementing the Dependency Injection pattern in C# there are 3 different ways that dependencies can be injected:
Constructor Injection
Property Injection (also called Setter injection)
Method Injection
There is no accepted pattern for injecting private member variables. In fact, this cannot be done with standard OO principles, in .NET it can only be accomplished using Reflection.
Also, when using the the Dependency Injection pattern, there is no rule that says you must use a DI container such as Autofac. In fact, the use of a DI container is completely optional when applying the DI pattern. For example, when making unit tests it is easy to use the pattern without Autofac - here is an example that uses NUnit and Moq.
[Test]
public void TestDoSomething()
{
// Arrange
var foo = new Mock<IFoo>();
var bar = new Mock<IBar>();
var baz = new Mock<IBaz>();
var target = new MyClass(foo.Object, bar.Object, baz.Object);
// Act
var result = target.DoSomething();
// Assert
Assert.IsNotNull(result);
// Test other conditions
}
On the other hand, if you add this extra bit of Reflection, you would need access to it in order to populate your MyClass with dependencies.
[Test]
public void TestDoSomething()
{
// Arrange
var foo = new Mock<IFoo>();
var bar = new Mock<IBar>();
var baz = new Mock<IBaz>();
var target = new MyClass();
// Use Reflection to insert the dependencies into the object
InjectDependencies(target, foo.Object, bar.Object, baz.Object);
// Act
var result = target.DoSomething();
// Assert
Assert.IsNotNull(result);
// Test other conditions
}
A big concern here is that the code will compile fine if you completely remove the InjectDependencies(target, foo, bar, baz); line and you will probably end up with a NullReferenceException at runtime somewhere in your class. The purpose of an instance constructor is:
to create and initialize any instance member variables when you use the new expression to create an object of a class.
This guarantees the object is correctly constructed with all of its dependencies. A typical example of the DI pattern with constructor injection:
public class MyClass
{
private readonly IFoo _foo;
private readonly IBar _bar;
private readonly IBaz _baz;
public MyClass(IFoo foo, IBar bar, IBaz baz) {
_foo = foo ?? throw new ArgumentNullException(nameof(foo));
_bar = bar ?? throw new ArgumentNullException(nameof(bar));
_baz = baz ?? throw new ArgumentNullException(nameof(baz));
}
}
The above example uses the readonly keyword and guard clauses in the constructor (which are missing from your example) to guarantee the instance of MyClass cannot be created unless all of its dependencies are supplied. In other words, there is a 0% chance that any of the member variables will ever be null, so you will not have to worry about increasing the complexity of the code by adding null checks to the rest of the class. There is also a 0% chance that any code outside of the constructor can change any of the dependencies, which could cause hard-to-find stability issues with the application.
The bottom line is, you could use Reflection to populate your classes this way if you would like to build your own Autofac extension and write null checks throughout your class, but I wouldn't recommend it because you are taking something that is achieving loose coupling with pure OOP and turning it into a tightly-coupled piece of Reflection code that all of your classes (and anyone who uses them) will depend upon.
You are also removing the possibility of using the handy features of C# that guarantee that the instance will always have all of its dependencies regardless of the context in which it is used (DI container or no DI container) and that they cannot be unwittingly replaced or set to null during runtime.
Workaround
If your primary concern about "boilerplate code" is that you have to type the constructor code yourself, here are a couple of Visual Studio extensions that automate that part:
DependencyInjectionToolset
DiConstructorGeneratorExtension
Unfortunately, neither one of them seems to add the guard clause to the constructor.

Swift:Class cannot be declared public because its Super class is internal

I am trying to declare the class as public as shown below
class RewardsAndRedemptionModel:BaseObject {
var rewardHistory :[RewardHistoryModel]!
}
This is where i am trying to make the class public but i could not.
public class RewardHistoryModel :BaseObject {
var rewardValue : String!
var recordedByName : String!
var rewardFor : String!
}
Even i read the documentations available on Internet i couldn't get it please help me out.
The compiler tells you that you can't make it public because the super class is internal. The compiler isn't lying, you know.
No subclass can be more accessible than its super class. Why? Think about it this way, a subclass has all the properties and members that its super class has. If this restriction didn't exist, then access modifiers will not be as useful anymore. You have an internal class. Someone else subclasses your internal class and declare it as public. Now encapsulation is broken. Things that you don't want to be accessed can now be accessed through the subclass.
In other words, if a subclass is more accessible than its super class, then the access modifier of the super class loses effect. That's why the compiler has this restriction: to remind you that what you're writing can make the super class' access modifier lose effect. You're probably doing the wrong thing.
To fix the problem, declare BaseClass and its super classes as public.
Swift 3
You need to declare the access level of the RewardHistoryModel & BaseObject class & their internal members like functions or variables as public or open (open is available in swift 3).
public class BaseObject {
// set member of this class as public that you want to access outside (Project/Framework Level)
}
public class RewardHistoryModel :BaseObject {
// set members as public or open - // open is available in swift 3.
public (or open) var rewardValue : String!
public (or open) var recordedByName : String!
public (or open) var rewardFor : String!
}
As stated in the documentation (The Swift Programming Language - Access Control) :
A public variable cannot be defined as having an internal or private
type, because the type might not be available everywhere that the
public variable is used.
Classes are declared as internal by default, so you have to add the public keyword to make them public.
A similar rule exists for functions as well.
A function cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code.
You have to declare BaseObject class as public as well.

Why do scope modifiers on fields in domain classes prevent validation?

I'm just starting with Grails (coming from Rails) and I noticed that Grails really doesn't seem to like scope modifiers on fields in domain classes.
I had understood that all unscoped fields in a domain class were by default public, but if you actually declare it public, Grails won't validate it.
class Person {
public String firstName
public String middleName
public String lastName
}
If you add a constraint, Grails will throw a NotReadablePropertyException exception when you call validate()
class Person {
public String firstName
public String middleName
public String lastName
static constraints = {
middleName nullable: true
}
}
However if you take out the public declaration, everything works normally.
Can someone explain what's going on behind the scenes with the scoping in domain classes? Hard to understand why explicitly declaring something public which is already public would break the framework. I'm guessing you wouldn't want to declare anything 'private' either, although it would be nice if there was away that a fields which shouldn't be manipulated directly could be hidden from consumers of the domain class.
When you add a field to a Groovy class without a scope modifier, it's more that it's inferred to be public than being actually public. The compiler converts the field to a private field and generates a public getter and a setter for it, although it won't overwrite a getter or setter that you wrote. This is convenient because you can later write getters and/or setters to implement business logic and not affect the callers.
But a public field (declared as 'public') is just that - a public field. There's no generated getter or setter. I recommend using a decompiler to see this in action - create a simple POGO in src/groovy, e.g.
class Thing {
String realProperty
public String fieldButNotProperty
}
and open up the .class file with http://jd.benow.ca/ or another decompiler.
GORM automatically assumes that typed properties are persistent unless you exclude some with the transients list. The type is required so it knows how to persist the data, and properties like def name will be ignored. Properties in this sense are similar to JavaBean properties - a matched getter/setter pair.
Hibernate has no support for Groovy and doesn't know what's going on under the hood - it just calls your getters and setters to set and access field data during persistence. So the Groovy compiler adding those in makes it easy for POGOs in Grails to be persisted by Hibernate. And you could do this yourself - add in a getter and setter with correct names and data type (e.g. String getName() and void setName(String name) and it will be treated as a persistent property, even if you do nothing with the values.
The reason for the NotReadablePropertyException is that there's no getter to call for your 'property'. Even though your fields are perfectly accessible, you've effectively hidden them from GORM and Hibernate.
If you add a constraint, Grails will throw a NotReadablePropertyException exception when you call validate()
Never noticed this before, sounds like a bug
it would be nice if there was away that a fields which shouldn't be manipulated directly could be hidden from consumers of the domain class.
If you want to prevent direct access to a property, simply add a getter and setter. In the (contrived) example below, I ensure that name is always read/written as an upper case string.
class Person {
public String firstName
public String middleName
public String lastName
public void setFirstName(String name) {
this.firstName = name.toUpperCase()
}
public String getFirstName() {
return this.firstName.toUpperCase()
}
}

Resources