我想将Foo
与FooHandler
分开。它们也应该由DI通过装配扫描进行注册。因此我有3种类型:
interface IFooHandler { // no type arguments, so it can be used by reflection
void DoStuff(object foo);
}
interface IFooHandler<TFoo>: IFooHandler { // TFoo tells us, what foo is it for
void DoStuff(TFoo foo); // developers are happy with strongly typed foos
}
abstract class FooHandler<TFoo>: IFooHandler<TFoo> {
void IFooHandler.DoStuff(object foo){
DoStuff((TFoo)foo); // adapter of interface 2 to 1
}
abstract void DoStuff(TFoo foo); // for nice implementation
}
这种设计的问题在于我不能轻易地禁止我的程序集中的其他人直接使用IFooHandler
或IFooHandler<TFoo>
。首先使用是个坏主意,因为它不会在DI中注册而且会失败。使用秒是个坏主意,因为你编写了无用的样板文件,已经用基类编写了。
使用Obsolete
添加error=True
属性以防止人们使用这些界面是否合理?是否有更好的方法来隐藏它们(我无法将它们移动到另一个组件并标记为内部)。
具体例子:
假设我们有webapplication,并且在各种类型的面板中有上下文(Foo),它们是给定上下文的选项列表的标识。假设你有货币选择,而Foo是CurrencyList
。然后你有CurrencyListProvider
类,它接受CurrencyList,从数据库中检索可用的货币并返回到面板,这样用户就可以选择他想用于交易的货币。我正在使用具体类型,因此您可以使用resharper等工具轻松移动代码库,但在这些具体类型中,有一些字符串通过http传播。
答案 0 :(得分:1)
是否合理,添加带有错误= True的Obsolete属性以防止人们使用这些接口?
没有。如果你害怕有人会直接访问你的实现,那就不会阻止他们。副作用是他们会质疑你作为开发人员的技能。
此外,他们应该通过装配扫描DI进行注册
这是你的痛苦所在。程序集扫描就是这样:检查程序集并创建实例,最好是通过一个很好的公共构造函数。所以,如果你不放弃这个要求,那就太复杂了。
如果你放弃这个要求,我认为你可以,因为你有3个版本,需要一个机制来切换它们;考虑使用自己的工厂。
让您的工厂决定返回哪个版本。
您甚至可以使用friend assemblies来保护构造函数。
真正的答案:
<小时/> 只需确保您的文档完整。如果人们读到你不鼓励使用某种类型,那就让他们决定吧。如果您的装配文件有详细记录,它可以帮助您:
我认为这是唯一符合逻辑的事情,而且比将事情标记为过时更为下降。