简体   繁体   English

如何定义对象的“公共”和“私有”接口?

[英]How to define 'public' and 'private' interfaces to an object?

I have a database and a DAL class that manages object-to-data (and vice-versa) mapping, in a similar way to Entity Frameworks - but we can't use EF here yet, so the DAL is a quite simple home-grown library that exposes a few objects and allows actions to be performed on them. 我有一个数据库和一个DAL类,以类似于Entity Frameworks的方式来管理对象到数据的映射(反之亦然)-但我们在这里还不能使用EF,因此DAL是一个非常简单的主目录,扩展的库,它公开了一些对象并允许对其执行操作。 It works, and will do until we can go to a 'proper' EF solution. 它会起作用,并且会一直起作用,直到我们可以使用“适当的” EF解决方案为止。

The DAL offers a variety of objects to 'client' applications, with methods and properties defined to encapsulate the logic of each action and hide the internal state of those objects as well as the mechanics needed to persist them to the database. DAL为“客户端”应用程序提供了各种对象,这些方法和属性定义为封装每个动作的逻辑并隐藏那些对象的内部状态以及将其持久化到数据库所需的机制。 This works too. 这也可以。

However, there are some actions that are exposed by the DALs' object interfaces which should really be 'private' - they are used by a service application that runs elsewhere, doing various background stuff to the objects in the database. 但是,DAL的对象接口公​​开了一些操作,这些操作实际上应该是“私有”的,它们由运行在其他地方的服务应用程序使用,这些操作对数据库中的对象进行了各种后台处理。 I do not really want the 'client' applications to be able to see these methods, but I do want the methods to be visible when the DAL is referenced by the service application. 我确实不希望“客户端”应用程序能够看到这些方法,但是当服务应用程序引用DAL时,我确实希望这些方法可见。

Example of the current implementation: 当前实现的示例:

 DAL Library Object Method LoadObject() Method SaveObject() Method AdjustInternalObjectProperty() 

Thus, the client apps can see all three methods, though they should never use the third - that is a function that should only be visible to the service app (which should be able to see and use all three methods). 因此,客户端应用程序可以看到所有三种方法,尽管它们永远不应使用第三种方法-这是仅应对服务应用程序可见的功能(该功能应能够查看和使用所有三种方法)。

So the question is, what is the best approach to take which will preserve the intention of using interfaces to each object, but which will 'hide' parts of that interface and only make the hidden parts accessible to a suitably 'friendly' service app. 因此,问题是,采用哪种最佳方法将保留使用每个对象的接口的意图,但将“隐藏”该接口的各个部分,而仅使隐藏的部分可供适当的“友好”服务应用程序访问。 Is there some access modifier technique that will let me make certain parts of the interface 'private', with a mechanism that the service app uses (but the client does not) to gain access to those private elements? 是否有一些访问修饰符技术可以使我将接口的某些部分设为“私有”,并使用一种服务应用程序使用的机制(但客户端没有)来访问这些私有元素? Or is this a scenario where two different interfaces should exist, where the 'client' interface simply omits the 'internal' methods? 还是在这种情况下应该存在两个不同的接口,而“客户端”接口只是省略了“内部”方法? Or something else? 或者是其他东西?

I want to do this the 'right' way - I've searched SO and found a bunch of answered questions regarding multiple object interfaces, but none seem to quite hit the spot for my specific question. 我想以“正确”的方式进行操作-我已经搜索了SO,发现了一堆有关多个对象接口的已回答问题,但是似乎没有一个问题针对我的特定问题。 If there is an existing answer, by all means point me at it and close this question. 如果一个现有的答案,通过各种手段指向我吧,并关闭了这个问题。

EDIT (after reading answers and experimenting): 编辑(阅读答案并进行实验后):

using System;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Test")]

namespace Interface_Test
{
  public interface IStandard
  {
    void StandardMethod();
  }
  internal interface ISuper : IStandard
  {
    void SuperMethod();
  }

