亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

控制internal成員訪問

標簽:
C#

在上一篇文章中,为了解决成员访问级别的问题,我采用了一个object adapter,使得客户程序无法轻易地修改对象的属性。网友评论说,我的这种做法就是绕了一圈,的确,这种方法没办法阻止客户程序刻意地去修改对象的属性,但在一定程度上起到了保护作用:至少降低了误操作的可能性。

今天发现其实可以用System.Runtime.CompilerServices.InternalsVisibleToAttribute这个特性达到同样的效果。以下是操作步骤。

  1. 假设ExposedSetter.Library这个class library中包含了一个具有internal setter属性的SourcedAggregationRoot类。首先,对ExposedSetter.Library作数字签名。在ExposedSetter.Library项目上点右键选择“Properties”。在“Signing”页下选择“Sign the assembly”选项,然后指定一个强名称密钥文件。SourcedAggregationRoot的代码以及ExposedSetter.Library的签名设置如下

  2. 隐藏行号 复制代码
  3. 代码

    1. public class SourcedAggregationRoot : IVersionControllable
    2. {
    3.     private long version;
    4.     private long branch;

    5.     #region IVersionControllable Members

    6.     public long Version
    7.     {
    8.         get { return this.version; }
    9.         internal set { this.version = value; }
    10.     }

    11.     public long Branch
    12.     {
    13.         get { return this.branch; }
    14.         internal set { this.branch = value; }
    15.     }

    16.     #endregion

    17.     public override string ToString()
    18.     {
    19.         return string.Format("Version = {0}, Branch = {1}",
    20.             version, branch);
    21.     }
    22. }

     image

  4. 新建一个class library,以调用ExposedSetter.Library中SourcedAggregationRoot的internal setter属性。为方便描述,我们将这个class library命名为ExposedSetter.Library2。在这个class library上添加对ExposedSetter.Library的引用,同时随便写一个测试的类,在类里直接调用SourcedAggregationRoot的internal setter属性来设置属性值。

  5. 隐藏行号 复制代码
  6. 代码

    1. public class Class1
    2. {
    3.     public SourcedAggregationRoot Test()
    4.     {
    5.         SourcedAggregationRoot sar = new SourcedAggregationRoot();
    6.         sar.Branch = 125;
    7.         return sar;
    8.     }
    9. }

    同样,为ExposedSetter.Library2做数字签名(这一点很重要!)

  7. 启动Visual Studio的Command Line,使用sn.exe获得ExposedSetter.Library2的公共密钥(public key),注意:是public key,而不是public key token
    image

  8. 打开ExposedSetter.Library的AssemblyInfo.cs文件,向其添加InternalsVisibleToAttribute:

  9. 隐藏行号 复制代码
  10. 代码

    1. [assembly: InternalsVisibleTo("ExposedSetter.Library2, PublicKey=0024000004800000940000000602000000240" +
    2.     "000525341310004000001000100bbccb249a2e7a1" +
    3. "7cbddf86e24532777568cb13c2ea7643b61cf60367068f2b9ca785dca303c49f015823e4eaa17b" +
    4. "50ed60ac47563dc8d8771358f10c3dc41f288530cfa350e6a2a24781dedeb8ec4138f93e76c537" +
    5. "bce6c5aa7b25858fa90d6ef5c6ea613b1b49e6e287f9ebb7f990cfa0ce17fbfe1c338e95e88c14" +
    6. "81f9598f")]

    注意,InternalsVisibleToAttribute的参数指定了允许访问其internal成员的assembly名称和公共密钥数据。在此不能设置assembly的版本等信息,否则编译都过不去。

  11. 编译解决方案

这种方式有点像C++的友元。与我上文提到的引入object adapter的解决方案相比,这种做法更加professional一些,毕竟可以通过.NET Framework直接支持,而且也更加安全一些,它能够明确指定哪些assembly可以访问,其余的则不能访问。但这种做法也有弊端:假设我今后又有一个assembly希望使用ExposedSetter.Library中的internal成员,我需要去修改ExposedSetter.Library中的代码,以添加一个InteralsVisibleToAttribute特性。


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消