Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “我怎样才能隐藏?”;“二传手”;除了一个组件之外,其他所有组件都有?_C#_.net_Assemblies_Access Modifiers_Getter Setter - Fatal编程技术网

C# “我怎样才能隐藏?”;“二传手”;除了一个组件之外,其他所有组件都有?

C# “我怎样才能隐藏?”;“二传手”;除了一个组件之外,其他所有组件都有?,c#,.net,assemblies,access-modifiers,getter-setter,C#,.net,Assemblies,Access Modifiers,Getter Setter,我在中提到了这个问题,但我认为值得将其分解为自己的问题,因为它并不真正依赖于我提到的其他场景 不管怎么说,关于Q,我不知道这是否可能。正在寻找解决方案/解决方法 我有一个类库,除了POCO之外什么都没有: MyCompany.MyProject.Domain.POCO 此部件的POCO如下所示: public class Post { public int PostId { get; set; } public int Name { get; set; } ... }

我在中提到了这个问题,但我认为值得将其分解为自己的问题,因为它并不真正依赖于我提到的其他场景

不管怎么说,关于Q,我不知道这是否可能。正在寻找解决方案/解决方法

我有一个类库,除了POCO之外什么都没有:

MyCompany.MyProject.Domain.POCO
此部件的POCO如下所示:

public class Post
{
   public int PostId { get; set; }
   public int Name { get; set; }
      ...
}
现在,我有了另一个类库,它是我的DAL/存储库,并使用Entity Framework 4.0进行持久化:

MyCompany.MyProject.Repositories
此程序集引用POCO项目,因为它需要在POCO上执行CRUD操作(抓取DB对象、投影到POCO、返回以及修改POCO)

现在,我还有一个Web应用程序,它同时引用了POCO和存储库程序集

如果我这样做:

somePOCO.PostId = 10;
我得到一个SQLException,因为PostId是数据库中的一个标识字段,因此不应显式设置

是否有一种方法可以隐藏这些特殊属性的setter,以便只有存储库可以访问setter


我想不出一种使用常规可访问性修饰符的方法(因为它们都不适合这种情况),你们能想出一个解决方法吗?

将所有的设置器标记为内部,然后将InternalsVisibleTo属性添加到POCOs程序集:

 [assembly: InternalsVisibleTo( "MyCompany.MyProject.Repositories" )]  

您可以将setter设置为内部,并使内部对存储库程序集可见

[assembly: InternalsVisibleTo("MyLibrary.Repositories")]
public class Post
{
   public int PostId { get; internal set; }
   public int Name { get; internal set; }
      ...
}
这意味着一切都可以“获取”这些属性,但只有此程序集和包含存储库的程序集可以“设置”

是一个好答案。它满足问题的技术要求。但我建议谨慎,因为这可能无法解决未来的问题


不要建议过度工程化,但您可能想进一步抽象出您对这些具有可设置ID属性的对象所做的工作。用这个属性装饰来创建这个“可见性”可能就足够了,但我认为这是解决这个问题的一种方法。用其他东西封装这些对象之间的交互可能会更干净,从而从使用代码中删除setter访问权限。

是否正在寻找
内部
修饰符?所以只有同一程序集中的类才能看到它们?@Justin'jngguy'Nelson-`没有。你读过这个问题吗?存储库需要获取/设置它们。我希望web能够“获取”某些属性,但不能设置。存储库位于不同的程序集中,需要能够设置。@RPM,我确实读过。这就是为什么我没有把它作为一个答案,因为我认为它是错误的。@RPM1984-我知道你可能不是有意的,但你对贾斯汀有点粗鲁。他只是问了一个澄清的问题,可能漏掉了一点。我们都是来帮忙的:)@Luke Shafer-我同意,贾斯汀道歉。只是有人已经发布了一个答案,上面写着“只需将其标记为内部”。我评论了他为什么不正确,然后他删除了他的答案(哈哈),然后贾斯汀做了同样的评论。但是,我再次道歉您的思路是正确的,但这不是说“所有内部”只对存储库可见吗?我只想限制所有属性的“setter”,而不是“get/set”。知道我的意思吗?我的错-你的正确(@Luke Schafer)的答案帮助了我。虽然我给了Luke答案,+1也是因为正确。是的,这就是我想要的@Nescio提到了这一点,但你在POCO的内部设置上说得更清楚了。谢谢。我同意这是一个
黑客行为
——但我想不出任何其他解决方案(不会影响我的架构)。可以吗?我不知道这在EF中是如何工作的,但我有一个非常类似的设置,但我使用L2S。我不担心
ID
属性被意外地设置在某个地方,因为在INSERT情况下(我假设您是从IDENTITY SQLException中引用的),
ID
属性被忽略。这和你不一样吗?好吧,POCO内的工厂可以处理模型的创建,并因此进行修改。这家工厂将被公开曝光。这将允许存储库创建模型并设置其属性,但不允许其他程序集在事后进行更改。这取决于你是否需要修改。不幸的是,它不是。L2SQL不使用纯POCO,它们是由L2SQL使用designer.cs文件中的所有元数据/sql属性/access生成的。我使用的是手工编码的纯POCO。@Luke Schafer-如果我直接走这条路,我怎么能对POCO进行更改?在我的UI中,我需要能够更改帖子标题。我可以说post.Title=“Foo”,然后在我的存储库中调用“SaveChanges”。如果我“不允许更改”,我如何修改POCO?我必须将所有属性作为方法参数公开。(即公共作废修改帖子(字符串标题))。