  public sealed class TestClass : ISuper
  {
    public void StandardMethod()
    {
      Console.WriteLine("The standard method");
    }
    void ISuper.SuperMethod()
    {
      Console.WriteLine("The super method");
    }
  }
}

This does the job - the bulk of the object exposure is through the IStandard interface, which is a bog-standard public interface that any and all client assemblies can use. 这样做就可以了-对象IStandard的大部分是通过IStandard接口进行的,该接口是所有客户端程序集都可以使用的沼泽标准公共接口。 The 'restricted' stuff is only accessible through the alternate ISuper interface, which inherits all the core stuff from IStandard but adds the extra items that I only want a specific 'service client' to use. “受限”内容只能通过备用ISuper接口访问,该接口继承了IStandard所有核心内容,但添加了我只希望特定“服务客户端”使用的其他内容。 By adding the [InternalsVisibleTo] attribute as suggested, this interface and its' methods/properties are completely invisible to all but the named assembly. 通过按照建议的方式添加[InternalsVisibleTo]属性,该接口及其方法/属性对除了命名程序集以外的所有组件都是完全不可见的。

The downside is that there are two interfaces, but in the absence of a language facility such as allowing 'internal' as a modifier on interface method definitions it's a reasonable way of ensuring client assemblies can't get to features the interface supports but which aren't for general use. 缺点是有两个接口,但是在缺少语言功能(如允许'internal'作为接口方法定义的修饰符)的情况下,这是确保客户端程序集无法获得接口支持的功能的合理方法,不能用于一般用途。

One option is: 一种选择是:

  • Create an internal interface 创建一个internal接口
  • Implement it explicitly (to avoid requiring public methods) 明确实现它(避免使用公共方法)
  • Use [InternalsVisibleTo] to give your "service application" access to the internal interface 使用[InternalsVisibleTo]授予“服务应用程序”对内部界面的访问权限

You may be interested in this blog post which shows a few interesting options for other situations. 您可能对此博客文章感兴趣, 该文章显示了其他情况下的一些有趣选项。

One common approach is to have 2 interfaces: 一种常见的方法是具有2个接口:

public interface IBar
{
   void DoSimpleStudd();
   int This {get;}

}

public interface ISuperBar : IBar
{
   void DoComplexStuff();
   int That {get; set;}

}

// at service layer
public class ServiceWidget
{
    public ISuperBar Bar {get; set;}
    ...
}

// other places
public class ServiceWidget
{
    public IBar Bar {get; set;}
    ...
}

So in the service layer , they will be using ISuperBar and in other parts of the application, they will use IBar . 因此,在service layer ,他们将使用ISuperBar而在应用程序的其他部分中,他们将使用IBar

UPDATE 更新

Yes, interfaces are meant to be public. 是的,接口是公开的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在javascript中定义公共和私有属性 - How to define public and private property in javascript 定义私有/公共类型的结构 - Define private / public type of struct 如何使用公共属性而不是私有集合方法实现多个接口? - How do I implement multiple interfaces with public properties but private set methods? 是否可以在私有方法中定义公共变量? - Is it possible to define a public variable in a private method? 如何定义两个依赖的通用接口? - How to define two dependent generic interfaces? 带有公共 getter 的抽象属性,可以在具体类中定义私有 setter 吗? - Abstract property with public getter, define private setter in concrete class possible? C#-实现带有两个公共接口的私有类,然后转换为两个接口? 馊主意? - C# - Implementing a private class with two public interfaces, then casting to both of them? Bad idea? C# 接口和类。 接口中需要的类中使用的变量不能是私有的,或者私有的只能是公共的。 为什么? - C# Interfaces and classes. Variables used in the class needed in the interface can't be private, or private only public. Why? 如何将公共 Web 服务 API 设为私有? - How to make a public web service API private? 如何避免公众进入私有领域? - How to avoid public access to private fields?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM