I am new to F#. In C#, I have an interface defined as:
public interface IMenuEvents
{
event Action SaveEvent;
event EventHandler<ParagraphReadyEventArgs> ParagraphReadyEvent;
....
}
where
public class ParagraphReadyEventArgs : System.EventArgs
{
public ParagraphReadyEventArgs(string paragraph_title)
{
ParagraphTitle = paragraph_title;
}
public string ParagraphTitle { get; }
}
How is the interface IMenuEvents written in F# ?
Thank you for any help.
Given declaration translates to
open System
type ParagraphReadyEventArgs(paragraphTitle: string) =
inherit EventArgs()
member val ParagraphTitle = paragraphTitle
type IMenuEvents =
[<CLIEvent>]
abstract member SaveEvent : IDelegateEvent<EventHandler>
[<CLIEvent>]
abstract member ParagraphReadyEvent : IDelegateEvent<EventHandler<ParagraphReadyEventArgs>>
Key difference is that EventHandler wrapped inside IDelegateEvent<T>
Behind the scenes you get same interface that you could get with C#. Decompilation
I don't understand why F# chose to make things that complicated yet. Hope somebody have an answer for this question
Few words about original design: It's recommended for all events to have type EventHandler or EventHandler<TEventArgs>, don't use custom event types. If you concern about memory allocation from EventArgs, then use EventArgs.Empty instead of new EventArgs()
Related
I am attempting to provide a Dataview delegate overide to the UnionDeductions view in PRCalculationEngine.cs
I note that this View does NOT have a defined dataview delegate in the Base graph - and the declaration is a bit 'different' in that is uses a BQL Fluent class.
Is this even possible to introduce a data view delegate in an extension
If so, Is there a different way of declaring the delegate ?
The business case is that the client needs to modify the Amount of the union deduction based on certain Employee attributes (length of service etc) and needs to dynamically modify the amount.
Due to the private and protected access of the GetBenefits and CalculateRegularBenefitNominalAmount methods, the only way I see to do this is to over-ride the dataview delegate and alter the Deduction/Benefit amounts prior to the calculation of the Benefit/Deduction amount...
public partial class PRCalculationEngine : PXGraph
{.....
public UnionDeductionQuery UnionDeductions;
...}
When I attempt to define a dataview delegate for this view in an Extension - I cannot get the dataview delegate to 'fire'
ie The code always just runs the .Select on the Base view but does not execute the delegate.
This is the core of the extension code
public class PRCalculationEngine_Ext1ESP : PXGraphExtension
{
public static bool IsActive() { return PXAccess.FeatureInstalled<FeaturesSet.payrollModule>(); }
#region Select Overrides
public PRCE.UnionDeductionQuery UnionDeductions;
protected System.Collections.IEnumerable unionDeductions()
{
foreach (PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType> result in
UnionDeductions.Select())
{
// modify the package amount here...
yield return result;
}
}
#endregion
}
This is how the view is being called in the Base Graph
foreach (IGrouping<int?, PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType>> resultGroup in UnionDeductions.Select(deductionCode.CodeID)
.Select(x => (PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType>)x)
.GroupBy(x => ((PREarningDetail)x).RecordID))
{
Any advice or observations would be appreciated.
If the requirement is to overwrite the logic of the base dataview delegate which also references other protected methods, try if this helps:
First create an extension of the base class as follows with the PXProtectedAccess attribute and the methods that you want to override:
[PXProtectedAccess]
public abstract class PRCalculationEngine_FirstExt : PXGraphExtension<PRCalculationEngine>
{
[PXProtectedAccess]
public abstract DedBenAmount CalculateRegularBenefitNominalAmount(
PRDeductCode deductCode,
PREmployeeDeduct employeeDeduct,
PRPaymentDeduct paymentDeduct);
}
Then create a second extension (your actual graph extension) inheriting from both the base class and the first extension you created above.
public class PRCalculationEngine_Extension : PXGraphExtension<PRCalculationEngine_FirstExt, PRCalculationEngine>
{
// Here declare the view, write the PXOverride method, and access the protected methods of the base graph by referencing those as Base1.CalculateRegularBenefitNominalAmount()
}
Note that the above snippets are just to give an indication. I have not really worked on the PRCalculationEngine or tested that code but had done similar changes on a different graph to override the dataview delegate. Let me know if it helps. Thank you.
I got redirected from here: https://github.com/aspnet/AspNetCore/issues/11963
I'm in the process of converting a solution over from .Net 4.6 and i'm looking at metadata.
In the old solution I had a custom implementation of the data annotations metadata provider which I had extended like this ....
public class ApiMetadataProvider : DataAnnotationsModelMetadataProvider, IDisposable
{
public IResourceProvider ResourceProvider { get; }
public ICoreDataContext CoreDb { get; }
public ApiMetadataProvider(IResourceProvider resourceProvider, ICoreDataContext core)
{
ResourceProvider = resourceProvider;
CoreDb = core;
}
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
ModelMetadata modelMetadata = base.CreateMetadata(
attributes,
containerType,
modelAccessor,
modelType,
propertyName);
Type serverType = (modelType == typeof(string))
? typeof(string)
: modelType.ImplementsGenericInterface(typeof(IEnumerable<>)) ?? modelType;
if (serverType.IsGenericType && serverType.Name.StartsWith("Nullable") && typeof(Nullable<>).MakeGenericType(serverType.GenericTypeArguments) == serverType) { serverType = serverType.GenericTypeArguments[0]; }
modelMetadata.AdditionalValues.Add("ServerType", serverType.AssemblyQualifiedName);
SetTemplateHint(modelMetadata);
SetCustomAttributes(attributes, modelMetadata, modelType, propertyName);
SetResourceStrings(modelMetadata);
return modelMetadata;
}
....
}
... the key thing here is that I pull the base copy of the model meta for the given type and then manipulate it in my own custom ways (some of which is shown in the sample above).
I cut the rest out because there's quite a bit of it.
The net result is that from my own base generic controller I had an action that looked like this ...
protected MetadataContainer GetMetadataForType(Type type)
{
return new MetadataContainer(MetaProvider.GetMetadataForType(null, type));
}
Controllers would then often make decisions based on this.
I am looking to reproduce this behaviour, the key thing being the ability to get a customised version of the "final meta" from the stack (I gather from this: https://github.com/aspnet/Mvc/issues/2522 ... that meta is now a "chain of providers" in some fashion).
So I have a couple of questions ....
How can i add or remove / update custom "properties" / attributes in the meta information for a given type?
How can I get an instance of the meta that the stack sees as being the "final result" after all providers have been executed?
The existing solution often handed this meta information to client JS code to allow for "dynamic component construction" in the browser, is this a scenario that has any form of best practice that I can gather more advice from (perhaps you guys have a blog post or something to get me started)?
The answer was simple in the end ...
Don't bother doing any of this, build a cache of the reflection derived information and in the controller just serve it up.
This basically just means this is simple reflection code to extract the relevant type info wanted.
I use this code in my application and I find it very ugly.
Is there a smart way of doing this?
for (final ApplicationCategories applicationCategorie : applicationCategories) {
if (applicationCategorie == ApplicationCategories.PROJECTS) {
// invoke right method
} else if (applicationCategorie == ApplicationCategories.CALENDAR) {
// ...
} else if (applicationCategorie == ApplicationCategories.COMMUNICATION) {
} else if (applicationCategorie == ApplicationCategories.CONTACTS) {
} else if (applicationCategorie == ApplicationCategories.DOCUMENTS) {
} else if (applicationCategorie == ApplicationCategories.WORKINGBOOK) {
}
}
My aim is to handle all application categorie enums which contained into the enum list.
The least you can do is to declare the method that handles the behaviour dependent to the enum inside ApplicationCategories. In this way, if you will add a new value to the enum, you will only to change the code relative to enum.
In this way, your code adheres to the Open Closed Principle, and so it is easier to maintain.
enum ApplicationCategories {
PROJECTS,
CALENDAR,
// And so on...
WORKINGBOOK;
public static void handle(ApplicationCategories category) {
switch (category) {
case PROJECTS:
// Code to handle projects
break;
case CALENDAR:
// Code to handle calendar
break;
// And so on
}
}
}
This solution is only feasable if you do not need any external information to handle the enum value.
Remember you can also add fields to enum values.
EDIT
You can also implement a Strategy design pattern if you need. First of all, define a strategy interface and some concrete implementations.
interface CategoryStrategy {
void handle(/* Some useful input*/);
}
class ProjectStrategy implements Strategy {
public void handle(/* Some useful input*/) {
// Do something related to projects...
}
}
class CalendarStrategy implements Strategy {
public void handle(/* Some useful input*/) {
// Do something related to calendars...
}
}
//...
Then, you can modify your enum in order to use the above strategy.
enum ApplicationCategories {
PROJECTS(new ProjectStrategy()),
CALENDAR(new CalendarStrategy()),
// And so on...
WORKINGBOOK(new WorkingBookStrategy());
private CategoryStrategy strategy;
ApplicationCategories(CategoryStrategy strategy) {
this.strategy = strategy;
}
public static void handle(ApplicationCategories category) {
category.strategy.handle(/* Some inputs */);
}
}
Clearly, the above code is only a sketch.
The design pattern you need is the Strategy.
Enums and violation of the Open/Closed Principle
The use of enums when you have to perform a different action for each defined value is a bad practice. As the software evolves, it is likely that you have to spread the if chain around different places. If you add a new enum value, you'll have to add a new if for that value in all these places. Since you may not even be able to find all the places where you have to include the new if, that is a source for bugs.
Such approach also violates the Open/Closed Principle (OCP). Just creating a method to handle each enum value doesn't make your code conformant to OCP. It will make the code more organised but doesn't change anything about the "if" issue.
Java 7 solution with Strategy Pattern
Using Java 7 or prior, you can define a ApplicationCategory interface that all categories will implement. This interface will provide a common method that each category will implement to perform the required actions for that category:
public interface ApplicationCategory {
boolean handle();
}
Usually your method should return something. Since I don't know what is your exact goal, I'm making the method to return just a boolean. It would indicate if the category was handled or not, just as an example.
Then you have to define a class implementing such an interface for each category you have. For instance:
public class CalendarCategory implements ApplicationCategory {
boolean handle(){
//the code to handle the Calendar category
return true;
}
}
public class CommunicationCategory implements ApplicationCategory {
boolean handle(){
//the code to handle the Communication category
return true;
}
}
Now you don't need the enum class and the handle method that was inside it needs to be moved elsewhere, that completely depends on your project. That handle method will be changed to:
public static void handle(ApplicationCategory category) {
//Insert here any code that may be executed,
//regardless of what category it is.
category.handle();
}
You don't need an enum anymore because any variable declared as ApplicationCategory just accepts an object that implements such an interface. If you use the enum together with the Strategy implementation, it will be yet required to change the enum class any time you add a new ApplicationCategory implementation, violating the OCP again.
If you use the Strategy pattern, you don't even need the enum anymore in this case.
Java 8 solution with functional programming and Strategy Pattern
You can more easily implement the Strategy pattern using functional programming and lambda expressions, and avoid the proliferation of class just to provide different implementations of a single method (the handle method in this case).
Since the handle method is not receiving any parameter and is retuning something, this description conforms to the Supplier functional interface. An excellent way to identify what kind of functional interface a method you are defining conforms to, it is studying the java.util.function package.
Once the type of functional interface is identified, we can create just a ApplicationCategory class (that in the Java 7 example was an interface) in a functional way, defining the previous handle method as an attribute of the Supplier type. You must define a setter for this handle attribute to enable changing the handle implementation. Defining a method as an attribute, you are enabling such a method implementation to be changed in runtime, providing a different but far simpler, easier and more maintainable implementation of the Strategy pattern.
If you need to use the category name somewhere, for instance to display it in a user interface, you could define an enum inside the ApplicationCategory class. However, there is no direct relation between the enum value and the handle provided. The enum works just as a tag for the category. It is like a "name" attribute in a Person class, that we usually just use to "tag" and print a person.
public class ApplicationCategory {
//insert all categories here
enum Type {CALENDAR, COMMUNNICATION}
/**
* The Supplier object that will handle this category object.
* It will supply (return) a boolean to indicate if the category
* was processed or not.
*/
private Supplier<Boolean> handler;
private Type type;
/**
* A constructor that will receive a Supplier defining how to
* handle the category that is being created.
*/
public ApplicationCategory(Type type, Supplier<Boolean> handler){
Objects.requireNonNull(type);
this.handler = handler;
setType(type);
}
/**
* Handle the category by calling the {#link Supplier#get()} method,
* that in turn returns a boolean.
*/
public boolean handle(){
return supplier.get();
}
public Type getType(){ return type; }
public final void setHandler(Supplier<Boolean> handler){
Objects.requiredNonNull(handler);
this.handler = handler;
}
}
If you give the behaviour that will handle the enum value at the enum constructor call, as suggested by the other answer provided here, then you don't have how to change the behaviour in runtime and it in fact doesn't conform to the Strategy pattern. Unless you really don't need that, you might implement in that way, but remember it violates the OCP.
How to use the Java 8 functional ApplicationCategory class
To instantiate a ApplicationCategory you have to provide the Type (an enum value) and the handler (that is a Supplier and can be given as a lambda expression). See the example below:
import static ApplicationCategory.CALENDAR;
public class Test {
public static void main(String args[]){
new Test();
}
public Test(){
ApplicationCategory cat = new ApplicationCategory(CALENDAR, this::calendarHandler);
System.out.println("Was " + cat + " handled? " + cat.handle());
}
private boolean calendarHandler(){
//the code required to handle the CALENDAR goes here
return true;
}
}
The this::calendarHandler instruction is a method reference to pass a "pointer" to the calendarHandler method. It is not calling the method (you can see that due to the use of :: instead of . and the lack of parenthesis), it is just defining what method has to be in fact called when the handle() method is called, as can be seen in System.out.println("Was " + cat + " handled? " + cat.handle());
By using this approach, it is possible to define different handlers for different instances of the same category or to use the same handler for a subset of categories.
Unlike other languages, Java provides facilities that specifically allow this sort of thing to be done in a safe object-oriented way.
Declare an abstract method on the enum, and then specific implementations for each enum constant. The compiler will then ensure that every constant has an implementation and nobody has to worry about missing a case somewhere as new values are added:
enum ApplicationCategories {
PROJECTS {
void handle() {
...
}
},
...
public abstract void handle();
}
Then, instead of calling some static handle(category), you just call category.handle()
I'm trying to write a generic method parameter validation functionality that can be chained (fluent interface) to attach more and more validations/checks like:
public void SomeMethod(User user, string description)
{
ParameterHelper
.Create(() => user)
.RejectNull();
ParameterHelper
.Create(() => description)
.RejectNull()
.RejectEmptyString();
// now this would be luxurious
ParameterHelper
.Create(() => new { user = user, desc = description })
.RejectNull(o => o.user)
.RejectNull(o => o.desc)
.RejectEmptyString(o => o.desc);
}
I would like to use this helper class to test method parameters for certain values before using them (most of the time null will be tested).
Current state of affairs
I first started writing static helper class without the Create() method like:
public static class ParameterHelper
{
public static void RejectNull(Expression<Func<T>> expr)
{
if (expr.Compile()().Equals(default(T)))
{
MemberExpression param = (MemberExpression)expr.Body;
throw new ArgumentNullException(param.Member.Name);
}
}
}
But this doesn't allow chaining. That's why I created the Create() method that would return something that can be used by chained extension methods.
The problem
I would like to avoid multiple Compile() calls, so basically my Create() method should return Func<T> and reject methods should be extension methods of Func<T>.
If my Create() does return Func<T> I don't get the chance to read parameter names that should be supplied to various exceptions (using MemberExpression).
If I return Expression<Func<T>> instead I will have to call Compile() in each Reject extension method.
Questions
Is there a C# library that already does this kind of chaining?
If not, what do you suggest how this should be done? Any examples from the web would be warmly welcome.
Additional note
I should point out that complex/long validation invocation code is not an option here, because my current validation is done like:
if (user == null)
{
throw new ArgumentNullException("user");
}
or
if (string.IsNullOrEmpty(description))
{
throw new ArgumentNullException("description");
}
Which has two major drawbacks:
I repeat the same lines of code over and over
it uses magic strings
So validation should be done with a one liner per check as described above in the desired scenario.
There is a simple way to implement such a fluent interface. Your 'ParameterHelper.Create' method should return an instance of some class (this class is named Requirements below). This instance should hold the expression which was passed to Create. Also this class should have Require... instance methods which will validate expression and return this. Requirements class can be a private class inside ParameterHelper. I would also introduce an interface for this requirements chain (this interface is named IRequirements below. Sample:
public static class ParameterHelper
{
public static IRequirements Create<T>(Expression<Func<T>> expression)
{
return new Requirements{ Expression = expression };
}
private class Requirements<T> : IRequirements
{
public readonly Expression<Func<T>> Expression { get; set; }
public IRequirements RejectNull()
{
if (Expression .Compile()().Equals(default(T)))
{
MemberExpression param = (MemberExpression)Expression.Body;
throw new ArgumentNullException(param.Member.Name);
}
return this;
}
// other Require... methods implemented in the same way
}
}
public interface IRequirements
{
IRequirements RejectNull();
}
This approach will allow you implementing your luxurious solution - you just need to add a corresponding parameters to Reject... methods. Also you will probably need to make IRequirements interface generic.
Robert,
I have a library that solves this problem. It is called Bytes2you.Validation (Project). It is fast, extensible, intuitive and easy-to-use C# library providing fluent APIs for argument validation.
It focuses exactly on the problem that you want to solve, but does not use expressions. This is so, because they are a lot slower than just passing the argument name. For a library like that, that is designed to be used everywhere the performance is one of the most critical features.
For example:
Guard.WhenArgument(stringArgument,"stringArgument").IsNullOrEmpty().IsEqual("xxx").Throw();
// Which means - when stringArgument is null or empty OR is equal to "xxx" we will throw exception. If it is null, we will throw ArgumentNullException. If it is equal to "xxx", we will throw ArgumentException.
Hey there! I'm relatively new to both GWT and java programming (or OOP for that matter), so apologies for the beginner questions/mistakes in advance. I've been trying to create some kind of observer pattern, but the development mode console keeps dropping error messages and sadly, they're far from helpful.
So here's what I'm trying to achieve:
- I've got the model that consists of the class Country, and stores a value called Influence.
- The view is the class called CountryDisplay. It's a GWT widget that should always display the current influence of a given country.
public class Country {
private int influece;
private CountryDisplay display;
public Country() {
influence = 0;
}
public void setDisplay(CountryDisplay display) //...
public int getInfluence() //...
public void setInfluence(int value) {
influence = value;
display.update();
}
}
public class CountryDisplay {
private Country country;
public CountryDisplay (Country country) {
//GWT widget creating stuff
this.country = country;
}
public void update() {
//InfluenceCounter is a simple Label
InfluenceCounter.setText(Integer.toString(country.getInfluence()));
}
}
Then in the EntryPoint class I do something like this:
Country italy = new Country();
CountryDisplay italyDisplay = new CountryDisplay(italy);
italy.setDisplay(italyDisplay);
RootPanel.get("nameFieldContainer").add(italyDisplay);
italy.setInfluence(3);
The development console indicated that it had a problem with the line "display.update();" in class Country. My first guess was that the problem was that the display was not initiated, so I created an interface for it, and in the Country constructor I created an empty, new display, that would later be overwritten.
public Country() {
influence = 0;
display = new DisplayInterface() {
public void update() {}
}
}
But I had no luck this way either. I guess this kind of cross-referencing is not allowed? I mean that the view has the model as a variable and vice versa.
When calling a method on the view individually (like:
italy.setInfluence(3);
italyDisplay.displayTheCurrentValue();
) it works, so the problem is definitely in the observer logic.
If I understand correctly, your are trying to "bind" user interface elements (your view class CountryDisplay) to data (the model class Country). "Bind" in the sense that if you change the model data (for example, call italy.setInfluence(10)) then the view would automatically update itself to reflect the change. And if your view provided an editor, you want the "binding" also to work in the other direction.
There are several frameworks out there that achieve this, see for example the post Best data binding solution for GWT. I have used GWT Pectin and there is the GWT Editors framework (which I have not yet used myself as it is relatively new).
Looking at your code, I feel you might want to more clearly separate the model from the view: your model class (Country) should not know about the view class, that is, it should not store a reference to CountryDisplay.