Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which `[InternalsVisibleTo]` for .NET Framework and .NET Standard / Core framework assemblies?

I'm having an issue with cross-assembly / friend assembly type visibility.

I have the following program (which I sign / strong-name). It tells Castle DynamicProxy (I'm using version 4.2.1 of the Castle.Core NuGet package) to create a proxy for my interface IFoo. I'm also specifying that my internal class InterfaceProxyBase should be the base class for the proxy type.

DynamicProxy then uses System.Reflection.Emit to create the proxy type. But apparently, System.Reflection.Emit.TypeBuilder does not have access to InterfaceProxyBase.

// [assembly: InternalsVisibleTo("?")]
//                               ^^^
// What do I need here for my program to work both on the .NET Framework 4.5+
// and on .NET Core / .NET Standard 1.3+?

using Castle.DynamicProxy;

class Program
{
    static void Main()
    {
        var generator = new ProxyGenerator();

        var options = new ProxyGenerationOptions
            {
                BaseTypeForInterfaceProxy = typeof(InterfaceProxyBase)  // <--
            };

        var proxy = generator.CreateInterfaceProxyWithoutTarget(
                typeof(IFoo),
                options,
                new Interceptor());
    }
}

public interface IFoo { }

internal abstract class InterfaceProxyBase { }

internal sealed class Interceptor : IInterceptor
{
    public void Intercept(IInvocation invocation) { }
}

Unhandled Exception: System.TypeLoadException: Access is denied: 'InterfaceProxyBase'.
   at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
   ...
   at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
   at Program.Main() in Program.cs

So, apparently I need an [assembly: InternalsVisibleTo] attribute for the framework's own assembly / assemblies. My program (a class library, actually) targets both .NET 4.5 and .NET Standard 1.3.

Which [assembly: InternalsVisibleTo] attribute(s) do I need (including the precise public keys) to make my code work for the mentioned platforms / targets?


P.S.: I know that I can circumvent the problem by just making InterfaceProxyBase public and hiding it with [EditorBrowsable(Never)] for appearance's sake, but I really don't want to make this internal type public if I don't have to.

P.P.S.: If making internals public to framework assemblies is a really bad idea, security-wise, please let me know, then I'll happily reconsider my approach.

like image 883
stakx - no longer contributing Avatar asked Dec 11 '17 20:12

stakx - no longer contributing


People also ask

What is the difference between .NET Core and .NET Framework and .NET standard?

. Net Core does not support desktop application development and it rather focuses on the web, windows mobile, and windows store. . Net Framework is used for the development of both desktop and web applications as well as it supports windows forms and WPF applications.

Is .NET standard compatible with .NET Core?

. NET Core is an implementation of the . NET Standard that's optimized for building console applications, Web apps and cloud services using ASP.NET Core. Its SDK comes with a powerful tooling that in addition to Visual Studio development supports a full command line-based development workflow.

Should I use .NET standard or core?

A cross-platform and open-source framework, . NET Core is best when developing applications on any platform. . NET Core is used for cloud applications or refactoring large enterprise applications into microservices. You should use .


1 Answers

You should set InternalsVisibleTo for DynamicProxyGenAssembly2:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

DynamicProxyGenAssembly2 is a temporary assembly built by Castle.DynamicProxy. This assembly contains generated proxy type that inherits from your InterfaceProxyBase. That's why DynamicProxyGenAssembly2 should have an access to InterfaceProxyBase type. The possible options are either adding InternalsVisibleTo attribute or making InterfaceProxyBase public.

like image 160
CodeFuller Avatar answered Oct 13 '22 15:10

CodeFuller