How to use CallerMemberName in a CLS compliant assembly - c#-6.0

I have used the CallerMemberName attribute in a class's implementation of INotifyPropertyChanged as described on MSDN as follows:
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
However, using default parameters is not CLS compliant. But CallerMemberName can only be used with parameters that have default values... Is there a commonly used way to solve this inconsistency without having to call the notify method with a hard-coded string argument?

I have simply removed the CallerMemberName attribute and the default parameter value, meaning the parameter is no longer optional, so the method signature becomes:
private void NotifyPropertyChanged(String propertyName)
Then it is a small (enough) change to call it with the nameof operator providing the string argument:
NotifyPropertyChanged(nameof(FooProperty));
This seems to work quite well.
I will leave the question open for a little while however as others may have better ways, or suggest problems with this solution.

Related

Overriding standard ID scalar

I want to use UUID as an identifier but standard scalar ID is coerced as string.
So have to parse uuid from string everywhere I use ID type.
I wonder is it possible to override ID type with my own implementation?
This scalar type has some special meaning or I can just use my own scalar called UUID as identifier?
We can not override the available scalers, please refer this link for discussion.
You can define a UUIDScalar in your code, for the same you will have to override the following methods
#Override
public Object serialize(Object dataFetcherResult) {
//
}
#Override
public Object parseValue(Object input) {
//
}
#Override
public Object parseLiteral(Object input) {
//
}
Reference: Making custom scalars in graphql java
Luckily the code for making custom scalar for UUID is available online, you can use this PR

How can I use a local variable in the annotation #Preauthorize?

i need to do something like this
String myVar = "myString";
...
#Preauthorize("customMethod(myVar)")
public void myMethod() {
...
}
but I'm failing at it. How can I do that? It says it cannot be resolved
EDIT:I'm decoupling few rest services and sometimes I have to share infos between them
#Value("${my-properties}")
String urlIWantToShare;
...
#PreAuthorize("isValid(#myValue,urlIWantToShare)")
#RequestMapping(value = "**/letsCheckSecurityConfig", method = RequestMethod.GET)
public boolean letsCheckSecurityConfig(#RequestHeader(name = "MY-VALUE") String myValue)) {
return true;
}
this "isValid" custom security method will call an external service, that doesn't know anything about the caller and his infos. I need to transmit few infos and I need to take them from different kind of sources
One of the sources is my application.properties
EDIT2: I managed to do this
#PreAuthorize("isValid(#myValue, #myProperty)")
#RequestMapping(value = "**/letsCheckSecurityConfig", method = RequestMethod.GET)
public boolean letsCheckSecurityConfig(#RequestHeader(name = "MY-VALUE") String myValue,
#Value("${my-property-from-app-properties}") String myProperty))
..but I want to use not only actual static properties but runtime one. Any help?
You can create a wrapper method without parameters which will call the desired method with parameters. In the annotation you can use the method without parameters
Apologies if I have misunderstood what you are trying to do, but from my understanding you're trying to set an annotation at runtime based on a variable / app.properties, so that you can then read this variable and then execute your class?
If this is the case, You cannot do this from an annotation alone as annotations cannot read local variables and cannot be set at runtime.
However, one option for you is to have an object which contains the 'values' of interest for you and then read the values from the object.
Something like the below:
PoJo
public class testObject{
#test
private String myVar;
private String myValue;
//Getters and Setters
}
Get Object values
public void getFields (Object obj){
Field fields = obj.getClass().getDeclaredFields();
for (Field f : fields){
test fieldAnnotation = f.getAnnotation(test.Class);
if (fieldAnnotation != null){
f.get(obj);
// Do checks based on this
}
}
}
Main Class
public static void main(String[] args){
//Create object
testObject test = new testObject();
test.setOne("testOne");
test.setTwo("testTwo");
getFields(test);
}
I've pulled this code based on what I had to do to get the fields - but in my case, I did not know the object types I was going to be passed. You are simply using the annotation to 'mark' the fields you want to retrieve and then reading the value from the object.
If you're in a similar situation, then you can see my answer here: initial answer
Let me know if i've misunderstood this and I can try and further clarify my answer.

Spring model attribute declaration

What is the difference between declaring #ModelAttribute as a method parameter and using model.asMap()?
Example:
public void method1(#ModelAttribute("attr") MyObject myObj) {
...
}
public void method2(Model model) {
MyObject myObj = (MyObject) model.asMap().get("attr");
}
These are not the same if that's what your thinking. I tried to get an attribute from the model doing it the first way but didn't work so ended up doing it the second way.
Thanks
EDIT: What I mean by "it didn't work" is that when I used #ModelAttribute, it was confusing the values of the variables in that object to another object of a different type which had the same variable names.
EDIT #2: No it is not a duplicate because he does not address the model.asMap() method. As per the other post, I tried using #ModelAttribute on a #SessionAttributes variable but ran into problems so had to use model.asMap()

Static classes and "this" keyword

I have a static class with a custom event in it, as below:
//The delegate
public static delegate void eventDoneDelegate(object sender, WebLoaderEventArgs e);
//The event that uses the delegate
public static event eventDoneDelegate PageRequestDone;
//Calls the event
private static void onPageRequestDoneChanged(WebLoaderEventArgs e)
{
if (PageRequestDone != null)
PageRequestDone(this, e);
}
I know "this" can't be used because it references the current instance, but how can I pass the currect class as a parameter?
Or maybe my logic is wrong, please aware me as I am new to this.
Thanks.
The semantic meaning of the sender argument value depends on a vague agreement between the event publisher and the event subscribers; there is no universal standard. In your example, I can't see any need for a sender value at all, you might as well pass null.

Order of function modifiers in C#

I would like to know if there is a standard to set the order of function modifiers in C#. i.e.
public static void Method()
{}
static public void Method()
{}
this both work well, BUT
when I code:
public void static Method()
{}
I receive the following error:
Member modifier 'static' must precede
the member type and name
and
Method must have a return type
Method declarations must always follow this pattern:
[modifiers] returnType methodName([parameters])
There is no rule regarding the order of modifiers, but they must always precede the return type.
I don't think there is any standard order, people just do as they please... Personally I prefer to put the access modifier (public, private, etc) first, then the static modifier (if any), then the virtual, abstract or override modifier (if applicable).
See the C# spec for details (ยง10.6)
The problem is that void isn't a modifier - it's the return type. All the modifiers have to come before the return type.
I'm pretty sure there is a convention for the ordering of genuine modifiers, but I don't know where it's documented.
I would always write the accessibility (public etc) first.
There is no specific order for method modifiers.
Following is the formal grammar from the C# Standard specification ...
Methods are declared using method-declarations:
method-declaration:
method-header method-body
method-header:
attributesopt method-modifiersopt partialopt return-type member-name type-parameter-listopt
( formal-parameter-listopt ) type-parameter-constraints-clausesopt
****method-modifiers:****
new
public
protected
internal
private
static
virtual
sealed
override
abstract
extern
return-type:
type
void
member-name:
identifier
interface-type . identifier

Resources