首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >替代InternalsVisibleTo

替代InternalsVisibleTo
EN

Stack Overflow用户
提问于 2021-02-02 09:40:52
回答 1查看 228关注 0票数 1

我目前正在尝试在我的解决方案中编写单元测试,但我想将我的单元测试放在另一个单独的项目中。问题是,当我生成一些假的测试数据时,我需要设置类的属性,但这是不可能的,因为属性具有私有/内部集。我找到了一种使用属性InternalsVisibleTo只向某些项目公开内部属性的方法,这很好,但它看起来有点凌乱和不干净。我正在寻找更分散的方式,以暴露我的私人财产给其他项目。例如,也许有一种方法可以公开我的属性,而无需在域类中显式添加属性?知道我该怎么做吗?

编辑:我找到了这篇关于在csproj文件中设置InternalsVisibleTo的文章。有人用过这个吗?https://bartwullems.blogspot.com/2020/06/internalsvisibleto-in-your-csproj-file.html

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-17 00:58:33

这篇博客文章中有一个在GitHub上使用示例代码描述的替代方法,它使用一个未记录的属性,用于访问私有/内部成员的程序集中。

然而,请注意以下事项:

  • 这是没有记录的,也不推荐。
  • 您不能直接编译它,而是需要使用Roslyn
  • 它似乎也忽略了对私有成员的访问,这肯定是需要非常小心的。

但是,它可能是有用的,例如,在处理动态程序集等时,请参见下面的示例。

代码

下面是需要完成的工作,在代码中添加IgnoresAccessChecksToAttribute,如下代码所示(确保它不在任何其他名称空间下,否则就无法工作):

代码语言:javascript
复制
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    public class IgnoresAccessChecksToAttribute : Attribute
    {
        public IgnoresAccessChecksToAttribute(string assemblyName)
        {
            AssemblyName = assemblyName;
        }

        public string AssemblyName { get; }
    }
}

然后在代码中的任何地方添加属性,如下所示:

代码语言:javascript
复制
[assembly: IgnoresAccessChecksTo("AssemblyToAccess")]

或者在csproj文件中:

代码语言:javascript
复制
<ItemGroup>
  <AssemblyAttribute Include="System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute">
     <_Parameter1>AssemblyToAccess</_Parameter1>
   </AssemblyAttribute>
</ItemGroup>

编译

编译是很棘手的,因为它不能用标准的方法编译,相反,必须通过Roslyn调用它,应该有许多关于如何使用Roslyn动态编译的可用资源,但是下面是这个编译工作所需的具体细节:

代码语言:javascript
复制
var compilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication).
            WithMetadataImportOptions(MetadataImportOptions.All);

var topLevelBinderFlagsProperty = typeof(CSharpCompilationOptions)
        .GetProperty("TopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);

// 22 is the value of the undocumented member BinderFlags.IgnoreAccessibility
topLevelBinderFlagsProperty.SetValue(compilationOptions, (uint)1 << 22);

在程序集生成器中的使用

一个合法的使用是在编译需要访问内部类的动态程序集时,有关示例代码,请参阅我在那的回答

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66007077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档