Skip to content

Instantly share code, notes, and snippets.

@cjrpriest
Created April 20, 2018 08:22
Show Gist options
  • Save cjrpriest/f53aed66bf9b9171c9413e5af760fb66 to your computer and use it in GitHub Desktop.
Save cjrpriest/f53aed66bf9b9171c9413e5af760fb66 to your computer and use it in GitHub Desktop.
a demonstration that by making a class sealed, it's possible for it to take a generic parameter of an internal type, and still have that class referenced by other assemblies
using NSubstitute;
namespace ConsoleApp
{
public class SealedInternal
{
public void Run()
{
// this executes fine
Substitute.For<IDoSomething>()
.DoSomethingSealed<Thing>()
.Returns(new SealedThingResultWrapper<Thing>());
// this blows up with exception Castle.DynamicProxy.Generators.GeneratorException: Can not create proxy for type ConsoleApp.ThingResultWrapper`1[[ConsoleApp.Thing, ConsoleApp7, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because type ConsoleApp.Thing is not accessible. Make it public, or internal and mark your assembly with [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] attribute, because assembly ConsoleApp7 is not strong-named.
Substitute.For<IDoSomething>()
.DoSomething<Thing>()
.Returns(new ThingResultWrapper<Thing>());
}
}
internal class Thing{}
public interface IDoSomething
{
SealedThingResultWrapper<TResult> DoSomethingSealed<TResult>();
ThingResultWrapper<TResult> DoSomething<TResult>();
}
public sealed class SealedThingResultWrapper<TResult> {}
public class ThingResultWrapper<TResult> {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment