防止接口在其他程序集中实现

问题描述 投票:0回答:5

我在程序集 C 中有以下内容:

public interface InterfaceA
{
    string Data {get; }
}

public interface InterfaceB
{
    InterfaceA DoStuff();

}

public interface InterfaceC
{
    IEnumerable<InterfaceA> GetStuffThatHaveBeenDone();
}

InterfaceB 的一个实现称为 Doer,在程序集 A(这是主项目)中定义。 类似地,在 AssemblyA 中定义了 InterfaceA 的实现,但程序集 B 对这些实现一无所知。

程序集 B 将由外部公司开发,并将被程序集 A 引用(不是动态的,在设计时)。该公司的目的是为 InterfaceC 编写一个实现。

情况如下:我想阻止外部公司创建自己的 InterfaceA 实现并将其放入 InterfaceC.GetStuffThatHaveBeenDone() 返回的列表中。预期用法是:它们调用 InterfaceB.DoStuff(),获取 InterfaceA 的实例,并将其添加到它们将返回的列表中。

我必须对 InterfaceC.GetStuffThatHaveBeenDone() 返回的列表中包含的对象的类型做出假设。我知道它们都具有仅在程序集 A 中定义的特定类型。因此,我试图确保这些对象只会在程序集 A 中创建,并且我想在编译时强制执行此操作以避免发现 MyCustomImplementionOfA 对象在列表中。

因此我试图找出如何防止接口在另一个程序集中实现。我想也许可以通过稍微重新考虑我的设计来解决这个问题,但我似乎没有找到。

谢谢你

c#
5个回答
5
投票

我喜欢 Eric 提出的不透明代币解决方案。 您还可以通过使用 abstract class 代替

InterfaceA
并将其构造函数设为内部来实现此技巧。

public abstract class ContractA
{
   internal ContractA() {};
   public abstract string Data {get; }

}

4
投票

我能想到的唯一方法是创建一个不透明的对象,然后将其传回给他们:

internal interface InterfaceA
{
    string Data {get; }
}
public interface InterfaceB
{
    OpaqueToken DoStuff();
}

public interface InterfaceC
{
    IEnumerable<OpaqueToken> GetStuffThatHaveBeenDone();
}

public sealed class OpaqueToken
{
    internal OpaqueToken() {} 
    internal InterfaceA A { get; set; }
}

这样

InterfaceA
是内部的,因此只有您的库中的代码(除非您使用
InternalsVisibleTo
)才能实现它。您的库的使用者只会看到
OpaqueToken
的实例,并且您的构造函数是内部的,因此他们无法调用它。实现
InterfaceA
的对象也只能在您的库中访问。如果您愿意,
OpaqueToken
甚至可以实现
InterfaceA

需要指出的是,这不是一种安全措施——任何使用反射的消费者都可能违反所有这些规则。


0
投票

c# 8.0之后,可以使用internal关键字:

public interface IA
{
    internal void OnlyImplementableInternal();
}

-1
投票

将接口标记为 internal,然后如果您需要从您自己的任何程序集(例如,不是定义它的程序集)引用该接口,您可以使用 internalsvisibleto 属性来指定哪些程序集可以“看到”它。


-2
投票

以下是您可以执行的操作的提示:

public interface InterfaceA
{
    // Only expose what is of public interest!
    string Description { get; }
}

internal interface InterfaceAInternal : InterfaceA
{
    string Data { get; }
}

public interface InterfaceB
{
    InterfaceA DoStuff();
}

internal interface InterfaceC
{
    IEnumerable<InterfaceAInternal> GetStuffThatHaveBeenDone();
}

public interface InterfaceD
{
    IEnumerable<InterfaceA> GetStuffThatHaveBeenDone();
}

不要注意下面朱哈尔天真的评论。她可能拥有良好的声誉,但这并不是基于真正的编程知识/能力。

© www.soinside.com 2019 - 2024. All rights reserved.