Replies: 27 comments
-
You can write an analyzer which enforces this behavior in your projects today. |
Beta Was this translation helpful? Give feedback.
-
This reminds me of the visibility proposal. Analyzers are okay I guess but I still wish there was some kind of idiomatic language support for things like this. |
Beta Was this translation helpful? Give feedback.
-
There are at least three solutions to this, using existing technologies:
Do we really need a fourth solution that requires a language change? |
Beta Was this translation helpful? Give feedback.
-
Nobody is claiming that there are no solutions to this, but none of them is actually clean, and you are forced to bend your code around something that could be a part of the compilation process, and solutions actually break down really quickly. It is not even a language change, there is no new keyword, just a new attribute that compiler can look at and give a proper error. I am sure that for friend assembly there was a work around, make tests internal to your assembly, and then change compilation process to exclude does files from assembly. But for some reason compiler gives you an option to mark assembly as friend.
|
Beta Was this translation helpful? Give feedback.
-
Partials. #711 would help with this as well.
Analyzers are designed specifically to solve such domain-specific problems, so they are tools you should learn. |
Beta Was this translation helpful? Give feedback.
-
I wanted to say "file-per-entity". I understand that analyzers would help, and certainly is a good skill to have, but seriously, percent wise, how many devs. out there even know about them? |
Beta Was this translation helpful? Give feedback.
-
#225 addresses the same concerns, using a different approach. |
Beta Was this translation helpful? Give feedback.
-
@epitka as @DavidArno said, you already have 3 possibilities to achieve it now.
So you never ever write helepr methods using reflection? Because it's practically the same? I'd like to downvote it twice if I could because this proposal just says
Virtually all developers I know are aware of analyzers. Yes, they don't use them but not because they can't. Analyzers just have very narrow use area and their tasks don't require it. |
Beta Was this translation helpful? Give feedback.
-
@Pzixel 1."this feature gives no expressiveness but only encourage bad code design. When you want this code to be called by only several allowed types then it's just a code smell." |
Beta Was this translation helpful? Give feedback.
-
Thus, you can spend 2-3 hours implementing this feature for you yourself OR you can spend several months arguing that we have to add it into the language and go to alternative v.1 if it won't be implemented. |
Beta Was this translation helpful? Give feedback.
-
@Pzixel |
Beta Was this translation helpful? Give feedback.
-
@epitka it's exactly the reason why Roslyn Analyzers were created. Why not use it? Everybody can add theirs own checks - if type is referenced within same assembly, everywhere but not in this assembly, that calling type must starts with |
Beta Was this translation helpful? Give feedback.
-
Is Analyzers really an option here? I mean it comes with quirks of its own, members would still show in the intellisense when it isn't appropriate, you can turn Analyzers off so it wouldn't be safe to use these members unless you have the Analyzer turned on which tells you when is the right context to use it etc... To an extreme what you guys are saying is let's have everything public and use Analyzers to determine accessibility. It seems like there's a weird tendency in the community where some people would propose something and then there's this other group that would suggest to replace it with extension method or an analyzer as if these tools are the silver bullet for any feature. Anyhow, I agree with @DavidArno, option 2 is in my opinion the way to go here, sometimes you would find yourself needing a language feature because you shot yourself in the foot to being with, this isn't to say that there might be a useful examples and valid use-cases to this feature but I didn't really face one, well, maybe I had one with the provider pattern but this was long time ago. 😄 |
Beta Was this translation helpful? Give feedback.
-
I dunno. This proposal doesn't actually change the language, it's just asking for the compiler to throw additional errors when you contravene the rules of an attribute, which is exactly where Analyzers shine. Perhaps if there's enough demand for such an analyser, then the LDM could consider integrating that into the language itself. However, I think it's a bit foolish to jump in cold when an analyser would solve the issue today and there's little demand (so far) for this as a language feature. If this was actually requesting new syntax such as |
Beta Was this translation helpful? Give feedback.
-
I have to agree with @eyalsk. It hurts to have to expose some internal stuff to IntelliSense. |
Beta Was this translation helpful? Give feedback.
-
I assume |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h Precisely. Also, |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h Even if it works, you're going from seeing everything to see nothing in the intellisense because there's no notion of context, also, I'm not sure whether it would work for other editors but Visual Studio. If I have a member that only a specific a set of classes should see I want the language to help me with it, I want it to be safe*, I want the IDE experience to feel as great as any other accessibility modifier we use today. * The issue with safety is how much safe, I don't know whether CLR support can be added for it which might end up being a synthetic feature or work on top of the current accessibility modifiers that we have today but that might be good enough, dunno. Edit: Rephrased. |
Beta Was this translation helpful? Give feedback.
-
So, I tried to implement this analyzer, but quickly run into problems, probably because I don't know enough about Roslyn. This analyzer would have to perform solution wide analysis and I am not sure how to get symbols for all classes that have this attribute on the constructor. I wanted to perform analysis at SyntaxNodeAction for ObjectCreationExpression is enountered. Basically, I need to check if class being newed up is annotated with this attribute, and if it is, then check if type is newed up within a class that is defined on the attribute as the one that can invoke constructor. Initial research indicates that solution wide analysis is not something that Roslyn is good for, at least not from within analyzer. Any pointers? |
Beta Was this translation helpful? Give feedback.
-
@epitka I'm affraid that analyzers cannot work on solution-wide level, because they are project entities. But you probably don't need it Here is at least one way which is pretty straightforward: you just have to create a new workspace and analyze the whole solution that all types that are referencing your class are of type declared in attribute:
If you put it in Another option is going backward: you can write an analyzer that checks that THIS class doesn't reference any class with |
Beta Was this translation helpful? Give feedback.
-
What I would like to do is
If I could build a metadata at the start of the solution editing, or if any type is annotated with InvocableBy attribute and store that in some structure than I guess I could give real-time information about proper usage. Is there an event, or process to which I can subscribe to collect initially needed info? |
Beta Was this translation helpful? Give feedback.
-
It's all on VS itself, analyzer don't have to control when user is typing or something. My expirience says that it always build up-to-date information because it's how Intellisence works. I'l try to create a sample project. |
Beta Was this translation helpful? Give feedback.
-
Here it is: https://github.com/Pzixel/InvocableByAnalyzer |
Beta Was this translation helpful? Give feedback.
-
I like |
Beta Was this translation helpful? Give feedback.
-
@jnm2 we need analyzer to work with intellisense then. I'm not sure that we currently have API for this. |
Beta Was this translation helpful? Give feedback.
-
@Pzixel No, it would be nice but we don't need IntelliSense to be intelligent about it. We just need an error squiggly to fail the build if you reference a field or nested type or use |
Beta Was this translation helpful? Give feedback.
-
@Pzixel: Thanks for the effort to put this analyzer together, great job. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Over the years using DDD coding style, I wished many times there was a way to define a “Friend” class on the member of the class. This would make a member visible only to the class defined as a friend, similar to what we have when defining a friend assembly. There are several use cases for this, such as bi-directional relationship synchronization and/or construction of the class. Goal of this is to lock the code down and prevent logical errors especially for developers using DDD style and/or using ORMs such as EF or NHibernate.
Let take example of two classes, Order and OrderDetail. If I approach this in DDD fashion, Order is the one that should create OrderDetail, always. But in order for Order to create OrderDetail, OrderDetail must have constructor. Even if we mark constructor “internal”, it is not obvious just by looking at the code whether constructor can be invoked directly or if there is some factory, service, entity that should invoke it. So we resort to comments such as
//do not invoke directly, go through …
It would be much simpler and safer, and intent revealing, if one could write code like this (pay attention to InvocableBy attribute). Code is oversimplified just to show the concept.
Members should either be removed from IntelliSense, or warning should be shown and it should fail at compile time if member is invoked by a class that is not listed in InvocableBy. Not sure if Attribute or some other mechanism should be used.
Beta Was this translation helpful? Give feedback.
All reactions