Replies: 11 comments
-
How would that even work? If you have a method like Do you expect the runtime to detect that the proxy exists for this class and make every call to instance methods of this type be indirect in some way? What happens if an assembly containing the proxy is loaded only after the machine code is already generated? To me, this looks like a very complicated and problematic feature. And the only reason is so that you don't have to write wrapper classes for badly designed third party code? I think a feature like this would need a much better justification. |
Beta Was this translation helpful? Give feedback.
-
I'm not sure I follow the logic of this request. By marking a class as If a class is marked EDIT: a point made by @joe4evr on gitter has made me realise the above is a bit simplistic. There are occasions when a non-determinist class needs to be marked as |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I personally was tasked to "fix" a bug in Team Explorer for Visual Studio 2015 which was officially refused to be fixed by Microsoft with "won't fix" tag on official bug tracker. Microsoft indeed admitted that there is bug here in the .NET TFS API client, but refused to fix it and officially recommended to use Team Foundation Server web access instead. My mangement wasn't satisfied with such Microsoft answer and required me to "do something" myself to fix that bug. What I have done? I have decompiled TFS API Client code with ReSharper dotPeek .NET decompiler, studied its internals and then have used quite dangerous and obviously type-safety breaking practices to patch failed code at runtime, effectively replacing failed class instance with wrapper around it which fix failed behavior on one particular method and simply pass through other methods and properties invokes. So, some people at our enterprise management was happy to see that bug was "fixed" and their particularly unusual use case scenario with VS2015 and TFS 2017 stopped to crash Visual Studio. It's funny how sometimes you forced to do unusual and "practically awful" things when 3-rd party officially refuse to support their own software and dismiss you with your petty bug reports and your local management refuse to take 3-rd party rejection to fix the problem as acceptable answer even if you provide them full evidence of 3-rd party behavior. |
Beta Was this translation helpful? Give feedback.
-
That sounds like a particularly awful reason to hack this into the language. Language features should simplify common tasks that represent good practices. While I get that it was particularly difficult to work around your problem you did manage to do it and it sounds like the amount of effort required is about correct for both the nature of the task and the frequency in which it is likely to occur. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour transparent proxies have its uses cases beyond that kind of problems I described. Full .NET framework have built-in support for transparent proxies as well. Even Entity Framework 6 do use transparent proxies to intercept calls to entity classes when such classses are defined as POCO by developer. Anyone can see it in debugger. EF6 do materialize entity class instance as transparent proxy instead of original class instance and it's clearly seen in debugger as your POCO is displayed as instance with weird type name having unique id suffix instead of original type name. It's transparently used instead of original class instance in place. So it's why EF6 would never be ported to .NET Core as .NET Core haven't transparent proxy support. Another particular case for transparent proxies is all sorts of network remoting frameworks and transparent marshalling of classes by reference across process and application domain boundary, including Microsoft built-in implementations to do it. As you can see such transparent proxy functionality is widely used by Microsoft itself on the full .NET framework. So it have much "not awful" use cases. |
Beta Was this translation helpful? Give feedback.
-
@svick transparent proxies are already here at full .NET runtime. It works exactly as a form of limited violation of type-safety, as a supported by runtime apparent "hole" in type safety which allow to transparently substitute original class implementation with fake implementation and invoking code would never know that it invoke completely different type. http://blog.steveniemitz.com/fun-with-net-remoting-building-a-realproxy-implementation/
|
Beta Was this translation helpful? Give feedback.
-
Which, if anything, further demonstrates why it should not be a language feature. It's rarely used directly (rather behind an API layer) and depends on very specific features of the underlying CLR which cannot be expected to be there. The functionality that is there in the full framework has been there since 1.0 and clearly both the BCL and external projects have made successful use of it without the need for special language syntax or semantics. |
Beta Was this translation helpful? Give feedback.
-
@Opiumtm I'm with you on the hackability. I have used and would use such hacks again were I given the opportunity. However, I have to agree that that does not make it a good reason to add it to the language. It's not a design goal of the language to expose arbitrary hooks at every potentially useful point for every potential purpose. Part of creating a good architecture is exposing the right hooks; if everything is a hook, you can't encapsulate. I'd rather see IL patching hooks exposed at the CLR level and accessible through internal calls. (It might even be possible with CoreCLR today if you aren't afraid to write unmanaged code.) I think putting an API for it even in the BCL is a bad idea. |
Beta Was this translation helpful? Give feedback.
-
As far as I know, the .Net Framework transparent proxies only work for types that inherit from
How could that work? Like I said, AFAIK, you can't create transparent proxies of POCOs. And looking at EF6 source, I see some code that uses remoting, but that doesn't look like it's creating POCO proxies. On the other hand, I see code that creates "proxies" using Reflection.Emit. But those aren't transparent proxies, AFAICT, those are just types that inherit from the POCO types, so standard .Net inheritance rules are why they can be treated as instances of the POCO types. And those proxies indeed have names with unique suffixes (which is a SHA256 hash of the POCO type description).
Yes, transparent proxies are part of the built-in remoting infrastructure, which is almost never used anymore and which Microsoft considers to be "legacy technology that is retained for backward compatibility". But I have never heard of other remoting frameworks that would use the built-in transparent proxies. Care to share some names?
I don't see any evidence of that. It's used by one legacy technology and that's pretty much it. |
Beta Was this translation helpful? Give feedback.
-
This seems like more of a runtime feature, whether it's built-in directly or simply exists as some specific integration using the Profiling APIs. I'm not sure how changing the language would benefit the scenario. |
Beta Was this translation helpful? Give feedback.
-
@sharwell Single language change is simply to disable type checks on compilation for known and backed by CLR cases of "type substitutions". Transparent proxy idea is good on its own as it provides foundation for AOP. It isn't implemented properly and on all versions of CLR although. I agree, interfaces are much better solution for it, but there are cases when you should implement custom wrapper over already existing class and you can't create child class. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
It would require CLR change as well.
AFAIK full .NET already have built-in transparent proxy support, but it's somewhat "internal" feature and I'm not sure if .NET Core supports transparent proxies (looks like it don't supported).
Simple transparent proxies support would be very useful for unit testing too. It would be easy to fake any already existing (even 3-rd party and don't designed to be unit testable) class with transparent proxy.
This feature would compromise type safety to some degree. But sometimes it's needed to compromise type safety if you exactly know what are you doing. Common reason to compromise type safety is 3rd-party code which should be extended, but developers don't provided required extensibility points and you have no control over 3rd-party lib source code.
Beta Was this translation helpful? Give feedback.
All reactions