-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should DynamicProxy emit IgnoresAccessChecksToAttribute? #402
Comments
Interesting, thanks @stakx for mentioning this.
I foresee a problem with this. DynamicProxy doesn't know in advance for which types a proxy will be requested. But assembly level attributes have to be defined at assembly creation, right? I assume it's not possible to add attributes after the assembly has been created? |
I think that's not a problem. I've quickly tried this in my Gist (link above) by moving the assembly-level attribute application towards the end of the Gist, after all other types have been baked. That worked just fine. I believe it is only the C# language that requires |
There is indeed a requirement. Once the CLR has loaded any type from the assembly, the magic attribute can't be added later or it will have no effect. So all the attributes have to be added at once up front or else you have to create a new dynamic assembly. |
See microsoft/vs-mef#93 for a relevent bug fix regarding when the magic attributes are applied. |
@AArnott: Thanks for that bit of information. Small follow-up question: That PR you've linked to takes care not to generate more dynamic assemblies than necessary. Do you know how problematic / inefficient it would be for the runtime (both CLR, and CoreCLR) if one generated a new dynamic assembly for each proxy type? That is, if the runtime had to deal with potentially hundreds of small dynamic modules in memory? In either case, @thomaslevesque is probably right and we cannot use this attribute for DynamicProxy as long as we share one dynamic assembly for many proxy types (as opposed to one dynamic assembly per proxy type). Which is how things are probably going to stay for the foreseeable future. I guess we can close this then. |
I don't know the exact cost. But there is a perfect and memory cost for each assembly that the CLR loads. Which is why we tried to avoid it. |
@AArnott - I might run a few benchmarks to learn more about the exact cost someday, but for now my curiosity is satisfied. Makes sense to keep the number of loaded assemblies low. Thanks! |
Yesterday, I was made aware of the small wonder that is
[assembly: IgnoresAccessChecksTo("AssemblyName")]
. This attribute might be useful for DynamicProxy.What is it?
Put simply, this attribute type is the reverse of
InternalsVisibleToAttribute
. It can be applied in a dynamic assembly to get access to theinternal
members of another assembly. It is supported by the .NET Core 1.0+ and the .NET Framework 4.6+ runtimes. The BCL does not pre-define that attribute type, one has to define it e.g. inside the dynamic assembly as follows:There isn't a lot of information about this attribute (it appears to be undocumented, unfortunately but perhaps for understandable reasons), here's a few links if you want to learn more:
Description of that attribute type in aelij/IgnoresAccessChecksToGenerator's README
@AArnott posted information about which runtimes support the attribute in Add support for internal metadata view interfaces microsoft/vs-mef#10 (comment).
.NET Core's
DispatchProxyGenerator
already uses it, see e.g. itsEnsureTypeIsVisible
method. (DynamicProxy could do something similar.)A small demo program (Gist) by yours truly.
What would this be good for?
If DynamicProxy automatically emitted that attribute type definition in its dynamic modules, and (recursively) applied it for the assemblies containing proxied types, downstream users running on recent framework versions would no longer need the
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
bit.For people running on an older platform (.NET Framework <4.6), there would be no change from DynamicProxy's current behavior.
Is it a good idea to always have access to
internal
members?That's the one thing I am not sure about. Are there cases where users do not want DynamicProxy to see / intercept / be able to proxy internal types or type members? Would there have to be some kind of configuration switch that allows people to opt in/out of DynamicProxy automatically emitting
[IgnoresAccessChecksTo]
?/cc @blairconrad, @dtchepak, @thomaslevesque, @zvirja
The text was updated successfully, but these errors were encountered: